Added status update for when a client goes offline
This commit is contained in:
parent
34e1b610ac
commit
af865b77ad
@ -7,6 +7,11 @@ import java.util.Set;
|
|||||||
|
|
||||||
import com.jenkov.nioserver.ISocketIdListener;
|
import com.jenkov.nioserver.ISocketIdListener;
|
||||||
|
|
||||||
|
import envoy.data.User;
|
||||||
|
import envoy.event.UserStatusChangeEvent;
|
||||||
|
import envoy.server.database.PersistenceManager;
|
||||||
|
import envoy.server.processors.UserStatusChangeProcessor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Project: <strong>envoy-server-standalone</strong><br>
|
* Project: <strong>envoy-server-standalone</strong><br>
|
||||||
* File: <strong>ConnectionManager.java</strong><br>
|
* File: <strong>ConnectionManager.java</strong><br>
|
||||||
@ -44,6 +49,11 @@ public class ConnectionManager implements ISocketIdListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void socketCancelled(long socketId) {
|
public void socketCancelled(long socketId) {
|
||||||
|
// notifying contacts of this users offline-going
|
||||||
|
long clientId = getUserIdBySocketId(socketId);
|
||||||
|
User user = new User(clientId, PersistenceManager.getPersistenceManager().getUserById(clientId).getName());
|
||||||
|
UserStatusChangeProcessor.updateUserStatus(new UserStatusChangeEvent(user));
|
||||||
|
// removing the socket
|
||||||
if (!pendingSockets.remove(socketId))
|
if (!pendingSockets.remove(socketId))
|
||||||
sockets.entrySet().stream().filter(e -> e.getValue() == socketId).forEach(e -> sockets.remove(e.getValue()));
|
sockets.entrySet().stream().filter(e -> e.getValue() == socketId).forEach(e -> sockets.remove(e.getValue()));
|
||||||
}
|
}
|
||||||
@ -70,6 +80,15 @@ public class ConnectionManager implements ISocketIdListener {
|
|||||||
*/
|
*/
|
||||||
public long getSocketId(long userId) { return sockets.get(userId); }
|
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
|
* @param userId the ID of the user to check for
|
||||||
* @return {@code true} if the user is online
|
* @return {@code true} if the user is online
|
||||||
|
@ -37,6 +37,7 @@ public class LoginCredentialProcessor implements ObjectProcessor<LoginCredential
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void process(LoginCredentials input, long socketId, ObjectWriteProxy writeProxy) throws IOException {
|
public void process(LoginCredentials input, long socketId, ObjectWriteProxy writeProxy) throws IOException {
|
||||||
|
UserStatusChangeProcessor.setWriteProxy(writeProxy);
|
||||||
System.out.println(String.format("Received login credentials %s from socket ID %d", input, socketId));
|
System.out.println(String.format("Received login credentials %s from socket ID %d", input, socketId));
|
||||||
|
|
||||||
envoy.server.data.User user = getUser(input);
|
envoy.server.data.User user = getUser(input);
|
||||||
@ -45,7 +46,7 @@ public class LoginCredentialProcessor implements ObjectProcessor<LoginCredential
|
|||||||
if (user == null) return;
|
if (user == null) return;
|
||||||
// notifies contacts of this users online-going and updates his status in the
|
// notifies contacts of this users online-going and updates his status in the
|
||||||
// database
|
// database
|
||||||
UserStatusChangeProcessor.updateUserStatus(new UserStatusChangeEvent(user.toCommonUser()), writeProxy);
|
UserStatusChangeProcessor.updateUserStatus(new UserStatusChangeEvent(user.toCommonUser()));
|
||||||
|
|
||||||
ConnectionManager.getInstance().registerUser(user.getId(), socketId);
|
ConnectionManager.getInstance().registerUser(user.getId(), socketId);
|
||||||
|
|
||||||
|
@ -22,19 +22,20 @@ import envoy.server.net.ObjectWriteProxy;
|
|||||||
*/
|
*/
|
||||||
public class UserStatusChangeProcessor implements ObjectProcessor<UserStatusChangeEvent> {
|
public class UserStatusChangeProcessor implements ObjectProcessor<UserStatusChangeEvent> {
|
||||||
|
|
||||||
|
private static ObjectWriteProxy writeProxy;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Class<UserStatusChangeEvent> getInputClass() { return UserStatusChangeEvent.class; }
|
public Class<UserStatusChangeEvent> getInputClass() { return UserStatusChangeEvent.class; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void process(UserStatusChangeEvent input, long socketId, ObjectWriteProxy writeProxy) throws IOException {
|
public void process(UserStatusChangeEvent input, long socketId, ObjectWriteProxy writeProxy) throws IOException {
|
||||||
|
|
||||||
PersistenceManager perMan = PersistenceManager.getPersistenceManager();
|
PersistenceManager perMan = PersistenceManager.getPersistenceManager();
|
||||||
// new status should not equal old status
|
// new status should not equal old status
|
||||||
if (input.get().equals(perMan.getUserById(input.getId()).getStatus())) {
|
if (input.get().equals(perMan.getUserById(input.getId()).getStatus())) {
|
||||||
System.out.println("Received an unnecessary UserStatusChangeEvent");
|
System.out.println("Received an unnecessary UserStatusChangeEvent");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
updateUserStatus(input, writeProxy);
|
updateUserStatus(input);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,19 +44,16 @@ public class UserStatusChangeProcessor implements ObjectProcessor<UserStatusChan
|
|||||||
* currently online contacts are notified.
|
* currently online contacts are notified.
|
||||||
*
|
*
|
||||||
* @param evt the {@link UserStatusChangeEvent} that signals the change
|
* @param evt the {@link UserStatusChangeEvent} that signals the change
|
||||||
* @param writeProxy the {@link ObjectWriteProxy} that is used to send objects
|
|
||||||
* back to clients
|
|
||||||
* @throws IOException if sending this update failed for any contact
|
|
||||||
* @since Envoy Server Standalone v0.1-alpha
|
* @since Envoy Server Standalone v0.1-alpha
|
||||||
*/
|
*/
|
||||||
public static void updateUserStatus(UserStatusChangeEvent evt, ObjectWriteProxy writeProxy) throws IOException {
|
public static void updateUserStatus(UserStatusChangeEvent evt) {
|
||||||
|
// handling for newly logged in clients
|
||||||
PersistenceManager perMan = PersistenceManager.getPersistenceManager();
|
PersistenceManager perMan = PersistenceManager.getPersistenceManager();
|
||||||
envoy.server.data.User user = perMan.getUserById(evt.getId());
|
envoy.server.data.User user = perMan.getUserById(evt.getId());
|
||||||
// handling for newly logged in clients
|
|
||||||
perMan.updateUserStatus(user, evt.get());
|
perMan.updateUserStatus(user, evt.get());
|
||||||
|
|
||||||
// handling for contacts that are already online
|
// handling for contacts that are already online
|
||||||
notifyContacts(evt, user, writeProxy);
|
notifyContacts(evt, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -64,15 +62,29 @@ public class UserStatusChangeProcessor implements ObjectProcessor<UserStatusChan
|
|||||||
*
|
*
|
||||||
* @param evt the {@link UserStatusChangeEvent} to send to other clients
|
* @param evt the {@link UserStatusChangeEvent} to send to other clients
|
||||||
* @param user the {@link User}
|
* @param user the {@link User}
|
||||||
* @param writeProxy the {@link ObjectWriteProxy} that is used to send objects
|
|
||||||
* back to clients
|
|
||||||
* @throws IOException if sending this update failed for any contact
|
* @throws IOException if sending this update failed for any contact
|
||||||
* @since Envoy Server Standalone v0.1-alpha
|
* @since Envoy Server Standalone v0.1-alpha
|
||||||
*/
|
*/
|
||||||
public static void notifyContacts(UserStatusChangeEvent evt, envoy.server.data.User user, ObjectWriteProxy writeProxy) throws IOException {
|
private static void notifyContacts(UserStatusChangeEvent evt, envoy.server.data.User user) {
|
||||||
ConnectionManager conMan = ConnectionManager.getInstance();
|
ConnectionManager conMan = ConnectionManager.getInstance();
|
||||||
|
try {
|
||||||
for (User contact : user.getContacts())
|
for (User contact : user.getContacts())
|
||||||
if (conMan.isOnline(contact.getId())) writeProxy.write(conMan.getSocketId(contact.getId()), evt);
|
if (conMan.isOnline(contact.getId())) writeProxy.write(conMan.getSocketId(contact.getId()), evt);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
System.err.println("Could not notify online contacts of user" + evt.getId() + "that his status changed");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is only called by the LoginCredentialProcessor because every
|
||||||
|
* user needs to login (open a socket) before changing his status.
|
||||||
|
* Needed to ensure propagation of events because an uninitialised writeProxy
|
||||||
|
* would cause problems.
|
||||||
|
*
|
||||||
|
* @param writeProxy the writeProxy that is used to send objects back to clients
|
||||||
|
* @since Envoy Server Standalone v0.1-alpha
|
||||||
|
*/
|
||||||
|
public static void setWriteProxy(ObjectWriteProxy writeProxy) { UserStatusChangeProcessor.writeProxy = writeProxy; }
|
||||||
|
|
||||||
}
|
}
|
Reference in New Issue
Block a user