Java websocket ping pong

Руководство по API Java для WebSocket

WebSocket предоставляет альтернативу ограничению эффективной связи между сервером и веб-браузером, обеспечивая двунаправленную полнодуплексную связь клиент-сервер в реальном времени. Сервер может отправлять данные клиенту в любое время. Поскольку он работает через TCP, он также обеспечивает низкоуровневую связь с малой задержкой и снижает накладные расходы на каждое сообщение.

В этой статье мы рассмотрим Java API для WebSockets, создав приложение, похожее на чат.

2. JSR 356

JSR 356 или Java API для WebSocket определяет API, который разработчики Java могут использовать для интеграции WebSockets со своими приложениями — как на стороне сервера, так и на стороне клиента Java.

Этот Java API предоставляет компоненты как на стороне сервера, так и на стороне клиента:

  • Server: все в пакетеjavax.websocket.server.
  • Client: содержимое пакетаjavax.websocket, который состоит из клиентских API, а также общих библиотек для сервера и клиента.

3. Создание чата с использованием WebSockets

Мы создадим очень простое приложение, похожее на чат. Любой пользователь сможет открыть чат из любого браузера, ввести свое имя, войти в чат и начать общаться со всеми, кто подключен к чату.

Начнем с добавления последней зависимости в файлpom.xml:

 javax.websocket javax.websocket-api 1.1 

Последнюю версию можно найтиhere.

Чтобы преобразовать JavaObjects в их представления JSON и наоборот, мы будем использовать Gson:

 com.google.code.gson gson 2.8.0 

Последняя версия доступна в репозиторииMaven Central.

3.1. Конфигурация конечной точки

Существует два способа настройки конечных точек: на основеannotation- и на основе расширений. Вы можете либо расширить классjavax.websocket.Endpoint, либо использовать специальные аннотации на уровне метода. Поскольку модель аннотации приводит к более чистому коду по сравнению с программной моделью, аннотация стала обычным выбором кодирования. В этом случае события жизненного цикла конечной точки WebSocket обрабатываются следующими аннотациями:

  • @ServerEndpoint: Если оформлен@ServerEndpoint,, контейнер обеспечивает доступность класса в качестве сервераWebSocket, прослушивающего определенное пространство URI
  • @ClientEndpoint: класс, украшенный этой аннотацией, рассматривается как клиентWebSocket
  • @OnOpen: метод Java с@OnOpen вызывается контейнером, когда инициируется новое соединениеWebSocket
  • @OnMessage: метод Java, помеченный@OnMessage,, получает информацию из контейнераWebSocket, когда сообщение отправляется в конечную точку
  • @OnError: метод с@OnError вызывается, когда есть проблема со связью
  • @OnClose: используется для украшения метода Java, который вызывается контейнером при закрытии соединенияWebSocket

3.2. Написание конечной точки сервера

Мы объявляем конечную точку сервера Java-классаWebSocket, аннотируя ее с помощью@ServerEndpoint. Мы также указываем URI, где развернута конечная точка. URI определяется относительно корня контейнера сервера и должен начинаться с косой черты:

@ServerEndpoint(value = "/chat/") public class ChatEndpoint < @OnOpen public void onOpen(Session session) throws IOException < // Get session and WebSocket connection >@OnMessage public void onMessage(Session session, Message message) throws IOException < // Handle new messages >@OnClose public void onClose(Session session) throws IOException < // WebSocket connection closes >@OnError public void onError(Session session, Throwable throwable) < // Do error handling here >>

Приведенный выше код представляет собой скелет конечной точки сервера для нашего приложения, похожего на чат. Как видите, у нас есть 4 аннотации, сопоставленные с их соответствующими методами. Ниже вы можете увидеть реализацию таких методов:

@ServerEndpoint(value="/chat/") public class ChatEndpoint < private Session session; private static SetchatEndpoints = new CopyOnWriteArraySet<>(); private static HashMap users = new HashMap<>(); @OnOpen public void onOpen( Session session, @PathParam("username") String username) throws IOException < this.session = session; chatEndpoints.add(this); users.put(session.getId(), username); Message message = new Message(); message.setFrom(username); message.setContent("Connected!"); broadcast(message); >@OnMessage public void onMessage(Session session, Message message) throws IOException < message.setFrom(users.get(session.getId())); broadcast(message); >@OnClose public void onClose(Session session) throws IOException < chatEndpoints.remove(this); Message message = new Message(); message.setFrom(users.get(session.getId())); message.setContent("Disconnected!"); broadcast(message); >@OnError public void onError(Session session, Throwable throwable) < // Do error handling here >private static void broadcast(Message message) throws IOException, EncodeException < chatEndpoints.forEach(endpoint -> < synchronized (endpoint) < try < endpoint.session.getBasicRemote(). sendObject(message); >catch (IOException | EncodeException e) < e.printStackTrace(); >> >); > >

Когда новый пользователь входит в систему (@OnOpen) немедленно отображается в структуру данных активных пользователей. Затем создается сообщение, которое отправляется всем конечным точкам с помощью методаbroadcast.

Этот метод также используется всякий раз, когда любое из подключенных пользователей отправляет новое сообщение (@OnMessage) — это основная цель чата.

Читайте также:  Mailto links in html

Если в какой-то момент происходит ошибка, метод с аннотацией@OnError обрабатывает ее. Вы можете использовать этот метод для регистрации информации об ошибке и очистки конечных точек.

Наконец, когда пользователь больше не подключен к чату, метод@OnClose очищает конечную точку и транслирует всем пользователям, что пользователь был отключен.

4. Типы сообщений

