1

In my application I have a sessionhandler that stores all connected sessions when they connect and removes them if they disconnects properly. If they do not I keep the sessions and if they reconnect I replace the old session with the new one. (The code below seems stupid, but it is just to make my point)

@ServerEndpoint(value = "/games")
public class GameEndPoint {

    @Inject
    private GameSessionHandler sessionHandler;

    @OnOpen
    public void open(Session session) {
        sessionHandler.addSession(session);
    }

    @OnClose
    public void close(Session session, CloseReason closeReason) {
        sessionHandler.sessionClosed(session, closeReason.getCloseCode());
    }

    @OnError
    public void onError(Throwable error) {
        LOGGER.log(Level.SEVERE, "Socket connection error", error);
    }

    @OnMessage
    public String handleMessage(String payload, Session session) {
        return payload;
    }
}

@Singleton
public class GameSessionHandler implements Serializable {

    private final Set<Session> sessions = new HashSet<>();

    public void addSession(Session session) {
        for(Session existing: sessions) {
            if(existing.equals(session)) {//DOES NOT WORK
                //client reconnected!
                sessions.remove(existing);
                break;
            }
        }
        sessions.add(session);
    }

    public void removeSession(Session session) {
        if (CloseReason.CloseCodes.NORMAL_CLOSURE.equals(reason)) {
            sessions.remove(session)
        }
    }
}

The problem is: how can I check that the session is for a client that was connected earlier, so that I can replace the session with the new open one?

Edit: This is needed because my client is a html5 application where the user can refresh/navigate on the page, and then the connection is lost. Whenever he attempts to reconnect I want to know which game he was currently playing. If the user is on a unstable connection (ie. on a mobile phone), also the connection will be lost from time to time.

Runar Halse
  • 3,528
  • 10
  • 39
  • 59

1 Answers1

1

I am not able to make a solid enough check for this, so ended up sending a unique string (uuid) to the client upon connecting. If client connects with a query param giving his old uuid, I use this to figure out who he is. I just trust the client to be who he says he is, and anyhow he can only connect with this uuid if the old session with this uuid has disconnected.

I have not considered security at all, and if I had I should possibly use something like diffie hellman key exchange so the only two parties that know the shared uuid is the server and the client.

Runar Halse
  • 3,528
  • 10
  • 39
  • 59
  • I adopted a similar approach for an application I'm working on (where two clients use the WS server to pass messages to each other). One of the clients works with a DB, so it uses the DB name as the identifier. The problem I'm facing is that at some point in the exchange of messages, the connection breaks (or one of two clients loses connection and doesn't reconnect, despite having code to make it do that, and the other one sits idly waiting for messages on the open connection, or so I assume). – Agi Hammerthief Jun 11 '18 at 13:23