Allow sending username updates
This commit is contained in:
parent
d51cbc6d75
commit
60fa5adfe4
6 changed files with 76 additions and 30 deletions
|
@ -44,11 +44,11 @@ public class InsaPresence implements Presence {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void subscribe(ParametrizedCallback<ArrayList<UserInformation>> callback, ErrorCallback errorCallback) {
|
||||
public void subscribe(UserInformation userInformation, ParametrizedCallback<ArrayList<UserInformation>> callback, ErrorCallback errorCallback) {
|
||||
if (!isConnected()) {
|
||||
connectToPresence(
|
||||
() -> proxy.connect(() -> {
|
||||
sendSubscribeMessage(errorCallback);
|
||||
notify(userInformation, null, errorCallback);
|
||||
receiveSubscribeNotifications(callback, errorCallback);
|
||||
}, errorCallback),
|
||||
errorCallback);
|
||||
|
@ -57,15 +57,6 @@ public class InsaPresence implements Presence {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send current user information to tell the server who is subscribing
|
||||
*
|
||||
* @param errorCallback Called on connection error
|
||||
*/
|
||||
private void sendSubscribeMessage(ErrorCallback errorCallback) {
|
||||
presenceConnection.send(new UserInformation(CurrentUser.getInstance()), null, errorCallback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits for presence server response to the subscribe request
|
||||
*
|
||||
|
@ -106,6 +97,11 @@ public class InsaPresence implements Presence {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notify(UserInformation newInformation, @Nullable SimpleCallback callback, @Nullable ErrorCallback errorCallback) {
|
||||
presenceConnection.send(newInformation, callback, errorCallback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Connects to the presence server by TCP
|
||||
*
|
||||
|
|
|
@ -18,12 +18,12 @@ import java.util.ArrayList;
|
|||
public interface Presence {
|
||||
|
||||
/**
|
||||
* Subscribes to this presence server notifications.
|
||||
* Subscribes to this presence server notifications and publish current status.
|
||||
* A list of Ids representing the current active users is returned.
|
||||
*
|
||||
* @param callback Called when subscription completes
|
||||
*/
|
||||
void subscribe(ParametrizedCallback<ArrayList<UserInformation>> callback, @Nullable ErrorCallback errorCallback);
|
||||
void subscribe(UserInformation userInformation, ParametrizedCallback<ArrayList<UserInformation>> callback, @Nullable ErrorCallback errorCallback);
|
||||
|
||||
/**
|
||||
* Stops subscription to the presence server by closing TCP connections.
|
||||
|
@ -34,6 +34,14 @@ public interface Presence {
|
|||
*/
|
||||
void unsubscribe(SimpleCallback callback, @Nullable ErrorCallback errorCallback);
|
||||
|
||||
/**
|
||||
* Notifies the presence server of any changes to the current user
|
||||
*
|
||||
* @param newInformation The new information to send
|
||||
* @param callback Called when notify completes
|
||||
*/
|
||||
void notify(UserInformation newInformation, @Nullable SimpleCallback callback, @Nullable ErrorCallback errorCallback);
|
||||
|
||||
/**
|
||||
* Gets the proxy.
|
||||
* This can be used to initialize a
|
||||
|
|
|
@ -15,6 +15,7 @@ import fr.insa.clavardator.client.ui.dialogs.SnackbarController;
|
|||
import fr.insa.clavardator.client.ui.users.UserListController;
|
||||
import fr.insa.clavardator.client.users.CurrentUser;
|
||||
import fr.insa.clavardator.client.users.UserList;
|
||||
import fr.insa.clavardator.lib.users.UserInformation;
|
||||
import fr.insa.clavardator.lib.util.Log;
|
||||
import javafx.application.Platform;
|
||||
import javafx.fxml.FXML;
|
||||
|
@ -59,13 +60,31 @@ public class MainController implements Initializable {
|
|||
online = false;
|
||||
currentUser = CurrentUser.getInstance();
|
||||
currentUser.addObserver(propertyChangeEvent -> {
|
||||
if (propertyChangeEvent.getPropertyName().equals("state")) {
|
||||
final String propertyName = propertyChangeEvent.getPropertyName();
|
||||
if (propertyName.equals("state")) {
|
||||
final CurrentUser.State newState = (CurrentUser.State) propertyChangeEvent.getNewValue();
|
||||
onCurrentUserStateChange(newState);
|
||||
} else if (propertyName.equals("username")) {
|
||||
final String newUsername = (String) propertyChangeEvent.getNewValue();
|
||||
onCurrentUserNameChange(newUsername);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void onCurrentUserNameChange(String newUsername) {
|
||||
if (online) {
|
||||
if (userList != null) {
|
||||
userList.propagateUsernameChange();
|
||||
}
|
||||
if (presenceServer != null) {
|
||||
presenceServer.notify(
|
||||
new UserInformation(CurrentUser.getInstance().getId(), newUsername),
|
||||
null,
|
||||
null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the current user becomes valid, start the chat.
|
||||
* If it is invalid or not set, show the login screen.
|
||||
|
@ -286,6 +305,7 @@ public class MainController implements Initializable {
|
|||
private void subscribeToPresenceServer() {
|
||||
if (presenceServer != null && online) {
|
||||
presenceServer.subscribe(
|
||||
new UserInformation(CurrentUser.getInstance()),
|
||||
param -> userList.onReceivePresenceNotification(
|
||||
param,
|
||||
presenceServer.getProxy()),
|
||||
|
|
|
@ -7,6 +7,8 @@ import com.jfoenix.validation.base.ValidatorBase;
|
|||
import fr.insa.clavardator.client.ui.ButtonPressEvent;
|
||||
import fr.insa.clavardator.client.users.CurrentUser;
|
||||
import fr.insa.clavardator.client.users.UserList;
|
||||
import fr.insa.clavardator.lib.util.ParametrizedCallback;
|
||||
import fr.insa.clavardator.lib.util.SimpleCallback;
|
||||
import javafx.beans.property.ReadOnlyBooleanWrapper;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.fxml.FXML;
|
||||
|
@ -179,9 +181,6 @@ public class EditUsernameDialogController implements Initializable {
|
|||
if (successListener != null) {
|
||||
successListener.onPress();
|
||||
}
|
||||
if (userList != null) {
|
||||
userList.propagateUsernameChange();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -54,18 +54,20 @@ public class UserList {
|
|||
if (savedUser != null) {
|
||||
if (savedUser.isActive()) {
|
||||
if (userInfo.getState() == UserState.DISCONNECTED) {
|
||||
Log.v(getClass().getSimpleName(), "Received disconnected user from presence server already known and connected, disconnecting...");
|
||||
Log.v(getClass().getSimpleName(), "Received disconnected user from presence server was already known and connected, disconnecting...");
|
||||
savedUser.disconnect();
|
||||
} else {
|
||||
Log.v(getClass().getSimpleName(), "Received user from presence server already known and connected");
|
||||
Log.v(getClass().getSimpleName(), "Received user from presence server was already known and connected, updating info...");
|
||||
savedUser.setState(userInfo.getState());
|
||||
savedUser.setUsername(userInfo.getUsername());
|
||||
}
|
||||
} else {
|
||||
if (userInfo.getState() == UserState.CONNECTED) {
|
||||
Log.v(getClass().getSimpleName(), "Received user from presence server already known but not connected, connecting...");
|
||||
Log.v(getClass().getSimpleName(), "Received user from presence server was already known but not connected, connecting...");
|
||||
savedUser.init(proxy, userInfo.id, userInfo.getUsername(),
|
||||
e -> Log.e(getClass().getSimpleName(), "Error with user " + userInfo.getUsername(), e));
|
||||
} else {
|
||||
Log.v(getClass().getSimpleName(), "Received disconnected user from presence server already known and not connected.");
|
||||
Log.v(getClass().getSimpleName(), "Received disconnected user from presence server was already known and disconnected.");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -12,6 +12,7 @@ import java.net.Socket;
|
|||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class Presence {
|
||||
private static final int PRESENCE_PORT = 35650;
|
||||
|
@ -29,17 +30,30 @@ public class Presence {
|
|||
public void publish(UserInformation info) {
|
||||
ArrayList<UserInformation> msg = new ArrayList<>(1);
|
||||
msg.add(info);
|
||||
for (TcpConnection subscriber : subscribers.values()) {
|
||||
subscriber.send(msg, null,
|
||||
e -> Log.e(getClass().getSimpleName(), "Error while publishing user information", e));
|
||||
for (Map.Entry<String,TcpConnection> entry : subscribers.entrySet()) {
|
||||
// Do not send update to self
|
||||
if (!entry.getKey().equals(info.id)) {
|
||||
entry.getValue().send(msg, null,
|
||||
e -> Log.e(getClass().getSimpleName(), "Error while publishing user information", e));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateUser(UserInformation userInformation) {
|
||||
connectedUsers.removeIf(ui -> userInformation.id.equals(ui.id));
|
||||
connectedUsers.add(userInformation);
|
||||
}
|
||||
|
||||
private void adduser(UserInformation userInformation, TcpConnection userConnection) {
|
||||
subscribers.put(userInformation.id, userConnection);
|
||||
connectedUsers.add(userInformation);
|
||||
}
|
||||
|
||||
public void subscribe(Socket socket) {
|
||||
TcpConnection user = new TcpConnection(socket);
|
||||
TcpConnection userConnection = new TcpConnection(socket);
|
||||
|
||||
// Receive user information
|
||||
user.receiveOne(o -> {
|
||||
userConnection.receiveOne(o -> {
|
||||
if (o instanceof UserInformation) {
|
||||
UserInformation userInformation = ((UserInformation) o);
|
||||
Log.v(getClass().getSimpleName(), "Registering user " + userInformation.id +
|
||||
|
@ -50,13 +64,20 @@ public class Presence {
|
|||
|
||||
// Send the list of connected users to the new subscriber. We're cloning it because we're modifying it
|
||||
// just after this call, while the sender thread might not have send it yet
|
||||
user.send((Serializable) connectedUsers.clone(), null,
|
||||
userConnection.send((Serializable) connectedUsers.clone(), null,
|
||||
e -> Log.e(getClass().getSimpleName(), "Error while receiving user information", e));
|
||||
|
||||
subscribers.put(userInformation.id, user);
|
||||
connectedUsers.add(userInformation);
|
||||
adduser(userInformation, userConnection);
|
||||
|
||||
user.receive(msg -> Log.w(getClass().getSimpleName(), "Received an unexpected message " + msg),
|
||||
userConnection.receive(msg -> {
|
||||
if (msg instanceof UserInformation) {
|
||||
UserInformation newUserInformation = ((UserInformation) msg);
|
||||
Log.v(getClass().getSimpleName(), "Receiving user status update " + newUserInformation.id +
|
||||
" (" + newUserInformation.getUsername() + ")");
|
||||
updateUser(newUserInformation);
|
||||
publish(newUserInformation);
|
||||
}
|
||||
},
|
||||
e -> {
|
||||
if (e instanceof EOFException) {
|
||||
unsubscribe(userInformation);
|
||||
|
|
Loading…
Reference in a new issue