package envoy.server; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import com.jenkov.nioserver.ISocketIdListener; import envoy.data.User.UserStatus; import envoy.server.database.PersistenceManager; import envoy.server.processors.UserStatusChangeProcessor; /** * Project: envoy-server-standalone
* File: ConnectionManager.java
* Created: 03.01.2020
* * @author Kai S. K. Engelbart * @since Envoy Server Standalone v0.1-alpha */ public class ConnectionManager implements ISocketIdListener { /** * Contains all socket IDs that have not yet performed a handshake / acquired * their corresponding user ID. * * @since Envoy Server Standalone v0.1-alpha */ private Set pendingSockets = new HashSet<>(); /** * Contains all socket IDs that have acquired a user ID as keys to these IDs. * * @since Envoy Server Standalone v0.1-alpha */ private Map sockets = new HashMap<>(); private static ConnectionManager connectionManager = new ConnectionManager(); private ConnectionManager() {} /** * @return a singleton instance of this object * @since Envoy Server Standalone v0.1-alpha */ public static ConnectionManager getInstance() { return connectionManager; } @Override public void socketCancelled(long socketId) { if (!pendingSockets.remove(socketId)) { // notifying contacts of this users offline-going envoy.server.data.User user = PersistenceManager.getPersistenceManager().getUserById(getUserIdBySocketId(socketId)); user.setStatus(UserStatus.OFFLINE); user.setLastSeen(new Date()); UserStatusChangeProcessor.updateUserStatus(user); // removing the socket sockets.entrySet().stream().filter(e -> e.getValue() == socketId).forEach(e -> sockets.remove(e.getValue())); } } @Override public void socketRegistered(long socketId) { pendingSockets.add(socketId); } /** * Associates a socket ID with a user ID. * * @param userId the user ID * @param socketId the socket ID * @since Envoy Server Standalone v0.1-alpha */ public void registerUser(long userId, long socketId) { sockets.put(userId, socketId); pendingSockets.remove(socketId); } /** * @param userId the ID of the user registered at a socket * @return the ID of the socket * @since Envoy Server Standalone v0.1-alpha */ public long getSocketId(long userId) { return sockets.get(userId); } /** * @param socketId the id of the socket whose User is needed * @return the userId associated with this socketId * @since Envoy Server Standalone v0.1-alpha */ public long getUserIdBySocketId(long socketId) { return sockets.entrySet().stream().filter((entry) -> entry.getValue().equals(socketId)).findFirst().get().getKey(); } /** * @param userId the ID of the user to check for * @return {@code true} if the user is online * @since Envoy Server Standalone v0.1-alpha */ public boolean isOnline(long userId) { return sockets.containsKey(userId); } /** * @return the userId of all users who are currently online * @since Envoy Server Standalone v0.1-alpha */ public List getOnlineUsers() { List onlineUsers = new ArrayList<>(); sockets.forEach((userId, unimportant) -> onlineUsers.add(userId)); return onlineUsers; } }