|
| 1 | +### ⚙️ Core Logic Explained: How JSocket Works |
| 2 | + |
| 3 | +Understanding the flow of data and control is key to working with JSocket. Here's a simplified breakdown: |
| 4 | + |
| 5 | +1. **The Server Starts (`WebSocketServer.java`)** |
| 6 | + * Think of the [`WebSocketServer`](javaWebsocketChess/websocketCore/src/main/java/com/jSocket/websocket/WebSocketServer.java) as the main receptionist for your WebSocket service. |
| 7 | + * It listens for new client connections on a specific port. |
| 8 | + * When a new client tries to connect, it performs the initial "WebSocket Handshake" (a special HTTP upgrade request). |
| 9 | + |
| 10 | + ```bash |
| 11 | + # Conceptual Server Startup |
| 12 | + $ ./run_jsocket_server --port 8080 --listener YourAppLogic |
| 13 | + |
| 14 | + # WebSocketServer: Listening on port 8080... |
| 15 | + # Client trying to connect from IP: 192.168.1.101 |
| 16 | + # WebSocketServer: Performing handshake with 192.168.1.101... |
| 17 | + ``` |
| 18 | + |
| 19 | +2. **Connection Established (`ClientHandler.java`)** |
| 20 | + * If the handshake is successful, the `WebSocketServer` creates a dedicated [`ClientHandler`](javaWebsocketChess/websocketCore/src/main/java/com/jSocket/websocket/server/ClientHandler.java) for this specific client. |
| 21 | + * The `ClientHandler` is like a personal assistant assigned to manage all communication for that one client. |
| 22 | + * It then starts two specialized workers: a `WebSocketDataReader` and a `WebSocketDataWriter`. |
| 23 | + |
| 24 | + ```bash |
| 25 | + # WebSocketServer: Handshake with 192.168.1.101 successful! |
| 26 | + # WebSocketServer: Creating ClientHandler for 192.168.1.101. |
| 27 | + |
| 28 | + # ClientHandler (for 192.168.1.101): I'm now active. |
| 29 | + # ClientHandler: Starting my WebSocketDataReader (to listen for messages). |
| 30 | + # ClientHandler: Starting my WebSocketDataWriter (to send messages). |
| 31 | + # ClientHandler: Notifying YourAppLogic.onOpen(client_192_168_1_101). |
| 32 | + ``` |
| 33 | + |
| 34 | +3. **Receiving Data (`WebSocketDataReader.java` & `WebSocketFrame.java`)** |
| 35 | + * The [`WebSocketDataReader`](javaWebsocketChess/websocketCore/src/main/java/com/jSocket/websocket/server/WebSocketDataReader.java) runs in its own thread, constantly listening for incoming data from the client's connection. |
| 36 | + * When data arrives, it uses [`WebSocketFrame.WebSocketFrameparseClientFrame()`](javaWebsocketChess/websocketCore/src/main/java/com/jSocket/websocket/server/WebSocketFrame.java) to decode the raw bytes into a structured `WebSocketFrame`. This frame tells us if it's text, binary, a ping, etc. |
| 37 | + * The `WebSocketDataReader` then passes this structured frame to its `ClientHandler`. |
| 38 | + |
| 39 | + ```bash |
| 40 | + # WebSocketDataReader (for 192.168.1.101): Listening for data... |
| 41 | + # WebSocketDataReader: Received raw bytes: [0x81, 0x85, 0x37, 0xfa, 0x21, 0x3d, 0x7f, 0x9f, 0x4d, 0x51, 0x58] |
| 42 | + # WebSocketDataReader: Using WebSocketFrame to parse... |
| 43 | + # Parsed Frame: Type=TEXT, Content="Hello Server" |
| 44 | + # WebSocketDataReader: Telling ClientHandler about new Frame("Hello Server"). |
| 45 | + ``` |
| 46 | + |
| 47 | +4. **Processing Data (`ClientHandler.java` & `WebSocketListener.java`)** |
| 48 | + * The `ClientHandler` receives the parsed `WebSocketFrame`. |
| 49 | + * It looks at the frame's type (opcode): |
| 50 | + * If it's a **TEXT** message, it calls `yourAppLogic.onMessage(client, "Hello Server")`. (Your `ChessGameManager` is an example of `yourAppLogic` via the [`WebSocketListener`](javaWebsocketChess/websocketCore/src/main/java/com/jSocket/websocket/server/WebSocketListener.java) interface). |
| 51 | + * If it's a **PING**, the `ClientHandler` automatically prepares a PONG frame to send back. |
| 52 | + * If it's a **CLOSE** frame, it starts the connection closing procedure. |
| 53 | + |
| 54 | + ```bash |
| 55 | + # ClientHandler (for 192.168.1.101): Got Frame("Hello Server") from DataReader. |
| 56 | + # ClientHandler: It's a TEXT frame. |
| 57 | + # ClientHandler: Notifying YourAppLogic.onMessage(client_192_168_1_101, "Hello Server"). |
| 58 | + |
| 59 | + # YourAppLogic (e.g., ChessGameManager): |
| 60 | + # Received "Hello Server" from client_192_168_1_101. |
| 61 | + # Let's say my logic is to reply with "Hello Client". |
| 62 | + # Calling: client_192_168_1_101.sendMessage("Hello Client"). |
| 63 | + ``` |
| 64 | + |
| 65 | +5. **Sending Data (`WebSocketDataWriter.java` & `WebSocketFrame.java`)** |
| 66 | + * When your application logic (e.g., `ChessGameManager`) wants to send a message (e.g., `clientHandler.sendMessage("Hello Client")`), the `ClientHandler` creates a new `WebSocketFrame`. |
| 67 | + * This frame is put into a queue for the [`WebSocketDataWriter`](javaWebsocketChess/websocketCore/src/main/java/com/jSocket/websocket/server/WebSocketDataWriter.java). |
| 68 | + * The `WebSocketDataWriter` (also in its own thread) picks up frames from this queue, converts them back into bytes using [`WebSocketFrame.toBytes()`](javaWebsocketChess/websocketCore/src/main/java/com/jSocket/websocket/server/WebSocketFrame.java), and sends them to the client. |
| 69 | + |
| 70 | + ```bash |
| 71 | + # ClientHandler (for 192.168.1.101): |
| 72 | + # Application wants to send "Hello Client". |
| 73 | + # Creating new WebSocketFrame: Type=TEXT, Content="Hello Client". |
| 74 | + # Adding Frame("Hello Client") to DataWriter's outgoing queue. |
| 75 | + |
| 76 | + # WebSocketDataWriter (for 192.168.1.101): Checking my queue... |
| 77 | + # WebSocketDataWriter: Found Frame("Hello Client")! |
| 78 | + # WebSocketDataWriter: Using WebSocketFrame to convert to bytes... |
| 79 | + # Raw Bytes: [0x81, 0x0c, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74] |
| 80 | + # WebSocketDataWriter: Sending bytes to client 192.168.1.101. |
| 81 | + ``` |
| 82 | + |
| 83 | +6. **Connection Close** |
| 84 | + * Either the client or the server can initiate a close. |
| 85 | + * A special CLOSE frame is exchanged. |
| 86 | + * The `ClientHandler` manages this, stops its `DataReader` and `DataWriter`, closes the socket, and notifies your application logic via `yourAppLogic.onClose()`. |
| 87 | + |
| 88 | +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. |
0 commit comments