Added status update for when a client goes offline
This commit is contained in:
		| @@ -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); | ||||||
|  |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -42,37 +43,48 @@ public class UserStatusChangeProcessor implements ObjectProcessor<UserStatusChan | |||||||
| 	 * Sets the {@link UserStatus} for a given user. Both offline contacts and | 	 * Sets the {@link UserStatus} for a given user. Both offline contacts and | ||||||
| 	 * 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); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	/** | 	/** | ||||||
| 	 * notifies active contacts of this {@link User} that his {@link UserStatus} has | 	 * notifies active contacts of this {@link User} that his {@link UserStatus} has | ||||||
| 	 * changed | 	 * changed | ||||||
| 	 * | 	 * | ||||||
| 	 * @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(); | ||||||
| 		for (User contact : user.getContacts()) | 		try { | ||||||
| 			if (conMan.isOnline(contact.getId())) writeProxy.write(conMan.getSocketId(contact.getId()), evt); | 			for (User contact : user.getContacts()) | ||||||
|  | 				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
	 delvh
					delvh