Спецификация WebSocket поддерживает два формата данных в сети — текстовый и двоичный. API поддерживает оба этих формата, добавляет возможности для работы с объектами Java и сообщениями о проверке работоспособности (пинг-понг), как определено в спецификации:

  • Text: любые текстовые данные (java.lang.String, примитивы или их эквивалентные классы-оболочки)
  • Binary: двоичные данные (например, аудио, изображение и т. д.), представленныеjava.nio.ByteBuffer илиbyte[] (массив байтов)
  • Java objects: API позволяет работать с собственными представлениями (объектами Java) в вашем коде и использовать настраиваемые преобразователи (кодировщики / декодеры) для преобразования их в совместимые интерактивные форматы (текстовые, двоичные), разрешенные WebSocket. протокол
  • Ping-Pong:javax.websocket.PongMessage — это подтверждение, отправленное одноранговым узлом WebSocket в ответ на запрос проверки работоспособности (ping)

Для нашего приложения мы будем использоватьJava Objects.. Мы создадим классы для кодирования и декодирования сообщений.

4.1. кодировщик

Кодировщик берет объект Java и создает типичное представление, подходящее для передачи в виде сообщения, такое как JSON, XML или двоичное представление. Кодеры можно использовать, реализовав интерфейсыEncoder.Text илиEncoder.Binary .

В приведенном ниже коде мы определяем классMessage для кодирования, а в методеencode мы используем Gson для кодирования объекта Java в JSON:

public class MessageEncoder implements Encoder.Text  < private static Gson gson = new Gson(); @Override public String encode(Message message) throws EncodeException < return gson.toJson(message); >@Override public void init(EndpointConfig endpointConfig) < // Custom initialization logic >@Override public void destroy() < // Close resources >>

4.2. дешифратор

Декодер является противоположностью кодера и используется для преобразования данных обратно в объект Java. Декодеры могут быть реализованы с использованием интерфейсовDecoder.Text илиDecoder.Binary .

Читайте также:  Python packages for excel

Как мы видели с кодировщиком, методdecode — это то место, где мы берем JSON, полученный в сообщении, отправленном в конечную точку, и используем Gson для преобразования его в класс Java с именемMessage:.

public class MessageDecoder implements Decoder.Text  < private static Gson gson = new Gson(); @Override public Message decode(String s) throws DecodeException < return gson.fromJson(s, Message.class); >@Override public boolean willDecode(String s) < return (s != null); >@Override public void init(EndpointConfig endpointConfig) < // Custom initialization logic >@Override public void destroy() < // Close resources >>

4.3. Настройка кодировщика и декодера в конечной точке сервера

Давайте соберем все вместе, добавив классы, созданные для кодирования и декодирования данных, в аннотацию уровня класса@ServerEndpoint:

@ServerEndpoint( value="/chat/", decoders = MessageDecoder.class, encoders = MessageEncoder.class )

Каждый раз, когда сообщения отправляются в конечную точку, они автоматически конвертируются в объекты JSON или Java.

5. Заключение

В этой статье мы рассмотрели, что такое Java API для WebSockets и как оно может помочь нам в создании приложений, таких как чат в реальном времени.

Мы видели две модели программирования для создания конечной точки: аннотации и программирование. Мы определили конечную точку, используя модель аннотации для нашего приложения вместе с методами жизненного цикла.

Кроме того, чтобы иметь возможность обмениваться данными между сервером и клиентом, мы увидели, что нам нужны кодеры и декодеры для преобразования объектов Java в JSON и наоборот.

JSR 356 API — это очень простая и основанная на аннотациях модель программирования, которая упрощает создание приложений WebSocket.

Источник

Interface WebSocket

WebSocket instances are created through WebSocket.Builder .

WebSocket has an input and an output side. These sides are independent from each other. A side can either be open or closed. Once closed, the side remains closed. WebSocket messages are sent through a WebSocket and received through a WebSocket.Listener associated with it. Messages can be sent until the WebSocket’s output is closed, and received until the WebSocket’s input is closed.

Читайте также:  Web page html script

A send method is any of the sendText , sendBinary , sendPing , sendPong and sendClose methods of WebSocket . A send method initiates a send operation and returns a CompletableFuture which completes once the operation has completed. If the CompletableFuture completes normally the operation is considered succeeded. If the CompletableFuture completes exceptionally, the operation is considered failed. An operation that has been initiated but not yet completed is considered pending.

A receive method is any of the onText , onBinary , onPing , onPong and onClose methods of Listener . WebSocket initiates a receive operation by invoking a receive method on the listener. The listener then must return a CompletionStage which completes once the operation has completed.

To control receiving of messages, a WebSocket maintains an internal counter. This counter’s value is a number of times the WebSocket has yet to invoke a receive method. While this counter is zero the WebSocket does not invoke receive methods. The counter is incremented by n when request(n) is called. The counter is decremented by one when the WebSocket invokes a receive method. onOpen and onError are not receive methods. WebSocket invokes onOpen prior to any other methods on the listener. WebSocket invokes onOpen at most once. WebSocket may invoke onError at any given time. If the WebSocket invokes onError or onClose , then no further listener’s methods will be invoked, no matter the value of the counter. For a newly built WebSocket the counter is zero.

Unless otherwise stated, null arguments will cause methods of WebSocket to throw NullPointerException , similarly, WebSocket will not pass null arguments to methods of Listener . The state of a WebSocket is not changed by the invocations that throw or return a CompletableFuture that completes with one of the NullPointerException , IllegalArgumentException , IllegalStateException exceptions.

WebSocket handles received Ping and Close messages automatically (as per the WebSocket Protocol) by replying with Pong and Close messages. If the listener receives Ping or Close messages, no mandatory actions from the listener are required.

Источник

Оцените статью