mirror of
https://github.com/magefree/mage.git
synced 2025-12-24 04:22:01 -08:00
added pingInfo to user info
This commit is contained in:
parent
bc51a8fc79
commit
481e177d71
13 changed files with 159 additions and 24 deletions
|
|
@ -84,6 +84,7 @@ import java.awt.image.BufferedImage;
|
|||
import java.beans.PropertyVetoException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
|
@ -92,6 +93,8 @@ import java.util.concurrent.Executors;
|
|||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.prefs.Preferences;
|
||||
import mage.cards.repository.ExpansionInfo;
|
||||
import mage.cards.repository.ExpansionRepository;
|
||||
import mage.client.util.audio.AudioManager;
|
||||
import mage.interfaces.ServerState;
|
||||
import mage.view.ChatMessage;
|
||||
|
|
@ -140,7 +143,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
|
|||
private static final Map<UUID, DraftPanel> drafts = new HashMap<>();
|
||||
private static final MageUI ui = new MageUI();
|
||||
|
||||
private static final ScheduledExecutorService pingTaskExecutor = Executors.newSingleThreadScheduledExecutor();
|
||||
// private static final ScheduledExecutorService pingTaskExecutor = Executors.newSingleThreadScheduledExecutor();
|
||||
private static UpdateMemUsageTask updateMemUsageTask;
|
||||
|
||||
private static long startTime;
|
||||
|
|
@ -700,9 +703,46 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
|
|||
public boolean connect(Connection connection) {
|
||||
client = new Client(instance);
|
||||
boolean result = client.connect(connection.getUsername(), connection.getHost(), connection.getPort(), true, version);
|
||||
if (result) {
|
||||
updateDatabase(connection.isForceDBComparison(), serverState);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void updateDatabase(boolean forceDBComparison, ServerState serverState) {
|
||||
long cardDBVersion = CardRepository.instance.getContentVersionFromDB();
|
||||
if (forceDBComparison || serverState.getCardsContentVersion() > cardDBVersion) {
|
||||
List<String> classNames = CardRepository.instance.getClassNames();
|
||||
List<CardInfo> cards = CardRepository.instance.getMissingCards(classNames);
|
||||
CardRepository.instance.addCards(cards);
|
||||
CardRepository.instance.setContentVersion(serverState.getCardsContentVersion());
|
||||
logger.info("Updating client cards DB - existing cards: " + classNames.size() + " new cards: " + cards.size() +
|
||||
" content versions - server: " + serverState.getCardsContentVersion() + " client: " + cardDBVersion);
|
||||
}
|
||||
|
||||
long expansionDBVersion = ExpansionRepository.instance.getContentVersionFromDB();
|
||||
if (forceDBComparison || serverState.getExpansionsContentVersion() > expansionDBVersion) {
|
||||
List<String> setCodes = ExpansionRepository.instance.getSetCodes();
|
||||
List<ExpansionInfo> expansions = getMissingExpansionData(setCodes);
|
||||
for (ExpansionInfo expansion : expansions) {
|
||||
ExpansionRepository.instance.add(expansion);
|
||||
}
|
||||
ExpansionRepository.instance.setContentVersion(serverState.getExpansionsContentVersion());
|
||||
logger.info("Updating client expansions DB - existing sets: " + setCodes.size() + " new sets: " + expansions.size()+
|
||||
" content versions - server: " + serverState.getExpansionsContentVersion() + " client: " + expansionDBVersion);
|
||||
}
|
||||
}
|
||||
|
||||
private List<ExpansionInfo> getMissingExpansionData(List<String> codes) {
|
||||
List<ExpansionInfo> result = new ArrayList<>();
|
||||
for (ExpansionInfo expansionInfo : ExpansionRepository.instance.getAll()) {
|
||||
if (!codes.contains(expansionInfo.getCode())) {
|
||||
result.add(expansionInfo);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// public static boolean stopConnecting() {
|
||||
// return session.stopConnecting();
|
||||
// }
|
||||
|
|
|
|||
|
|
@ -216,7 +216,7 @@ public class Client {
|
|||
}
|
||||
|
||||
public String getSessionId() {
|
||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||
return channel.id().asLongText();
|
||||
}
|
||||
|
||||
public TableView createTournamentTable(UUID roomId, TournamentOptions tOptions) {
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ import org.mage.network.handlers.server.ServerMessageHandler;
|
|||
import org.mage.network.interfaces.MageServer;
|
||||
import org.mage.network.model.InformClientMessage;
|
||||
import org.mage.network.model.MessageType;
|
||||
import org.mage.network.model.PingMessage;
|
||||
import org.mage.network.model.ReceiveChatMessage;
|
||||
|
||||
/**
|
||||
|
|
@ -48,12 +49,13 @@ public class Server {
|
|||
|
||||
private static final int IDLE_PING_TIME = 30;
|
||||
private static final int IDLE_TIMEOUT = 60;
|
||||
private static final PingMessage ping = new PingMessage();
|
||||
|
||||
public static final ChannelGroup clients = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
|
||||
|
||||
private SslContext sslCtx;
|
||||
|
||||
private final HeartbeatHandler heartbeatHandler;
|
||||
private final MageServer server;
|
||||
private final PingMessageHandler pingMessageHandler = new PingMessageHandler();
|
||||
private final EventExecutorGroup handlersExecutor = new DefaultEventExecutorGroup(Runtime.getRuntime().availableProcessors() * 2);
|
||||
private final RegisterClientMessageHandler registerClientMessageHandler;
|
||||
|
|
@ -66,7 +68,7 @@ public class Server {
|
|||
private final RoomMessageHandler roomMessageHandler;
|
||||
|
||||
public Server(MageServer server) {
|
||||
heartbeatHandler = new HeartbeatHandler(server);
|
||||
this.server = server;
|
||||
registerClientMessageHandler = new RegisterClientMessageHandler(server);
|
||||
chatMessageHandler = new ChatMessageHandler(server);
|
||||
joinChatMessageHandler = new JoinChatMessageHandler(server);
|
||||
|
|
@ -117,18 +119,18 @@ public class Server {
|
|||
ch.pipeline().addLast(new ObjectEncoder());
|
||||
|
||||
ch.pipeline().addLast("idleStateHandler", new IdleStateHandler(IDLE_TIMEOUT, IDLE_PING_TIME, 0));
|
||||
ch.pipeline().addLast(handlersExecutor, heartbeatHandler);
|
||||
ch.pipeline().addLast(handlersExecutor, "heartbeatHandler", new HeartbeatHandler(server));
|
||||
ch.pipeline().addLast("pingMessageHandler", pingMessageHandler);
|
||||
|
||||
ch.pipeline().addLast("connectionHandler", new ConnectionHandler());
|
||||
ch.pipeline().addLast(handlersExecutor, registerClientMessageHandler);
|
||||
ch.pipeline().addLast(handlersExecutor, "registerClientMessageHandler", registerClientMessageHandler);
|
||||
|
||||
ch.pipeline().addLast(handlersExecutor, chatRoomIdHandler);
|
||||
ch.pipeline().addLast(handlersExecutor, chatMessageHandler);
|
||||
ch.pipeline().addLast(handlersExecutor, joinChatMessageHandler);
|
||||
ch.pipeline().addLast(handlersExecutor, leaveChatMessageHandler);
|
||||
ch.pipeline().addLast(handlersExecutor, serverMessageHandler);
|
||||
ch.pipeline().addLast(handlersExecutor, roomMessageHandler);
|
||||
ch.pipeline().addLast(handlersExecutor, "chatRoomIdHandler", chatRoomIdHandler);
|
||||
ch.pipeline().addLast(handlersExecutor, "chatMessageHandler", chatMessageHandler);
|
||||
ch.pipeline().addLast(handlersExecutor, "joinChatMessageHandler", joinChatMessageHandler);
|
||||
ch.pipeline().addLast(handlersExecutor, "leaveChatMessageHandler", leaveChatMessageHandler);
|
||||
ch.pipeline().addLast(handlersExecutor, "serverMessageHandler", serverMessageHandler);
|
||||
ch.pipeline().addLast(handlersExecutor, "roomMessageHandler", roomMessageHandler);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -158,4 +160,12 @@ public class Server {
|
|||
clients.writeAndFlush(new InformClientMessage(message, type));
|
||||
}
|
||||
|
||||
public void pingClient(String sessionId) {
|
||||
Channel ch = findChannel(sessionId);
|
||||
if (ch != null) {
|
||||
HeartbeatHandler heartbeatHandler = (HeartbeatHandler)ch.pipeline().get("heartbeatHandler");
|
||||
heartbeatHandler.pingClient();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,28 +5,38 @@ import io.netty.channel.ChannelHandlerAdapter;
|
|||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.timeout.IdleState;
|
||||
import io.netty.handler.timeout.IdleStateEvent;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import mage.remote.DisconnectReason;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.mage.network.interfaces.MageServer;
|
||||
import org.mage.network.model.PingMessage;
|
||||
import org.mage.network.model.PongMessage;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward
|
||||
*/
|
||||
@Sharable
|
||||
public class HeartbeatHandler extends ChannelHandlerAdapter {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(HeartbeatHandler.class);
|
||||
|
||||
private static PingMessage ping = new PingMessage();
|
||||
|
||||
private ChannelHandlerContext ctx;
|
||||
private long startTime;
|
||||
|
||||
private final MageServer server;
|
||||
|
||||
public HeartbeatHandler (MageServer server) {
|
||||
this.server = server;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelActive(ChannelHandlerContext ctx) throws Exception {
|
||||
this.ctx = ctx;
|
||||
super.channelActive(ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
|
||||
if (evt instanceof IdleStateEvent) {
|
||||
|
|
@ -36,9 +46,24 @@ public class HeartbeatHandler extends ChannelHandlerAdapter {
|
|||
ctx.disconnect();
|
||||
logger.info("Disconnected due to extended idle");
|
||||
} else if (e.state() == IdleState.WRITER_IDLE) {
|
||||
startTime = System.nanoTime();
|
||||
ctx.writeAndFlush(ping);
|
||||
logger.info("Sending ping");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object msg) {
|
||||
if (msg instanceof PongMessage) {
|
||||
long milliSeconds = TimeUnit.MILLISECONDS.convert(System.nanoTime() - startTime, TimeUnit.NANOSECONDS);
|
||||
server.pingTime(milliSeconds, ctx.channel().id().asLongText());
|
||||
}
|
||||
ctx.fireChannelRead(msg);
|
||||
}
|
||||
|
||||
public void pingClient() {
|
||||
startTime = System.nanoTime();
|
||||
ctx.writeAndFlush(ping);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,5 +26,7 @@ public interface MageServer {
|
|||
|
||||
List<String> getServerMessages();
|
||||
RoomView getRoom(UUID roomId);
|
||||
|
||||
void pingTime(long milliSeconds, String sessionId);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -491,6 +491,16 @@ public class Main implements MageServer {
|
|||
// public boolean ping(String sessionId, String pingInfo) {
|
||||
// return SessionManager.getInstance().extendUserSession(sessionId, pingInfo);
|
||||
// }
|
||||
|
||||
public void pingClient(String sessionId) {
|
||||
server.pingClient(sessionId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pingTime(long milliSeconds, String sessionId) {
|
||||
SessionManager.getInstance().recordPingTime(sessionId, milliSeconds);
|
||||
}
|
||||
|
||||
//
|
||||
// @Override
|
||||
// public void deregisterClient(final String sessionId) throws MageException {
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@ import java.util.Date;
|
|||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.regex.Matcher;
|
||||
|
|
@ -57,6 +59,7 @@ import org.jboss.remoting.callback.InvokerCallbackHandler;
|
|||
public class Session {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(Session.class);
|
||||
private static final ScheduledExecutorService pingTaskExecutor = Executors.newScheduledThreadPool(10);
|
||||
|
||||
private final String sessionId;
|
||||
private UUID userId;
|
||||
|
|
@ -64,6 +67,10 @@ public class Session {
|
|||
private int messageId = 0;
|
||||
private final Date timeConnected;
|
||||
private boolean isAdmin = false;
|
||||
private final static int PING_CYCLES = 10;
|
||||
private final LinkedList<Long> pingTime = new LinkedList<>();
|
||||
private String pingInfo = "";
|
||||
|
||||
// private final AsynchInvokerCallbackHandler callbackHandler;
|
||||
|
||||
private final ReentrantLock lock;
|
||||
|
|
@ -82,6 +89,12 @@ public class Session {
|
|||
// sendErrorMessageToClient(returnMessage);
|
||||
// }
|
||||
// return returnMessage;
|
||||
pingTaskExecutor.scheduleAtFixedRate(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Main.getInstance().pingClient(sessionId);
|
||||
}
|
||||
}, 10, 60, TimeUnit.SECONDS);
|
||||
return registerUserHandling(userName);
|
||||
}
|
||||
|
||||
|
|
@ -260,6 +273,7 @@ public class Session {
|
|||
logger.error("SESSION LOCK - kill: userId " + userId);
|
||||
}
|
||||
UserManager.getInstance().removeUser(userId, reason);
|
||||
pingTime.clear();
|
||||
} catch (InterruptedException ex) {
|
||||
logger.error("SESSION LOCK - kill: userId " + userId, ex);
|
||||
}
|
||||
|
|
@ -324,4 +338,21 @@ public class Session {
|
|||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
public void recordPingTime(long milliSeconds) {
|
||||
pingTime.add(milliSeconds);
|
||||
String lastPing = milliSeconds > 0 ? milliSeconds+"ms" : "<1ms";
|
||||
if (pingTime.size() > PING_CYCLES) {
|
||||
pingTime.poll();
|
||||
}
|
||||
long sum = 0;
|
||||
for (Long time :pingTime) {
|
||||
sum += time;
|
||||
}
|
||||
pingInfo = lastPing + " (Av: " + (milliSeconds > 0 ? milliSeconds + "ms":"<1ms")+")";
|
||||
}
|
||||
|
||||
public String getPingInfo() {
|
||||
return pingInfo;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -223,4 +223,11 @@ public class SessionManager {
|
|||
// }
|
||||
// return false;
|
||||
// }
|
||||
|
||||
void recordPingTime(String sessionId, long milliSeconds) {
|
||||
Session session = sessions.get(sessionId);
|
||||
if (session != null) {
|
||||
session.recordPingTime(milliSeconds);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -375,7 +375,7 @@ public class TableManager {
|
|||
logger.debug(user.getId()
|
||||
+ " | " + formatter.format(user.getConnectionTime())
|
||||
+ " | " + sessionState
|
||||
+ " | " + user.getName() +" (" +user.getUserState().toString() + " - " + user.getPingInfo() + ")");
|
||||
+ " | " + user.getName() +" (" +user.getUserState().toString() + " - " + session.getPingInfo() + ")");
|
||||
}
|
||||
ArrayList<ChatSession> chatSessions = ChatManager.getInstance().getChatSessions();
|
||||
logger.debug("------- ChatSessions: " + chatSessions.size() + " ----------------------------------");
|
||||
|
|
|
|||
|
|
@ -512,12 +512,12 @@ public class User {
|
|||
return userState;
|
||||
}
|
||||
|
||||
public String getPingInfo() {
|
||||
if (isConnected()) {
|
||||
return pingInfo;
|
||||
} else {
|
||||
return " (discon. "+ getDisconnectDuration() + ")";
|
||||
}
|
||||
}
|
||||
// public String getPingInfo() {
|
||||
// if (isConnected()) {
|
||||
// return pingInfo;
|
||||
// } else {
|
||||
// return " (discon. "+ getDisconnectDuration() + ")";
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -197,4 +197,8 @@ public class UserManager {
|
|||
logger.fatal("User manager exception - null");
|
||||
}
|
||||
}
|
||||
|
||||
void recordPingTime(UUID userId, long milliSeconds) {
|
||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,6 +73,8 @@ import mage.interfaces.Action;
|
|||
import mage.players.Player;
|
||||
import mage.server.ChatManager;
|
||||
import mage.server.Main;
|
||||
import mage.server.Session;
|
||||
import mage.server.SessionManager;
|
||||
import mage.server.TableManager;
|
||||
import mage.server.User;
|
||||
import mage.server.UserManager;
|
||||
|
|
@ -363,7 +365,8 @@ public class GameController implements GameCallback {
|
|||
GameManager.getInstance().joinGame(game.getId(), user.getId());
|
||||
logger.debug("Player " + player.getLogName() + " (disconnected) has joined gameId: " +game.getId());
|
||||
}
|
||||
ChatManager.getInstance().broadcast(chatId, user, user.getPingInfo() + " is pending to join the game", MessageColor.BLUE, true, ChatMessage.MessageType.STATUS);
|
||||
Session session = SessionManager.getInstance().getSession(user.getSessionId());
|
||||
ChatManager.getInstance().broadcast(chatId, user, session.getPingInfo() + " is pending to join the game", MessageColor.BLUE, true, ChatMessage.MessageType.STATUS);
|
||||
if (user.getSecondsDisconnected() > 240) {
|
||||
// Cancel player join possibility lately after 4 minutes
|
||||
logger.debug("Player " + player.getLogName() + " - canceled game (after 240 seconds) gameId: " +game.getId());
|
||||
|
|
|
|||
|
|
@ -46,6 +46,8 @@ import mage.game.Table;
|
|||
import mage.game.match.MatchOptions;
|
||||
import mage.game.tournament.TournamentOptions;
|
||||
import mage.server.RoomImpl;
|
||||
import mage.server.Session;
|
||||
import mage.server.SessionManager;
|
||||
import mage.server.TableManager;
|
||||
import mage.server.User;
|
||||
import mage.server.UserManager;
|
||||
|
|
@ -119,11 +121,12 @@ public class GamesRoomImpl extends RoomImpl implements GamesRoom, Serializable {
|
|||
matchView = matchList;
|
||||
List<UsersView> users = new ArrayList<>();
|
||||
for (User user : UserManager.getInstance().getUsers()) {
|
||||
Session session = SessionManager.getInstance().getSession(user.getSessionId());
|
||||
try {
|
||||
users.add(new UsersView(user.getName(), user.getInfo(), user.getGameInfo(), user.getPingInfo()));
|
||||
users.add(new UsersView(user.getName(), user.getInfo(), user.getGameInfo(), session.getPingInfo()));
|
||||
} catch (Exception ex) {
|
||||
logger.fatal("User update exception: " + user.getName() + " - " + ex.toString(), ex);
|
||||
users.add(new UsersView(user.getName(), user.getInfo(), "[exception]", user.getPingInfo()));
|
||||
users.add(new UsersView(user.getName(), user.getInfo(), "[exception]", session.getPingInfo()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue