Syncing clients
Setting up the server
As a quick reminder, let's see again the basic server set up:
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.
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.
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.