WebSocket библиотека Java: Полное руководство по разработке приложений реального времени
WebSocket — это протокол, обеспечивающий двустороннюю связь между клиентом и сервером через одно долгоживущее TCP-соединение. В Java существует несколько зрелых библиотек, которые упрощают работу с WebSocket. В этой статье мы рассмотрим основные библиотеки, их возможности и предоставим практические примеры кода.
1. Java WebSocket API (JSR 356)
Стандартный API для работы с WebSocket в Java EE / Jakarta EE. Входит в состав серверов приложений (WildFly, TomEE, GlassFish) и позволяет создавать как серверные, так и клиентские конечные точки.
Основные возможности:
- Аннотации
@ServerEndpointи@ClientEndpoint - Поддержка текстовых и бинарных сообщений
- Управление сессиями и жизненным циклом
- Интеграция с CDI (Contexts and Dependency Injection)
Пример серверного эндпоинта:
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
@ServerEndpoint("/chat")
public class ChatEndpoint {
@OnOpen
public void onOpen(Session session) {
System.out.println("Новое соединение: " + session.getId());
session.getUserProperties().put("username", "Гость");
}
@OnMessage
public String onMessage(String message, Session session) {
String username = (String) session.getUserProperties().get("username");
return username + ": " + message;
}
@OnClose
public void onClose(Session session, CloseReason reason) {
System.out.println("Соединение закрыто: " + reason.getReasonPhrase());
}
@OnError
public void onError(Session session, Throwable error) {
error.printStackTrace();
}
}
Пример клиента:
import javax.websocket.*;
import java.net.URI;
@ClientEndpoint
public class ChatClient {
private Session session;
@OnOpen
public void onOpen(Session session) {
System.out.println("Подключено к серверу");
this.session = session;
}
@OnMessage
public void onMessage(String message) {
System.out.println("Получено: " + message);
}
public void sendMessage(String message) throws IOException {
if (session != null && session.isOpen()) {
session.getBasicRemote().sendText(message);
}
}
public static void main(String[] args) throws Exception {
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
ChatClient client = new ChatClient();
container.connectToServer(client, new URI("ws://localhost:8080/chat"));
client.sendMessage("Привет, мир!");
Thread.sleep(1000);
}
}
2. Tyrus (Reference Implementation)
Tyrus — эталонная реализация JSR 356 от Oracle. Может использоваться как standalone-библиотека без полноценного сервера приложений. Идеально подходит для микросервисов и легковесных приложений.
Особенности:
- Работает с Grizzly, Jetty или JDK HTTP сервером
- Поддержка SockJS для совместимости с браузерами без WebSocket
- Настраиваемые фильтры и перехватчики
- Гибкая конфигурация через XML или Java Config
Пример standalone сервера на Tyrus + Grizzly:
import org.glassfish.tyrus.server.Server;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
@ServerEndpoint("/echo")
public class EchoEndpoint {
@OnMessage
public String echo(String message) {
return "Эхо: " + message;
}
public static void main(String[] args) {
Server server = new Server("localhost", 8025, "/ws", EchoEndpoint.class);
try {
server.start();
System.out.println("Сервер запущен на ws://localhost:8025/ws/echo");
System.in.read(); // ждём нажатия Enter
} catch (Exception e) {
e.printStackTrace();
} finally {
server.stop();
}
}
}
3. Netty WebSocket
Netty — высокопроизводительный асинхронный фреймворк для сетевых приложений. Его модуль WebSocket позволяет обрабатывать тысячи одновременных соединений с минимальными накладными расходами.
Преимущества:
- Неблокирующий ввод-вывод (NIO)
- Поддержка WebSocket расширений (permessage-deflate)
- Гибкая архитектура pipeline для кастомной обработки
- Идеально для высоконагруженных систем (чат, игры, биржевые данные)
Пример серверного обработчика Netty:
import io.netty.channel.*;
import io.netty.handler.codec.http.websocketx.*;
import io.netty.handler.codec.http.*;
import io.netty.buffer.Unpooled;
public class WebSocketServerHandler extends SimpleChannelInboundHandler<Object>