diff --git a/src/main/java/de/thm/arsnova/services/IUserService.java b/src/main/java/de/thm/arsnova/services/IUserService.java index 4e94a08f74ac76e0c79f718622712be502efa29a..735815357b6cab781051a5c7da110ce0d9a65bc4 100644 --- a/src/main/java/de/thm/arsnova/services/IUserService.java +++ b/src/main/java/de/thm/arsnova/services/IUserService.java @@ -44,4 +44,8 @@ public interface IUserService { void addCurrentUserToSessionMap(String keyword); String getSessionForUser(String username); + + void addUserToSessionBySocketId(UUID socketId, String keyword); + + void removeUserFromSessionBySocketId(UUID socketId); } diff --git a/src/main/java/de/thm/arsnova/services/UserService.java b/src/main/java/de/thm/arsnova/services/UserService.java index d4f2660af9ca648e05d15a58e818977c52321396..6fa6e45f3a2090aeed59dcc6dd6939f706fd39fd 100644 --- a/src/main/java/de/thm/arsnova/services/UserService.java +++ b/src/main/java/de/thm/arsnova/services/UserService.java @@ -41,8 +41,13 @@ public class UserService implements IUserService, InitializingBean, DisposableBe public static final Logger LOGGER = LoggerFactory.getLogger(UserService.class); private static final ConcurrentHashMap<UUID, User> socketid2user = new ConcurrentHashMap<UUID, User>(); + + /* used for Socket.IO online check solution (new) */ private static final ConcurrentHashMap<User, String> user2session = new ConcurrentHashMap<User, String>(); + /* used for HTTP polling online check solution (legacy) */ + private static final ConcurrentHashMap<User, String> user2sessionLegacy = new ConcurrentHashMap<User, String>(); + @Override public User getCurrentUser() { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); @@ -106,7 +111,7 @@ public class UserService implements IUserService, InitializingBean, DisposableBe public boolean isUserInSession(User user, String keyword) { if (keyword == null) return false; - String session = user2session.get(user); + String session = user2sessionLegacy.get(user); if (session == null) return false; return keyword.equals(session); @@ -120,6 +125,12 @@ public class UserService implements IUserService, InitializingBean, DisposableBe result.add(e.getKey()); } } + for (Entry<User, String> e : user2sessionLegacy.entrySet()) { + if (e.getValue().equals(keyword)) { + result.add(e.getKey()); + } + } + return result; } @@ -129,12 +140,25 @@ public class UserService implements IUserService, InitializingBean, DisposableBe User user = getCurrentUser(); if (user == null) throw new UnauthorizedException(); + user2sessionLegacy.put(user, keyword); + } + + @Override + @Transactional(isolation = Isolation.READ_COMMITTED) + public void addUserToSessionBySocketId(UUID socketId, String keyword) { + User user = socketid2user.get(socketId); user2session.put(user, keyword); } + @Override + @Transactional(isolation = Isolation.READ_COMMITTED) + public void removeUserFromSessionBySocketId(UUID socketId) { + user2session.remove(socketId); + } + @Override public String getSessionForUser(String username) { - for (Entry<User, String> entry : user2session.entrySet()) { + for (Entry<User, String> entry : user2sessionLegacy.entrySet()) { if (entry.getKey().getUsername().equals(username)) return entry.getValue(); } return null; @@ -157,7 +181,7 @@ public class UserService implements IUserService, InitializingBean, DisposableBe LOGGER.info("load from store: {}", map); socketid2user.putAll(s2u); - user2session.putAll(u2s); + user2sessionLegacy.putAll(u2s); } catch (IOException e) { LOGGER.error("IOException during restoring UserService", e); @@ -170,7 +194,7 @@ public class UserService implements IUserService, InitializingBean, DisposableBe public void destroy() { Hashtable<String, Map<?, ?>> map = new Hashtable<String, Map<?, ?>>(); map.put("socketid2user", socketid2user); - map.put("user2session", user2session); + map.put("user2session", user2sessionLegacy); try { File tmpDir = new File(System.getProperty("java.io.tmpdir")); diff --git a/src/main/java/de/thm/arsnova/socket/ARSnovaSocketIOServer.java b/src/main/java/de/thm/arsnova/socket/ARSnovaSocketIOServer.java index 6c8ad2c9c36973e53bb84efe75c0dd519888e985..e07444860a912e470d9d6d5dc03396f302b5420d 100644 --- a/src/main/java/de/thm/arsnova/socket/ARSnovaSocketIOServer.java +++ b/src/main/java/de/thm/arsnova/socket/ARSnovaSocketIOServer.java @@ -28,6 +28,7 @@ import de.thm.arsnova.services.IFeedbackService; import de.thm.arsnova.services.IQuestionService; import de.thm.arsnova.services.IUserService; import de.thm.arsnova.socket.message.Feedback; +import de.thm.arsnova.socket.message.Session; public class ARSnovaSocketIOServer { @@ -93,6 +94,13 @@ public class ARSnovaSocketIOServer { } }); + server.addEventListener("setSession", Session.class, new DataListener<Session>() { + @Override + public void onData(SocketIOClient client, Session session, AckRequest ackSender) { + userService.addUserToSessionBySocketId(client.getSessionId(), session.getKeyword()); + } + }); + server.addEventListener("arsnova/question/create", Question.class, new DataListener<Question>() { @Override public void onData(SocketIOClient client, Question question, AckRequest ackSender) { @@ -111,6 +119,7 @@ public class ARSnovaSocketIOServer { @Override public void onDisconnect(SocketIOClient client) { logger.info("addDisconnectListener.onDisconnect: Client: {}", new Object[] { client }); + userService.removeUserFromSessionBySocketId(client.getSessionId()); userService.removeUser2SocketId(client.getSessionId()); } }); diff --git a/src/main/java/de/thm/arsnova/socket/message/Session.java b/src/main/java/de/thm/arsnova/socket/message/Session.java new file mode 100644 index 0000000000000000000000000000000000000000..3b56fe50c035f2c77d19c9d8db581755e249fc01 --- /dev/null +++ b/src/main/java/de/thm/arsnova/socket/message/Session.java @@ -0,0 +1,13 @@ +package de.thm.arsnova.socket.message; + +public class Session { + private String keyword; + + public String getKeyword() { + return keyword; + } + + public void setKeyword(String keyword) { + this.keyword = keyword; + } +}