This repository has been archived on 2021-12-05. You can view files and clone it, but cannot push or open issues or pull requests.
envoy/server/src/main/java/envoy/server/net/ConnectionManager.java

123 lines
3.3 KiB
Java
Executable File

package envoy.server.net;
import java.time.Instant;
import java.util.*;
import java.util.stream.Collectors;
import com.jenkov.nioserver.ISocketIdListener;
import envoy.data.User.UserStatus;
import envoy.server.data.*;
import envoy.server.processors.UserStatusChangeProcessor;
/**
* @author Kai S. K. Engelbart
* @since Envoy Server Standalone v0.1-alpha
*/
public final 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 final Set<Long> 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 final Map<Long, Long> 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)) {
// Notify contacts of this users offline-going
final envoy.server.data.User user =
PersistenceManager.getInstance().getUserByID(getUserIDBySocketID(socketID));
if (user != null) {
user.setLastSeen(Instant.now());
UserStatusChangeProcessor.updateUserStatus(user, UserStatus.OFFLINE);
}
// Remove the socket
sockets.entrySet().removeIf(e -> e.getValue() == socketID);
}
}
@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 userIDs of all users who are currently online
* @since Envoy Server Standalone v0.1-alpha
*/
public Set<Long> getOnlineUsers() { return sockets.keySet(); }
/**
* @param group the group to search for
* @return a set of all IDs of currently active members in this group
* @since Envoy Server Standalone v0.1-beta
*/
public Set<Long> getOnlineUsersOfGroup(Group group) {
return group.getContacts().stream().map(Contact::getID).filter(this::isOnline)
.collect(Collectors.toSet());
}
}