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 envoy.data.User; | ||||
| import envoy.event.UserStatusChangeEvent; | ||||
| import envoy.server.database.PersistenceManager; | ||||
| import envoy.server.processors.UserStatusChangeProcessor; | ||||
|  | ||||
| /** | ||||
|  * Project: <strong>envoy-server-standalone</strong><br> | ||||
|  * File: <strong>ConnectionManager.java</strong><br> | ||||
| @@ -44,6 +49,11 @@ public class ConnectionManager implements ISocketIdListener { | ||||
|  | ||||
| 	@Override | ||||
| 	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)) | ||||
| 			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); } | ||||
|  | ||||
| 	/** | ||||
| 	 * @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 | ||||
|   | ||||
| @@ -37,6 +37,7 @@ public class LoginCredentialProcessor implements ObjectProcessor<LoginCredential | ||||
|  | ||||
| 	@Override | ||||
| 	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)); | ||||
|  | ||||
| 		envoy.server.data.User user = getUser(input); | ||||
| @@ -45,7 +46,7 @@ public class LoginCredentialProcessor implements ObjectProcessor<LoginCredential | ||||
| 		if (user == null) return; | ||||
| 		// notifies contacts of this users online-going and updates his status in the | ||||
| 		// database | ||||
| 		UserStatusChangeProcessor.updateUserStatus(new UserStatusChangeEvent(user.toCommonUser()), writeProxy); | ||||
| 		UserStatusChangeProcessor.updateUserStatus(new UserStatusChangeEvent(user.toCommonUser())); | ||||
|  | ||||
| 		ConnectionManager.getInstance().registerUser(user.getId(), socketId); | ||||
|  | ||||
|   | ||||
| @@ -22,19 +22,20 @@ import envoy.server.net.ObjectWriteProxy; | ||||
|  */ | ||||
| public class UserStatusChangeProcessor implements ObjectProcessor<UserStatusChangeEvent> { | ||||
|  | ||||
| 	private static ObjectWriteProxy writeProxy; | ||||
|  | ||||
| 	@Override | ||||
| 	public Class<UserStatusChangeEvent> getInputClass() { return UserStatusChangeEvent.class; } | ||||
|  | ||||
| 	@Override | ||||
| 	public void process(UserStatusChangeEvent input, long socketId, ObjectWriteProxy writeProxy) throws IOException { | ||||
|  | ||||
| 		PersistenceManager perMan = PersistenceManager.getPersistenceManager(); | ||||
| 		// new status should not equal old status | ||||
| 		if (input.get().equals(perMan.getUserById(input.getId()).getStatus())) { | ||||
| 			System.out.println("Received an unnecessary UserStatusChangeEvent"); | ||||
| 			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 | ||||
| 	 * currently online contacts are notified. | ||||
| 	 * | ||||
| 	 * @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 | ||||
| 	 * @param evt the {@link UserStatusChangeEvent} that signals the change | ||||
| 	 * @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(); | ||||
| 		envoy.server.data.User	user	= perMan.getUserById(evt.getId()); | ||||
| 		// handling for newly logged in clients | ||||
| 		perMan.updateUserStatus(user, evt.get()); | ||||
|  | ||||
| 		// 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 | ||||
| 	 * changed | ||||
| 	 * | ||||
| 	 * @param evt        the {@link UserStatusChangeEvent} to send to other clients | ||||
| 	 * @param user       the {@link User} | ||||
| 	 * @param writeProxy the {@link ObjectWriteProxy} that is used to send objects | ||||
| 	 *                   back to clients | ||||
| 	 * @param evt  the {@link UserStatusChangeEvent} to send to other clients | ||||
| 	 * @param user the {@link User} | ||||
| 	 * @throws IOException if sending this update failed for any contact | ||||
| 	 * @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(); | ||||
| 		for (User contact : user.getContacts()) | ||||
| 			if (conMan.isOnline(contact.getId())) writeProxy.write(conMan.getSocketId(contact.getId()), evt); | ||||
| 		try { | ||||
| 			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