Search
Close this search box.
websockets

Introduction to WebSockets in Java: A Beginner’s Guide

Introduction

WebSockets establish a persistent, long-lasting connection that enables two-way communication between a client and a server. Unlike HTTP, which is a request-response protocol, WebSockets allow for bidirectional data exchange, making them ideal for real-time applications such as chat apps, live notifications, and online gaming. In this article, we will explore how to use WebSockets in Java, guiding you step-by-step through the process with examples and code snippets.

What Are WebSockets?

WebSockets are a protocol that enables a continuous connection between a client and a server for ongoing communication. Once established, this connection allows both parties to send data to each other at any time, without needing to re-establish the connection.

websockets

Key Features of WebSockets:

  • Bidirectional communication: The client and server can exchange messages at the same time.
  • Low latency: Due to the persistent connection, WebSockets reduce the latency of message transmission compared to traditional HTTP requests.
  • Efficiency: WebSockets reduce the overhead associated with opening and closing multiple connections.

Setting Up a Java WebSocket Server

To implement WebSockets in Java, we’ll use the `javax.websocket` package, which is part of the Java API for WebSocket (JSR 356). Let’s start by setting up a basic WebSocket server.

Step 1: Create a Maven Project

First, create a new Maven project. Maven is a tool designed for automating the build process, mainly utilized in Java projects. To Know more about Maven, Please read my Maven article

mvn archetype:generate -DgroupId=com.example.websocket -DartifactId=demo-websocket-DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

Step 2: Add Dependencies

Open the `pom.xml` file and add the necessary dependencies. We’ll use `javax.websocket` for WebSocket support.

<dependencies>
    <dependency>
        <groupId>javax.websocket</groupId>
        <artifactId>javax.websocket-api</artifactId>
        <version>1.1</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.tyrus</groupId>
        <artifactId>tyrus-server</artifactId>
        <version>1.15</version>
    </dependency>
</dependencies>

Step 3: Create a WebSocket Endpoint

Next, create a WebSocket server endpoint. An endpoint is a class that handles WebSocket communication.

package com.aneesh.websocket;

import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;

@ServerEndpoint("/chat")
public class ChatEndpoint {

    @OnOpen
    public void onOpen(Session session) throws IOException {
        System.out.println("Connected: " + session.getId());
        session.getBasicRemote().sendText("Welcome to the chat!");
    }

    @OnMessage
    public void onMessage(String message, Session session) throws IOException {
        System.out.println("Received: " + message);
        session.getBasicRemote().sendText("You said: " + message);
    }

    @OnClose
    public void onClose(Session session) throws IOException {
        System.out.println("Disconnected: " + session.getId());
    }
}

Explanation:

  • `@ServerEndpoint(“/chat”)`: This annotation declares the class as a WebSocket endpoint with the path `/chat`.
  • `onOpen(Session session)`: This method is called when a new WebSocket connection is established.
  • `onMessage(String message, Session session)`: This method is invoked when a message is received from the client.
  • `onClose(Session session)`: This method is called when the WebSocket connection is closed.

Step 4: Deploy the WebSocket Server

To deploy the WebSocket server, you can use an embedded server like Jetty or GlassFish. For simplicity, we’ll use Jetty.

Add the Jetty dependency to your `pom.xml`:

<dependency>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-webapp</artifactId>
    <version>9.4.39.v20210325</version>
</dependency>
<dependency>
    <groupId>org.eclipse.jetty.websocket</groupId>
    <artifactId>websocket-server</artifactId>
    <version>9.4.39.v20210325</version>
</dependency>

Next, create a main class to start the Jetty server:

package com.aneesh.websocket;

import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer;

public class WebSocketServer {

    public static void main(String[] args) throws Exception {
        Server server = new Server(8080);
        ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
        context.setContextPath("/");
        server.setHandler(context);

        // Initialize javax.websocket layer
        WebSocketServerContainerInitializer.configureContext(context);
        server.start();
        server.join();
    }
}

Creating a WebSocket Client in Java

Now that the server is running, let’s create a simple WebSocket client in Java to communicate with it.

Step 1: Create the WebSocket Client Class

package com.aneesh.websocket;

import javax.websocket.ContainerProvider;
import javax.websocket.Session;
import javax.websocket.WebSocketContainer;
import java.net.URI;

public class WebSocketClient {

