Added UserStatusChangeProcessor
additionally added UserStatus updating in the LoginCredentialProcessor yet missing: method to handle clients going offline
This commit is contained in:
		| @@ -64,7 +64,7 @@ public class ConnectionManager implements ISocketIdListener { | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @param userId the ID of the user registered at the a socket | ||||
| 	 * @param userId the ID of the user registered at a socket | ||||
| 	 * @return the ID of the socket | ||||
| 	 * @since Envoy Server Standalone v0.1-alpha | ||||
| 	 */ | ||||
|   | ||||
| @@ -36,6 +36,7 @@ public class Startup { | ||||
| 		processors.add(new LoginCredentialProcessor()); | ||||
| 		processors.add(new MessageProcessor()); | ||||
| 		processors.add(new MessageStatusChangeProcessor()); | ||||
| 		processors.add(new UserStatusChangeProcessor()); | ||||
| 		processors.add(new IdGeneratorRequestProcessor()); | ||||
| 		Server server = new Server(8080, () -> new ObjectMessageReader(), new ObjectMessageProcessor(processors)); | ||||
|  | ||||
|   | ||||
| @@ -5,6 +5,7 @@ import java.util.List; | ||||
| import javax.persistence.EntityManager; | ||||
| import javax.persistence.Persistence; | ||||
|  | ||||
| import envoy.data.User.UserStatus; | ||||
| import envoy.server.data.ConfigItem; | ||||
| import envoy.server.data.Message; | ||||
| import envoy.server.data.User; | ||||
| @@ -164,4 +165,16 @@ public class PersistenceManager { | ||||
| 	// TODO current solution gets all users, not just contacts. Should be changed to | ||||
| 	// entityManager.createNamedQuery("getContactsOfUser").setParameter("user", | ||||
| 	// user).getResultList(); | ||||
|  | ||||
| 	/** | ||||
| 	 * Updates the {@link UserStatus} in the database. | ||||
| 	 * | ||||
| 	 * @param user   the {@link User} who changes his status | ||||
| 	 * @param status the new status of that user | ||||
| 	 * @since Envoy Server Standalone v0.1-alpha | ||||
| 	 */ | ||||
| 	public void updateUserStatusInDatabase(User user, UserStatus status) { | ||||
| 		user.setStatus(status); | ||||
| 		persistenceManager.updateUser(user); | ||||
| 	} | ||||
| } | ||||
| @@ -33,7 +33,6 @@ public class ObjectMessageProcessor implements IMessageProcessor { | ||||
| 	 */ | ||||
| 	public ObjectMessageProcessor(Set<ObjectProcessor<?>> processors) { this.processors = processors; } | ||||
|  | ||||
| 	@SuppressWarnings("unchecked") | ||||
| 	@Override | ||||
| 	public void process(Message message, WriteProxy writeProxy) { | ||||
| 		try (ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(message.sharedArray, message.offset + 4, message.length - 4))) { | ||||
|   | ||||
| @@ -22,7 +22,7 @@ public class ObjectWriteProxy { | ||||
| 	private final WriteProxy writeProxy; | ||||
|  | ||||
| 	/** | ||||
| 	 * Creates an instance of @link{ObjectWriteProxy}. | ||||
| 	 * Creates an instance of {@link ObjectWriteProxy}. | ||||
| 	 * | ||||
| 	 * @param writeProxy the {@link WriteProxy} to write objects to another client | ||||
| 	 * @since Envoy Server Standalone v0.1-alpha | ||||
|   | ||||
| @@ -10,6 +10,7 @@ import envoy.data.Contacts; | ||||
| import envoy.data.LoginCredentials; | ||||
| import envoy.data.Message.MessageStatus; | ||||
| import envoy.data.User; | ||||
| import envoy.event.UserStatusChangeEvent; | ||||
| import envoy.server.ConnectionManager; | ||||
| import envoy.server.ObjectProcessor; | ||||
| import envoy.server.data.Message; | ||||
| @@ -29,7 +30,7 @@ import envoy.server.net.ObjectWriteProxy; | ||||
|  */ | ||||
| public class LoginCredentialProcessor implements ObjectProcessor<LoginCredentials> { | ||||
|  | ||||
| 	private PersistenceManager	persistenceManager	= PersistenceManager.getPersistenceManager(); | ||||
| 	private PersistenceManager persistenceManager = PersistenceManager.getPersistenceManager(); | ||||
|  | ||||
| 	@Override | ||||
| 	public Class<LoginCredentials> getInputClass() { return LoginCredentials.class; } | ||||
| @@ -41,9 +42,10 @@ public class LoginCredentialProcessor implements ObjectProcessor<LoginCredential | ||||
| 		envoy.server.data.User user = getUser(input); | ||||
|  | ||||
| 		// Not logged in successfully | ||||
| 		if (user == null) { | ||||
| 			return; | ||||
| 		} | ||||
| 		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); | ||||
|  | ||||
| 		ConnectionManager.getInstance().registerUser(user.getId(), socketId); | ||||
|  | ||||
| @@ -73,7 +75,7 @@ public class LoginCredentialProcessor implements ObjectProcessor<LoginCredential | ||||
|  | ||||
| 	private envoy.server.data.User getUser(LoginCredentials credentials) { | ||||
| 		envoy.server.data.User user; | ||||
| 		 | ||||
|  | ||||
| 		if (credentials.isRegistration()) { | ||||
| 			user = new envoy.server.data.User(); | ||||
| 			user.setName(credentials.getName()); | ||||
| @@ -84,10 +86,8 @@ public class LoginCredentialProcessor implements ObjectProcessor<LoginCredential | ||||
| 		} else { | ||||
| 			user = persistenceManager.getUserByName(credentials.getName()); | ||||
| 			// TODO: Implement error when user does not exist | ||||
| 			if (!Arrays.equals(credentials.getPasswordHash(), user.getPasswordHash())) { | ||||
| 				// TODO: Wrong Password Response | ||||
| 			if (!Arrays.equals(credentials.getPasswordHash(), user.getPasswordHash())) // TODO: Wrong Password Response | ||||
| 				return null; | ||||
| 			} | ||||
| 		} | ||||
| 		return user; | ||||
| 	} | ||||
|   | ||||
| @@ -0,0 +1,78 @@ | ||||
| package envoy.server.processors; | ||||
|  | ||||
| import java.io.IOException; | ||||
|  | ||||
| import envoy.data.User.UserStatus; | ||||
| import envoy.event.UserStatusChangeEvent; | ||||
| import envoy.server.ConnectionManager; | ||||
| import envoy.server.ObjectProcessor; | ||||
| import envoy.server.data.User; | ||||
| import envoy.server.database.PersistenceManager; | ||||
| import envoy.server.net.ObjectWriteProxy; | ||||
|  | ||||
| /** | ||||
|  * This processor handles incoming {@link UserStatusChangeEvent}.<br> | ||||
|  * <br> | ||||
|  * Project: <strong>envoy-server-standalone</strong><br> | ||||
|  * File: <strong>UserStatusChangeProcessor.java</strong><br> | ||||
|  * Created: <strong>1 Feb 2020</strong><br> | ||||
|  * | ||||
|  * @author Leon Hofmeister | ||||
|  * @since Envoy Server Standalone v0.1-alpha | ||||
|  */ | ||||
| public class UserStatusChangeProcessor implements ObjectProcessor<UserStatusChangeEvent> { | ||||
|  | ||||
| 	@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); | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * 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 | ||||
| 	 * @since Envoy Server Standalone v0.1-alpha | ||||
| 	 */ | ||||
| 	public static void updateUserStatus(UserStatusChangeEvent evt, ObjectWriteProxy writeProxy) throws IOException { | ||||
| 		PersistenceManager		perMan	= PersistenceManager.getPersistenceManager(); | ||||
| 		envoy.server.data.User	user	= perMan.getUserById(evt.getId()); | ||||
| 		// handling for newly logged in clients | ||||
| 		perMan.updateUserStatusInDatabase(user, evt.get()); | ||||
|  | ||||
| 		// handling for contacts that are already online | ||||
| 		notifyContacts(evt, user, writeProxy); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * 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 | ||||
| 	 * @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 { | ||||
| 		ConnectionManager conMan = ConnectionManager.getInstance(); | ||||
| 		for (User contact : user.getContacts()) | ||||
| 			if (conMan.isOnline(contact.getId())) writeProxy.write(conMan.getSocketId(contact.getId()), evt); | ||||
| 	} | ||||
|  | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 delvh
					delvh