The Java API for WebSocket (JSR 356) provides a simple and efficient way to implement WebSocket communication in Java-based applications. WebSockets allow for full-duplex communication over a single connection, making them ideal for real-time applications such as chat apps, live data feeds, and multiplayer games. This article explores how to use the JSR 356 API for creating WebSocket servers and clients in Java.
JSR 356, also known as the Java API for WebSocket, is a specification that provides a set of APIs for WebSocket programming in Java. The API simplifies the creation of WebSocket clients and servers and supports bi-directional, low-latency communication over a single, persistent connection.
It is part of Java EE and can be used with any Java web server that supports the WebSocket protocol. The main components in JSR 356 are:
To start working with WebSockets, you need to create a WebSocket server endpoint using the JSR 356 API. This involves using the @ServerEndpoint
annotation to define a WebSocket server.
The following example demonstrates how to create a simple WebSocket server that listens for messages and sends a response back to the client:
import javax.websocket.OnMessage;
import javax.websocket.ServerEndpoint;
@ServerEndpoint("/chat")
public class ChatServer {
@OnMessage
public String onMessage(String message) {
return "Server received: " + message;
}
}
In this example, we use the @ServerEndpoint
annotation to define the endpoint /chat
, and the @OnMessage
annotation to handle incoming messages. The server responds by echoing back the received message.
In addition to creating a WebSocket server, you can also create a WebSocket client using the WebSocketContainer
and Session
classes. The client connects to the WebSocket server and can send and receive messages.
The following example demonstrates how to create a WebSocket client in Java that connects to the WebSocket server we defined earlier:
import javax.websocket.*;
import java.net.URI;
public class ChatClient {
public static void main(String[] args) throws Exception {
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
URI uri = new URI("ws://localhost:8080/chat");
Session session = container.connectToServer(ChatEndpoint.class, uri);
session.getBasicRemote().sendText("Hello, WebSocket Server!");
}
}
@ClientEndpoint
public class ChatEndpoint {
@OnMessage
public void onMessage(String message) {
System.out.println("Received from server: " + message);
}
}
In this client example, the WebSocketContainer
is used to establish a connection to the WebSocket server at ws://localhost:8080/chat
. The ChatEndpoint
class is annotated with @ClientEndpoint
to handle incoming messages from the server.
JSR 356 provides several annotations that you can use to handle WebSocket events such as opening a connection, receiving a message, and closing the connection.
@OnOpen
: Called when a new WebSocket connection is established.@OnMessage
: Called when a message is received from the client or server.@OnClose
: Called when a WebSocket connection is closed.@OnError
: Called when an error occurs during communication.
import javax.websocket.*;
@ServerEndpoint("/chat")
public class ChatServer {
@OnOpen
public void onOpen(Session session) {
System.out.println("New connection: " + session.getId());
}
@OnMessage
public String onMessage(String message) {
return "Server received: " + message;
}
@OnClose
public void onClose(Session session) {
System.out.println("Closed connection: " + session.getId());
}
@OnError
public void onError(Session session, Throwable throwable) {
System.out.println("Error occurred: " + throwable.getMessage());
}
}
In this example, we use the @OnOpen
, @OnClose
, and @OnError
annotations to handle different WebSocket events. The @OnOpen
method is called when a new connection is established, while @OnClose
handles the closing of a connection. The @OnError
method captures any errors that occur during communication.
JSR 356 also provides advanced features to manage sessions, send messages asynchronously, and implement more complex message handling:
Session
object to send messages to specific clients, get information about the connection, or close the session.
import javax.websocket.*;
import java.util.concurrent.Future;
@ServerEndpoint("/chat")
public class ChatServer {
@OnMessage
public void onMessage(Session session, String message) {
// Send message asynchronously
Future future = session.getAsyncRemote().sendText("Echo: " + message);
}
}
In this example, the sendText
method is used asynchronously to send a message back to the client without blocking the server's main thread. The Future
object allows you to track the status of the asynchronous operation.
In this article, we have introduced the Java API for WebSocket (JSR 356) and demonstrated how to use it to create WebSocket server and client applications. WebSockets enable real-time, bi-directional communication over a single connection, which is ideal for applications such as chat apps, notifications, and online gaming. By leveraging JSR 356, developers can easily integrate WebSocket functionality into Java-based applications with minimal effort and code.