Practical Java Applications

Fundamentals of WebSocket and a Dynamic Multi-Chat Application with Java

ierdoganierdoganNovember 10, 2025
Fundamentals of WebSocket and a Dynamic Multi-Chat Application with Java

WebSocket is a flexible and highly efficient communication protocol that provides bidirectional (full-duplex) communication channels over the TCP protocol. It is designed for use in web servers and browsers. It was standardized as RFC 6455 in 2011. WebSocket enables a persistent connection between the client and server. Thanks to the bidirectional communication model, the client and server can send data to each other at any time and to any extent. This feature distinguishes WebSocket from the classic HTTP protocol.

What are the Advantages of Using WebSocket?

The main advantages of the WebSocket protocol can be summarized as follows:

Real-Time Communication
WebSocket enables real-time communication between the server and client. This allows for the development of faster and more responsive applications.

Low Latency
It carries much less header information compared to HTTP, which significantly reduces latency. Data packets are sent and received much faster. Therefore, it is ideal for applications that require fast response times (chat, live scores, stock tracking, etc.).

Lower Bandwidth Consumption
Because it establishes a persistent connection, unnecessary data exchange is eliminated. Once the connection is established, it continues until it is closed. While a new connection is established for each request in HTTP, resource and bandwidth savings are achieved in WebSocket thanks to the persistent connection.

Bidirectional Communication
The server can send data to the client at any time, independently of the client (server-push). This feature is completely different from the classic HTTP structure, which operates only on the request → response logic, and forms the basis of real-time applications.

Flexible and Efficient Protocol
WebSocket is a flexible protocol with a very wide range of uses. It can be easily used in any environment, from web applications to IoT devices. Since it has a much smaller header size compared to HTTP, it allows for the creation of smaller packets and consumes fewer resources, resulting in high efficiency.

WebSocket is today’s most important protocol for developing real-time, low-latency, and bandwidth-friendly applications.

1*de9VVpUpwXsnEilfuVWFww.png

An overview of Frames, the cornerstone of the WebSocket protocol;

Frames are the smallest data unit that enable low-latency, bidirectional (full-duplex) communication between the client and server. Each WebSocket message consists of one or more frames. Large messages are divided into fragments (fragmentation) and reassembled on the receiving side.

The components of a WebSocket frame are as follows:

1-Basic Header (2 bytes)

FIN bit (1 bit): Indicates whether this is the last frame of the message. 1 = last part of this message, 0 = more to come.

RSV1, RSV2, RSV3 (each 1 bit): Used only when extensions are defined (e.g., per-message compression extension).

Opcode (4 bits): Defines the type of frame.

0x0 = continuation frame
0x1 = text frame
0x2 = binary frame
0x8 = connection close
0x9 = ping
0xA = pong
others are control frames or bits reserved for future use.

Mask bit (1 bit): Pins used to indicate whether the payload is masked.

In all frames sent from client → server, this bit must be 1.

In those sent from server → client, it is 0.

Payload length (7 bits): length field.

0–125 → actual length
126 → the next 2 bytes (16-bit unsigned) give the actual length
127 → the next 8 bytes (64-bit unsigned) give the actual length

2-Extended Payload

Length (optional): If the payload length field is 126 → 2 more bytes are read
if 127 → 8 more bytes are read

3-Masking Key (4 bytes)

Present if the mask bit is 1. All frames from the client are masked with this 4-byte random key.

The algorithmic logic used during masking: actual_data[i] = masked_data[i] XOR mask[i mod 4].

The server uses this key to unmask the data.

4-Payload Data (Payload) The actual message content is here. In text frames (opcode=1), the payload must be valid and UTF-8. In binary frames (opcode=2), any binary data is allowed.

For control frames (close, ping, pong), the payload length is a maximum of 125 bytes.

Establishing a Persistent Connection Significantly Reduces Data Transfer Latency

One of the greatest strengths of WebSocket is that it keeps the connection open (persistent) once it is established. In traditional HTTP, the following steps are repeated for each request (message, notification, update):

  • A new TCP connection is established (3-way handshake)

  • HTTP headers are sent/received (~200–800 bytes)

  • TLS/SSL handshake (if HTTPS)

  • Data is transferred

  • The connection is closed or reused (but there is still header overhead)

This cycle creates latency at the millisecond or even second level, especially in applications that require frequent data exchange.

In WebSocket:

  • The connection is established only once (starts with HTTP Upgrade)

  • After the initial handshake, the header size is only 2–14 bytes

  • No additional handshake is required as long as the TCP connection remains open

  • Data is sent/received directly

1*KOaIOc_1Bj9-Oq4z9bwEqQ.png

Thanks to WebSocket’s low latency and real-time communication capability, it is now preferred in almost every sector:

Use Case

Examples

Messaging Applications

The live chat feature of systems such as WhatsApp, Slack, Discord, Telegram works with WebSocket.

Real-Time Games

Agar.io, online chess, multiplayer battle-royale, or browser-based MMO games.

Live Updates

Stock tracking screens, cryptocurrency prices, live sports scores, news feeds.

IoT (Internet of Things)

Smart home devices, real-time monitoring of sensor data, remote control panels.

Finance Applications

Algo-trading platforms, real-time portfolio tracking, order transmission, financial dashboards.

Security and Monitoring Systems

IP camera live streams, instant notifications of burglar alarms, access control systems.

Blockchain and Crypto

Wallet balance updates, new block/mempool tracking, price and transaction flow on DEXs.