    public static void main(String[] args) {
        try {
            WebSocketContainer container = ContainerProvider.getWebSocketContainer();
            URI uri = URI.create("ws://localhost:8080/chat");
            Session session = container.connectToServer(ClientEndpoint.class, uri);
            session.getBasicRemote().sendText("Hello, Server!");

            // Keep the connection open for a while to receive messages
            Thread.sleep(10000);
            session.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Step 2: Implement the Client Endpoint

Create a new class `ClientEndpoint` that handles messages from the server:

package com.aneesh.websocket;

import javax.websocket.OnMessage;
import javax.websocket.ClientEndpoint;

@ClientEndpoint
public class ClientEndpoint {

    @OnMessage
    public void onMessage(String message) {
        System.out.println("Received from server: " + message);
    }
}

Running the WebSocket Application

To test the application, follow these steps:

  • Run the WebSocket Server: Start the `WebSocketServer` class. The server will run on `http://localhost:8080`.
  • Run the WebSocket Client: Run the `WebSocketClient` class. The client will connect to the server and send a message.

The output should display messages exchanged between the client and server.

Conclusion

WebSockets in Java provide an efficient way to implement real-time communication in web applications. In this tutorial, we set up a WebSocket server and client using Java’s `javax.websocket` API, creating a simple chat-like interaction. With this foundation, you can explore more advanced WebSocket features such as broadcasting messages to multiple clients, handling binary data, and implementing security mechanisms. Whether you’re building a chat app, a live notification system, or an online game, WebSockets offer a powerful tool for real-time, bidirectional communication.

FAQs

1. What is the main difference between WebSockets and HTTP in Java?

Answer: The primary difference between WebSockets and HTTP is the communication model. HTTP follows a request-response model, where the client sends a request, and the server responds, after which the connection is typically closed. In contrast, WebSockets provide a full-duplex communication channel over a single, long-lived connection, allowing both the client and server to send and receive messages independently and continuously without re-establishing the connection.

2. How do I handle multiple clients connecting to a WebSocket server in Java?

Answer: To handle multiple clients in a WebSocket server, you can maintain a collection (e.g., a `Set` or `Map`) of active sessions within your WebSocket endpoint class. When a client connects, their session is added to the collection, and when they disconnect, it is removed. This collection allows you to broadcast messages to all connected clients by iterating through the sessions and sending messages accordingly.

private static Set<Session> clients = Collections.synchronizedSet(new HashSet<>());

@OnOpen
public void onOpen(Session session) {
    clients.add(session);
}

@OnClose
public void onClose(Session session) {
    clients.remove(session);
}

public void broadcast(String message) {
    for (Session client : clients) {
        client.getAsyncRemote().sendText(message);
    }
}

3. Can I use WebSockets with Spring Boot in Java?

Answer: Yes, you can use WebSockets with Spring Boot. Spring Boot provides excellent support for WebSocket development through the `spring-websocket` module. You can create WebSocket endpoints using Spring’s `@ServerEndpoint` annotation or by defining a `@Controller` class with `@MessageMapping` methods. Spring’s WebSocket support is integrated with its messaging infrastructure, allowing easy implementation of complex communication patterns like broadcasting and messaging to specific users.

4. How do I secure a WebSocket connection in Java?

Answer: To secure a WebSocket connection in Java, you can use the Secure WebSocket (WSS) protocol, which is the WebSocket protocol over TLS/SSL. You need to configure your server to use HTTPS and ensure that the WebSocket connection is established over WSS instead of plain WS. Additionally, you can implement authentication and authorization mechanisms to ensure that only authorized clients can establish WebSocket connections.

Example of creating a WebSocket over WSS:

URI uri = URI.create("wss://your-secure-server.com/chat");
Session session = container.connectToServer(ClientEndpoint.class, uri);

5. What are some common use cases for WebSockets in Java applications?

Answer: WebSockets are ideal for any Java application that requires real-time, bidirectional communication. Common use cases include:

  • Live notifications: For real-time updates, such as stock prices, news, or social media notifications.
  • Online gaming: Where low-latency communication is critical for a seamless gaming experience.
  • Collaborative tools: Such as shared documents or whiteboards where multiple users interact in real time.
  • IoT applications: Where devices communicate with a central server in real time to send and receive updates.
  • Chat applications: Where messages need to be exchanged between users instantly.

Share the post

Leave a Reply

Your email address will not be published. Required fields are marked *