Skip to content

Syncing clients ​

Setting up the server ​

As a quick reminder, let's see again the basic server set up:

java
import io.javalin.Javalin;

public class WebSocketSync {
    public static void main(String[] args) {
        Javalin app = Javalin.create().start(5001);

        app.ws("/websocket", ws -> {
            ws.onConnect(ctx -> {
                // Handle new connections
                System.out.println("New connection: " + ctx.getSessionId());
            });
        });
    }
}

Tracking sockets ​

To update all clients, we need to keep track of the WebSocket sessions. Fortunately, Javalin provides a WsContext object for each connection, which we can store in a List or Set for easy tracking.

java
import io.javalin.Javalin;
import io.javalin.websocket.WsContext;

import java.util.Collections;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

public class WebSocketSync {
    private static final Set<WsContext> connectedClients =
        Collections.newSetFromMap(new ConcurrentHashMap<>());

    public static void main(String[] args) {
        Javalin app = Javalin.create().start(5001);

        app.ws("/websocket", ws -> {
            ws.onConnect(ctx -> {
                connectedClients.add(ctx);
                System.out.println("Connected clients: " + connectedClients.size());
            });

            ws.onClose(ctx -> {
                connectedClients.remove(ctx);
                System.out.println("Connection closed. Remaining clients: " + connectedClients.size());
            });
        });
    }
}
  • The connectedClients set holds references to all currently active WebSocket sessions.

  • When a client connects, it is added to the connectedClients set.

  • When a client disconnects, it is removed from the set.

Forwarding messages ​

To broadcast messages received from one client to all other connected clients, we iterate over the connectedClients set and call the send method for each session.

java
import io.javalin.Javalin;
import io.javalin.websocket.WsContext;

import java.util.Collections;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

public class WebSocketSync {
    private static final Set<WsContext> connectedClients =
        Collections.newSetFromMap(new ConcurrentHashMap<>());

    public static void main(String[] args) {
        Javalin app = Javalin.create().start(5001);

        app.ws("/websocket", ws -> {
            ws.onConnect(ctx -> connectedClients.add(ctx));

            ws.onClose(ctx -> connectedClients.remove(ctx));

            ws.onMessage((ctx, message) -> {
                for (WsContext client : connectedClients) {
                    if (client != ctx) { // Avoid echoing the message back to the sender
                        client.send(message);
                    }
                }
            });
        });
    }
}
  • The onMessage handler receives messages from a client.

  • The message is forwarded to all other connected clients using the send method.

And that's it! Now all connected users will receive any message sent by any other user.