Collaboration Tools

Applications where multiple people edit simultaneously, such as Google Docs, Figma, Miro, Notion.

Live Broadcast Control

Twitch chhorse, YouTube live comments, OBS control signals.

Education and Online Exam

Live attendance, instant Q&A, interactive whiteboard systems.

Any application in which users need to send/receive data to/from each other or the system instantly and continuously is a natural use case for WebSocket.

Basic Socket Programming with Java: Chat Application

In this section, a simple multi-user chat application was created using java (java.net and java.io) without using an external library. This application contains basic information for those who want to learn and practice the fundamental concepts of socket programming.

We can briefly summarize the features of the application as follows,

  • Real-time messaging

  • Multi-user support

  • User login/logout notifications

  • Low latency, lightweight and understandable code structure

The application is based on the classic client-server architecture and consists of two main components:

  • ChatSocketServer → Represents the server side.

  • ChatSocketClient → Represents the client side.

ChatSocketServer;

The basic workflow in ChatSocketServer is as follows;

1. The Server is Started and the Port is Set to Listen

(ServerSocket serverSocket = new ServerSocket(12345))

2. A Separate Thread is Created for Each Client

(new ClientHandler(clientSocket).start();)

3. Username is Received and Registered in the System

(Enter your username:)

4. Automatic Notifications for New Joins and Exits

broadcastMessage("Server", username + " has joined the chat.");

broadcastMessage("Server", username + " has left the chat.");

5. Messages are Instantly Broadcast to All Clients

while ((message = in.readLine()) != null) {
broadcastMessage(username, message);
}

1-Code block belonging to ChatSocketServer;

package com.testsocket;

import java.io.*;
import java.net.*;
import java.util.*;

public class ChatSocketServer {

private static final int PORT = 12345;
private static Map<String, PrintWriter> clientWriters = new HashMap<>();

public static void main(String[] args) {
System.out.println("Server is starting...");
try (ServerSocket serverSocket = new ServerSocket(PORT)) {
while (true) {
Socket clientSocket = serverSocket.accept();
new ClientHandler(clientSocket).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}

private static class ClientHandler extends Thread {
private Socket socket;
private String username;
private BufferedReader in;
private PrintWriter out;

public ClientHandler(Socket socket) {
this.socket = socket;
}

public void run() {
try {
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);

out.println("Enter your username:");
username = in.readLine();
synchronized (clientWriters) {
clientWriters.put(username, out);
}
System.out.println(username + " has connected.");

// Notify other clients that a user has joined
broadcastMessage("Server", username + " has joined the chat.");

// Listen for incoming messages and forward them
String message;
while ((message = in.readLine()) != null) {
System.out.println("[" + username + "]: " + message);
broadcastMessage(username, message);
}
} catch (IOException e) {
e.printStackTrace();
} finally {

if (username != null) {
synchronized (clientWriters) {
clientWriters.remove(username);
}
broadcastMessage("Server", username + " has left the chat.");
}
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

// Send the message to all clients
private void broadcastMessage(String sender, String message) {
synchronized (clientWriters) {
for (PrintWriter writer : clientWriters.values()) {
writer.println("[" + sender + "]: " + message);
}
}
}
}
}


ChatSocketClient;

The basic workflow in ChatSocketClient is as follows;

1-Connection to the Server is Established

2-Input/Output Streams are Prepared

3-Username is Requested by the Server and Sent

4-A Separate Thread is Started to Display Incoming Messages in Real Time

5-What the User Types is Instantly Sent to the Server (Main Thread)

6-If the Connection is Lost or the Server Shuts Down, the Program Terminates Cleanly

2-Code block belonging to ChatSocketClient;

package com.testsocket;

import java.io.*;
import java.net.*;
import java.util.Scanner;

public class ChatSocketClient {

private static final String SERVER_ADDRESS = "127.0.0.1";
private static final int SERVER_PORT = 12345;

public static void main(String[] args) {
try (Socket socket = new Socket(SERVER_ADDRESS, SERVER_PORT)) {
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);

Scanner scanner = new Scanner(System.in);

// A separate thread to listen for messages from the server
new Thread(() -> {
try {
String message;
while ((message = in.readLine()) != null) {
System.out.println(message);
}
} catch (IOException e) {
e.printStackTrace();
}
}).start();

// Read user messages and send them to the server
while (true) {
String message = scanner.nextLine();
out.println(message);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

The application flow is as follows;

1. Server Connection

The client connects to the server via the specified IP address and port, establishing the communication channel.

1*LSLmQMD8XeG8Ow1qFj4Fxg.png

2.Client Connection:

ChatSocketClient is run, connects to the server, and waits for the user to enter a username.

1*EP0vJtFHH2GlDNgrCBwhMw.png

3.Messaging:
As users type messages, these messages are transmitted via the server

…is transmitted to all other connected clients.

1*LTYsP2u1QUMlV089Lss7gg.png

4.Connection Management:
When a client disconnects, the server notifies other clients and releases the resources associated with the disconnected client.

Thank you for reading this article about the WebSocket protocol and basic socket programming! Please feel free to share your thoughts and experiences regarding WebSocket or socket programming in the comments. I am especially interested in hearing about the projects you have developed with this technology or the challenges you have encountered.

If you found this article useful, I kindly ask you to share it to help it reach more people.

(Note: The same article was also published on Medium in 2025.)

Did you like this article?

Share with your friends

Java WebSocket Server and Client: Real-Time Communication P… | Celsus Hub