mirror of
https://github.com/correl/mage.git
synced 2024-11-15 11:09:30 +00:00
remove stale users after 10 minutes
This commit is contained in:
parent
b4b02d0f68
commit
bf2f4e3078
9 changed files with 135 additions and 33 deletions
|
@ -70,6 +70,24 @@ public class ChatManager {
|
|||
chatSessions.get(chatId).broadcast(userName, message, color);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* use mainly for announcing that a user connection was lost or that a user has reconnected
|
||||
*
|
||||
* @param userId
|
||||
* @param message
|
||||
* @param color
|
||||
*/
|
||||
public void broadcast(UUID userId, String message, MessageColor color) {
|
||||
User user = UserManager.getInstance().getUser(userId);
|
||||
if (user != null) {
|
||||
for (ChatSession chat: chatSessions.values()) {
|
||||
if (chat.hasUser(userId))
|
||||
chat.broadcast(user.getName(), message, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void removeUser(UUID userId) {
|
||||
for (ChatSession chat: chatSessions.values()) {
|
||||
chat.kill(userId);
|
||||
|
|
|
@ -32,7 +32,6 @@ import java.text.DateFormat;
|
|||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import mage.interfaces.callback.ClientCallback;
|
||||
|
@ -51,8 +50,6 @@ public class ChatSession {
|
|||
private UUID chatId;
|
||||
private DateFormat timeFormatter = SimpleDateFormat.getTimeInstance(SimpleDateFormat.SHORT);
|
||||
|
||||
//TODO: use sessionId for chatting - prevents sending without being part of the chat
|
||||
|
||||
public ChatSession() {
|
||||
chatId = UUID.randomUUID();
|
||||
}
|
||||
|
@ -98,4 +95,8 @@ public class ChatSession {
|
|||
return chatId;
|
||||
}
|
||||
|
||||
public boolean hasUser(UUID userId) {
|
||||
return clients.containsKey(userId);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -253,7 +253,7 @@ public class MageServerImpl implements MageServer {
|
|||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
SessionManager.getInstance().disconnect(sessionId);
|
||||
SessionManager.getInstance().disconnect(sessionId, true);
|
||||
logger.info("Client deregistered ...");
|
||||
}
|
||||
}
|
||||
|
@ -563,8 +563,8 @@ public class MageServerImpl implements MageServer {
|
|||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
UUID userId = SessionManager.getInstance().getSession(sessionId).getUserId();
|
||||
GameManager.getInstance().sendPlayerUUID(gameId, userId, data);
|
||||
User user = SessionManager.getInstance().getUser(sessionId);
|
||||
user.sendPlayerUUID(gameId, data);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
@ -583,8 +583,8 @@ public class MageServerImpl implements MageServer {
|
|||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
UUID userId = SessionManager.getInstance().getSession(sessionId).getUserId();
|
||||
GameManager.getInstance().sendPlayerString(gameId, userId, data);
|
||||
User user = SessionManager.getInstance().getUser(sessionId);
|
||||
user.sendPlayerString(gameId, data);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
@ -603,8 +603,8 @@ public class MageServerImpl implements MageServer {
|
|||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
UUID userId = SessionManager.getInstance().getSession(sessionId).getUserId();
|
||||
GameManager.getInstance().sendPlayerBoolean(gameId, userId, data);
|
||||
User user = SessionManager.getInstance().getUser(sessionId);
|
||||
user.sendPlayerBoolean(gameId, data);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
@ -623,8 +623,8 @@ public class MageServerImpl implements MageServer {
|
|||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
UUID userId = SessionManager.getInstance().getSession(sessionId).getUserId();
|
||||
GameManager.getInstance().sendPlayerInteger(gameId, userId, data);
|
||||
User user = SessionManager.getInstance().getUser(sessionId);
|
||||
user.sendPlayerInteger(gameId, data);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
|
|
@ -138,12 +138,13 @@ public class Main {
|
|||
else
|
||||
sessionName = session.getHost();
|
||||
if (throwable instanceof ClientDisconnectedException) {
|
||||
SessionManager.getInstance().disconnect(client.getSessionId(), true);
|
||||
logger.info("client disconnected - " + sessionName);
|
||||
}
|
||||
else {
|
||||
SessionManager.getInstance().disconnect(client.getSessionId(), false);
|
||||
logger.info("connection to client lost - " + sessionName);
|
||||
}
|
||||
SessionManager.getInstance().disconnect(client.getSessionId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -200,9 +201,10 @@ public class Main {
|
|||
|
||||
@Override
|
||||
public void removeListener(InvokerCallbackHandler callbackHandler) {
|
||||
ServerInvokerCallbackHandler handler = (ServerInvokerCallbackHandler) callbackHandler;
|
||||
String sessionId = handler.getCallbackClient().getSessionId();
|
||||
SessionManager.getInstance().disconnect(sessionId);
|
||||
logger.fatal("removeListener called");
|
||||
// ServerInvokerCallbackHandler handler = (ServerInvokerCallbackHandler) callbackHandler;
|
||||
// String sessionId = handler.getCallbackClient().getSessionId();
|
||||
// SessionManager.getInstance().disconnect(sessionId);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -93,20 +93,21 @@ public class Session {
|
|||
return sessionId;
|
||||
}
|
||||
|
||||
public void kill() {
|
||||
// TableManager.getInstance().removeSession(sessionId);
|
||||
// GameManager.getInstance().removeSession(sessionId);
|
||||
// ChatManager.getInstance().removeSession(sessionId);
|
||||
public void disconnect() {
|
||||
UserManager.getInstance().disconnect(userId);
|
||||
}
|
||||
|
||||
|
||||
public void kill() {
|
||||
UserManager.getInstance().removeUser(userId);
|
||||
}
|
||||
|
||||
synchronized void fireCallback(final ClientCallback call) {
|
||||
try {
|
||||
call.setMessageId(messageId++);
|
||||
callbackHandler.handleCallbackOneway(new Callback(call));
|
||||
} catch (HandleCallbackException ex) {
|
||||
logger.fatal("Session fireCallback error", ex);
|
||||
kill();
|
||||
disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,13 +28,11 @@
|
|||
|
||||
package mage.server;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import mage.MageException;
|
||||
import mage.view.UserView;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.jboss.remoting.callback.InvokerCallbackHandler;
|
||||
|
||||
|
@ -83,10 +81,13 @@ public class SessionManager {
|
|||
return false;
|
||||
}
|
||||
|
||||
public synchronized void disconnect(String sessionId) {
|
||||
public synchronized void disconnect(String sessionId, boolean voluntary) {
|
||||
Session session = sessions.get(sessionId);
|
||||
if (session != null) {
|
||||
session.kill();
|
||||
if (voluntary)
|
||||
session.kill();
|
||||
else
|
||||
session.disconnect();
|
||||
sessions.remove(sessionId);
|
||||
}
|
||||
}
|
||||
|
@ -101,10 +102,7 @@ public class SessionManager {
|
|||
|
||||
public void disconnectUser(String sessionId, String userSessionId) {
|
||||
if (isAdmin(sessionId)) {
|
||||
Session session = sessions.get(userSessionId);
|
||||
if (session != null) {
|
||||
session.kill();
|
||||
}
|
||||
disconnect(userSessionId, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -122,4 +120,10 @@ public class SessionManager {
|
|||
return false;
|
||||
}
|
||||
|
||||
public User getUser(String sessionId) {
|
||||
if (sessions.containsKey(sessionId)) {
|
||||
return UserManager.getInstance().getUser(sessions.get(sessionId).getUserId());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,6 +53,7 @@ public class User {
|
|||
private String sessionId = "";
|
||||
private String host;
|
||||
private Date connectionTime = new Date();
|
||||
private Date lastActivity = new Date();
|
||||
private UserState userState;
|
||||
private Map<UUID, GameSession> gameSessions = new HashMap<UUID, GameSession>();
|
||||
|
||||
|
@ -133,6 +134,30 @@ public class User {
|
|||
fireCallback(new ClientCallback("replayGame", gameId));
|
||||
}
|
||||
|
||||
public void sendPlayerUUID(final UUID gameId, final UUID data) {
|
||||
lastActivity = new Date();
|
||||
GameManager.getInstance().sendPlayerUUID(gameId, userId, data);
|
||||
}
|
||||
|
||||
public void sendPlayerString(final UUID gameId, final String data) {
|
||||
lastActivity = new Date();
|
||||
GameManager.getInstance().sendPlayerString(gameId, userId, data);
|
||||
}
|
||||
|
||||
public void sendPlayerBoolean(final UUID gameId, final Boolean data) {
|
||||
lastActivity = new Date();
|
||||
GameManager.getInstance().sendPlayerBoolean(gameId, userId, data);
|
||||
}
|
||||
|
||||
public void sendPlayerInteger(final UUID gameId, final Integer data) {
|
||||
lastActivity = new Date();
|
||||
GameManager.getInstance().sendPlayerInteger(gameId, userId, data);
|
||||
}
|
||||
|
||||
public boolean isExpired(Date expired) {
|
||||
return userState == UserState.Disconnected && lastActivity.before(expired);
|
||||
}
|
||||
|
||||
private void reconnect() {
|
||||
for (Entry<UUID, GameSession> entry: gameSessions.entrySet()) {
|
||||
gameStarted(entry.getValue().getGameId(), entry.getKey());
|
||||
|
@ -148,5 +173,11 @@ public class User {
|
|||
public void removeGame(UUID playerId) {
|
||||
gameSessions.remove(playerId);
|
||||
}
|
||||
|
||||
public void kill() {
|
||||
for (Entry<UUID, GameSession> entry: gameSessions.entrySet()) {
|
||||
entry.getValue().kill();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -27,23 +27,41 @@
|
|||
*/
|
||||
package mage.server;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import mage.view.ChatMessage.MessageColor;
|
||||
|
||||
/**
|
||||
*
|
||||
* manages users - if a user is disconnected and 10 minutes have passed with no
|
||||
* activity the user is removed
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class UserManager {
|
||||
|
||||
protected static ScheduledExecutorService expireExecutor = Executors.newSingleThreadScheduledExecutor();
|
||||
|
||||
private final static UserManager INSTANCE = new UserManager();
|
||||
|
||||
public static UserManager getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
private UserManager() {}
|
||||
private UserManager() {
|
||||
expireExecutor.scheduleAtFixedRate(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
checkExpired();
|
||||
}
|
||||
}, 60, 60, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
private ConcurrentHashMap<UUID, User> users = new ConcurrentHashMap<UUID, User>();
|
||||
|
||||
|
@ -82,6 +100,7 @@ public class UserManager {
|
|||
public void disconnect(UUID userId) {
|
||||
if (users.containsKey(userId)) {
|
||||
users.get(userId).setSessionId("");
|
||||
ChatManager.getInstance().broadcast(userId, "has lost connection", MessageColor.BLACK);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -91,5 +110,25 @@ public class UserManager {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void removeUser(UUID userId) {
|
||||
if (users.containsKey(userId)) {
|
||||
users.get(userId).setSessionId("");
|
||||
ChatManager.getInstance().broadcast(userId, "has disconnected", MessageColor.BLACK);
|
||||
users.get(userId).kill();
|
||||
users.remove(userId);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkExpired() {
|
||||
Calendar expired = Calendar.getInstance();
|
||||
expired.add(Calendar.MINUTE, -10) ;
|
||||
for (User user: users.values()) {
|
||||
if (user.isExpired(expired.getTime())) {
|
||||
user.kill();
|
||||
users.remove(user.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -210,11 +210,17 @@ public class GameSession extends GameWatcher {
|
|||
}
|
||||
|
||||
public void removeGame() {
|
||||
UserManager.getInstance().getUser(userId).removeGame(playerId);
|
||||
User user = UserManager.getInstance().getUser(userId);
|
||||
if (user != null)
|
||||
user.removeGame(playerId);
|
||||
}
|
||||
|
||||
public UUID getGameId() {
|
||||
return game.getId();
|
||||
}
|
||||
|
||||
public void kill() {
|
||||
game.quit(playerId);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue