Understanding the flow of data and control is key to working with JSocket. Here's a simplified breakdown:
-
The Server Starts (
WebSocketServer.java)- Think of the
WebSocketServeras the main receptionist for your WebSocket service. - It listens for new client connections on a specific port.
- When a new client tries to connect, it performs the initial "WebSocket Handshake" (a special HTTP upgrade request).
# Conceptual Server Startup $ ./run_jsocket_server --port 8080 --listener YourAppLogic # WebSocketServer: Listening on port 8080... # Client trying to connect from IP: 192.168.1.101 # WebSocketServer: Performing handshake with 192.168.1.101...
- Think of the
-
Connection Established (
ClientHandler.java)- If the handshake is successful, the
WebSocketServercreates a dedicatedClientHandlerfor this specific client. - The
ClientHandleris like a personal assistant assigned to manage all communication for that one client. - It then starts two specialized workers: a
WebSocketDataReaderand aWebSocketDataWriter.
# WebSocketServer: Handshake with 192.168.1.101 successful! # WebSocketServer: Creating ClientHandler for 192.168.1.101. # ClientHandler (for 192.168.1.101): I'm now active. # ClientHandler: Starting my WebSocketDataReader (to listen for messages). # ClientHandler: Starting my WebSocketDataWriter (to send messages). # ClientHandler: Notifying YourAppLogic.onOpen(client_192_168_1_101).
- If the handshake is successful, the
-
Receiving Data (
WebSocketDataReader.java&WebSocketFrame.java)- The
WebSocketDataReaderruns in its own thread, constantly listening for incoming data from the client's connection. - When data arrives, it uses
WebSocketFrame.WebSocketFrameparseClientFrame()to decode the raw bytes into a structuredWebSocketFrame. This frame tells us if it's text, binary, a ping, etc. - The
WebSocketDataReaderthen passes this structured frame to itsClientHandler.
# WebSocketDataReader (for 192.168.1.101): Listening for data... # WebSocketDataReader: Received raw bytes: [0x81, 0x85, 0x37, 0xfa, 0x21, 0x3d, 0x7f, 0x9f, 0x4d, 0x51, 0x58] # WebSocketDataReader: Using WebSocketFrame to parse... # Parsed Frame: Type=TEXT, Content="Hello Server" # WebSocketDataReader: Telling ClientHandler about new Frame("Hello Server").
- The
-
Processing Data (
ClientHandler.java&WebSocketListener.java)- The
ClientHandlerreceives the parsedWebSocketFrame. - It looks at the frame's type (opcode):
- If it's a TEXT message, it calls
yourAppLogic.onMessage(client, "Hello Server"). (YourChessGameManageris an example ofyourAppLogicvia theWebSocketListenerinterface). - If it's a PING, the
ClientHandlerautomatically prepares a PONG frame to send back. - If it's a CLOSE frame, it starts the connection closing procedure.
- If it's a TEXT message, it calls
# ClientHandler (for 192.168.1.101): Got Frame("Hello Server") from DataReader. # ClientHandler: It's a TEXT frame. # ClientHandler: Notifying YourAppLogic.onMessage(client_192_168_1_101, "Hello Server"). # YourAppLogic (e.g., ChessGameManager): # Received "Hello Server" from client_192_168_1_101. # Let's say my logic is to reply with "Hello Client". # Calling: client_192_168_1_101.sendMessage("Hello Client").
- The
-
Sending Data (
WebSocketDataWriter.java&WebSocketFrame.java)- When your application logic (e.g.,
ChessGameManager) wants to send a message (e.g.,clientHandler.sendMessage("Hello Client")), theClientHandlercreates a newWebSocketFrame. - This frame is put into a queue for the
WebSocketDataWriter. - The
WebSocketDataWriter(also in its own thread) picks up frames from this queue, converts them back into bytes usingWebSocketFrame.toBytes(), and sends them to the client.
# ClientHandler (for 192.168.1.101): # Application wants to send "Hello Client". # Creating new WebSocketFrame: Type=TEXT, Content="Hello Client". # Adding Frame("Hello Client") to DataWriter's outgoing queue. # WebSocketDataWriter (for 192.168.1.101): Checking my queue... # WebSocketDataWriter: Found Frame("Hello Client")! # WebSocketDataWriter: Using WebSocketFrame to convert to bytes... # Raw Bytes: [0x81, 0x0c, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74] # WebSocketDataWriter: Sending bytes to client 192.168.1.101.
- When your application logic (e.g.,
-
Connection Close
- Either the client or the server can initiate a close.
- A special CLOSE frame is exchanged.
- The
ClientHandlermanages this, stops itsDataReaderandDataWriter, closes the socket, and notifies your application logic viayourAppLogic.onClose().
This cycle of reading, processing, and writing happens continuously for each connected client, all managed by their respective ClientHandler and its helpers. The WebSocketServer just focuses on accepting new clients.