WebSocket библиотека Java: Tyrus — эталонная реализация JSR 356
В современной веб-разработке потребность в двусторонней связи в реальном времени стала стандартом. Чат-приложения, онлайн-игры, торговые терминалы и системы уведомлений — все они требуют, чтобы сервер мог инициировать отправку данных клиенту без постоянных HTTP-запросов. Для Java экосистемы стандартом де-факто является спецификация JSR 356 (Java API for WebSocket), а её эталонной реализацией — библиотека Tyrus.
На странице pythonlib.ru мы часто рассматриваем инструменты для real-time коммуникаций. Сегодня подробно разберём Tyrus — мощную и гибкую библиотеку для работы с WebSocket в Java, которая позволяет легко встраивать двустнаправленный обмен данными в ваши проекты.
Что такое Tyrus и зачем он нужен?
Tyrus — это открытая реализация (reference implementation) спецификации JSR 356, разработанная под эгидой Eclipse Foundation. Она предоставляет полный набор API для создания как серверных, так и клиентских WebSocket-приложений на Java. Основные преимущества Tyrus:
- Полное соответствие стандарту JSR 356 — код, написанный с использованием Tyrus, будет легко портироваться на другие реализации (например, Apache Tomcat, Jetty).
- Поддержка аннотаций — минималистичный подход: достаточно добавить аннотации
@ServerEndpointили@ClientEndpointк POJO. - Гибкость — работает как в контейнерах сервлетов (Tomcat, GlassFish), так и в standalone-режиме (встроенный сервер Grizzly).
- Безопасность — поддержка WSS (WebSocket Secure) через стандартные Java SSL-сокеты.
Установка и подключение Tyrus
Для работы с Tyrus вам потребуется добавить несколько зависимостей в pom.xml (Maven). Базовая конфигурация включает ядро библиотеки и транспортный слой (Grizzly для standalone-режима):
<!-- Основная зависимость Tyrus -->
<dependency>
<groupId>org.glassfish.tyrus</groupId>
<artifactId>tyrus-server</artifactId>
<version>1.19</version>
</dependency>
<!-- Встроенный сервер Grizzly для standalone-режима -->
<dependency>
<groupId>org.glassfish.tyrus</groupId>
<artifactId>tyrus-container-grizzly-server</artifactId>
<version>1.19</version>
</dependency>
<!-- Клиентская часть (если нужно подключаться к другим серверам) -->
<dependency>
<groupId>org.glassfish.tyrus</groupId>
<artifactId>tyrus-client</artifactId>
<version>1.19</version>
</dependency>
Для Gradle (build.gradle):
implementation 'org.glassfish.tyrus:tyrus-server:1.19'
implementation 'org.glassfish.tyrus:tyrus-container-grizzly-server:1.19'
implementation 'org.glassfish.tyrus:tyrus-client:1.19'
Создание WebSocket сервера на Tyrus
Серверная часть — это обычный Java-класс с аннотацией @ServerEndpoint. Tyrus автоматически управляет жизненным циклом соединения.
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
@ServerEndpoint("/chat")
public class ChatEndpoint {
// Храним все активные сессии
private static final Set<Session> sessions = new CopyOnWriteArraySet<>();
@OnOpen
public void onOpen(Session session) {
sessions.add(session);
System.out.println("Новое подключение: " + session.getId());
broadcast("Пользователь " + session.getId() + " присоединился к чату.");
}
@OnMessage
public void onMessage(String message, Session session) {
System.out.println("Сообщение от " + session.getId() + ": " + message);
broadcast("[" + session.getId() + "]: " + message);
}
@OnClose
public void onClose(Session session) {
sessions.remove(session);
System.out.println("Отключение: " + session.getId());
broadcast("Пользователь " + session.getId() + " покинул чат.");
}
@OnError
public void onError(Session session, Throwable error) {
System.err.println("Ошибка на сессии " + session.getId() + ": " + error.getMessage());
}
private void broadcast(String message) {
for (Session session : sessions) {
if (session.isOpen()) {
try {
session.getBasicRemote().sendText(message);
} catch (IOException e) {
System.err.println("О