Перейти к основному содержимому

Отладка веб-сокетов

· 7 мин. чтения

1. Обзор

WebSocket обеспечивает управляемое событиями, двунаправленное и полнодуплексное соединение между клиентом и сервером. Связь через WebSocket включает рукопожатие, обмен сообщениями (отправку и получение сообщений) и закрытие соединения.

В этом руководстве мы научимся отлаживать WebSockets с помощью браузеров и других популярных инструментов .

2. Создание веб-сокета

Давайте начнем с создания сервера WebSocket, который отправляет обновления биржевого тикера клиентам.

2.1. Зависимости Maven

Во-первых, давайте объявим зависимость Spring WebSocket :

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
<version>2.5.4</version>
</dependency>

2.2. Конфигурация весенней загрузки

Затем давайте определим необходимые @Configuration s для включения поддержки WebSocket:

@Configuration
@EnableWebSocketMessageBroker
public class WebsocketConfiguration implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
config.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/stock-ticks").withSockJS();
}
}

Обратите внимание, что эта конфигурация предоставляет WebSocket на основе брокера сообщений и регистрирует конечные точки STOMP.

Кроме того, давайте создадим контроллер, который отправляет подписчикам фиктивные обновления акций:

private SimpMessagingTemplate simpMessagingTemplate;

public void sendTicks() {
simpMessagingTemplate.convertAndSend("/topic/ticks", getStockTicks());
}

2.3. Клиент — пользовательский интерфейс

Давайте создадим страницу HTML5 , которая отображает обновления с сервера:

<div class="spinner-border text-primary" role="status">
<span class="visually-hidden">Loading ...</span>
</div>

Далее давайте подключимся к серверу WebSocket с помощью SockJS :

function connect() {
let socket = new SockJS('/stock-ticks');
stompClient = Stomp.over(socket);
stompClient.connect({}, function (frame) {
stompClient.subscribe('/topic/ticks', function (ticks) {
...
});
});
}

Здесь мы открываем WebSocket с помощью SockJS, а затем подписываемся на тему /topic/ticks . В конце концов, клиент потребляет и отображает сообщения в пользовательском интерфейсе, когда сервер создает сообщения.

2.4. Демонстрация

Запустим сервер и откроем приложение в браузере:

mvn spring-boot:run

В результате мы видим, что биржевые тики меняются каждые три секунды без обновления страницы или опроса сервера:

Video Player should be here.

На данный момент мы создали приложение, которое получает биржевые тики через WebSocket. Далее давайте узнаем, как отлаживать это приложение.

3. Мозилла Фаерфокс

В Mozilla Firefox есть инспектор WebSocket наряду с другими инструментами веб-разработчика . В Firefox мы можем включить инструменты разработчика несколькими способами:

  • Windows и Linux: Ctrl + Shift + I или F12 или меню приложенийДополнительные инструменты → Инструменты веб-разработчика
  • macOS: Cmd + Opt + I

Затем нажмите Сетевой монитор → WS , чтобы открыть панель WebSockets:

./d8f55c96100ed9cd6575ee2d71b4b054.jpg

Теперь, когда инспектор WebSocket активен, давайте рассмотрим его подробнее.

3.1. Рукопожатие

Откройте URL-адрес http://localhost:8080 в Firefox. Открыв инструменты разработчика, мы видим HTTP-рукопожатие . Нажмите на запрос, чтобы проанализировать рукопожатие:

./116faef635500328236a9bfabab541e3.jpg

На вкладке « Заголовки » мы видим заголовки запроса и ответа с обновлениями протокола и другими заголовками WebSocket.

3.2. Обмен сообщениями

Далее, после рукопожатия, начинается обмен сообщениями . Нажмите на вкладку Response , чтобы просмотреть обмен сообщениями:

./5deb4c2f3675b2b0cf76c86a02a62c90.jpg

На панели ответов

./7a2c78a0071fc0d96ea85e9a570e3b4e.jpg

значок показывает запрос клиента, а представляет ответ сервера.

./c93e9e40815eb833d3d8c3517aa562d6.jpg

3.3. Прекращение соединения

В WebSockets соединение может закрыть либо клиент, либо сервер.

Во-первых, давайте эмулируем завершение соединения на стороне клиента. Нажмите кнопку « Отключить » на HTML-странице и перейдите на вкладку « Ответ »:

./2a1d86b516a09e9922b7b2ad259fa3c1.jpg

Здесь мы увидим запрос на завершение соединения от клиента.

Затем давайте выключим сервер, чтобы эмулировать закрытие соединения на стороне сервера. Соединение закрывается, так как сервер недоступен:

./7e3e9ad1622517b480fe8c5b715f941d.jpg

RFC6455 — протокол WebSocket определяет:

  • 1000 — нормальное закрытие
  • 1001 — сервер не работает или пользователь ушел со страницы.

4. Гугл Хром

В Google Chrome есть инспектор WebSocket, часть инструментов разработчика, похожая на Firefox. Мы можем активировать инспектор WebSocket несколькими способами:

  • Windows и Linux: Ctrl + Shift + I или Ctrl + Shift + J или F12 или Меню приложенийДополнительные инструментыИнструменты разработчика
  • macOS: Cmd + Opt + I

Затем нажмите на панель Network → WS , чтобы открыть панель WebSocket:

./0fd1450d80205d5178257d8ede7ab1db.jpg

4.1. Рукопожатие

Теперь откройте URL-адрес http://localhost:8080 в Chrome и нажмите на запрос в инструментах разработчика:

./7de1411d9b520b604133023e54488a11.jpg

На вкладке « Заголовки » мы видим все заголовки WebSocket, включая рукопожатие.

4.2. Обмен сообщениями

Далее проверим обмен сообщениями между клиентом и сервером. В инструментах разработчика перейдите на вкладку « Сообщения »:

./ed5655bbc76d0bc5bb43ea8fa897dd80.jpg

Как и в Firefox, мы можем просматривать обмен сообщениями, включая запрос CONNECT , запрос SUBSCRIBE и обмен MESSAGE .

4.3. Прекращение соединения

Наконец, мы отладим завершение соединения как на стороне клиента, так и на стороне сервера. Но сначала закроем соединение на стороне клиента:

./1ef6e1719e86ebfd42ebb7887e1be433.jpg

Мы видим изящное завершение соединения между клиентом и сервером. Далее давайте эмулируем сервер, разрывающий соединение:

./eb4bd4dd419b2478d0bfbcc599c5ed93.jpg

Успешное завершение соединения завершает обмен сообщениями между клиентом и сервером.

5. Wireshark

Wireshark — самый популярный, обширный и широко используемый инструмент для прослушивания сетевых протоколов. Итак, теперь давайте посмотрим, как обнюхивать и анализировать трафик WebSocket с помощью Wireshark.

5.1. Захват трафика

В отличие от других инструментов, мы должны захватывать трафик для Wireshark, а затем анализировать его. Итак, начнем с захвата трафика.

В Windows, когда мы открываем Wireshark, он отображает все доступные сетевые интерфейсы с текущим сетевым трафиком. Поэтому очень важно выбрать правильный сетевой интерфейс для захвата сетевых пакетов.

Как правило, сетевой интерфейс будет петлевым адаптером, если сервер WebSocket работает как локальный хост (127.0.0.1) :

./6ed1d324c9d65231bee4933c2db4e6d2.jpg

Затем, чтобы начать захват пакетов, дважды щелкните интерфейс. После выбора правильного интерфейса мы можем дополнительно фильтровать пакеты на основе протокола.

В Linux используйте команду tcpdump для захвата сетевого трафика . Например, откройте терминал оболочки и используйте эту команду для создания файла захвата пакетов, websocket.pcap :

tcpdump -w websocket.pcap -s 2500 -vv -i lo

Затем используйте Wireshark, чтобы открыть файл websocket.pcap .

5.2. Рукопожатие

Давайте попробуем проанализировать захваченные сетевые пакеты. Во-первых, поскольку начальное рукопожатие осуществляется по протоколу HTTP, давайте отфильтруем пакеты для протокола http :

./606aef7bb95910f51e095b0e22fa7fae.jpg

Далее, чтобы получить подробное представление о рукопожатии, щелкните пакет правой кнопкой мыши → FollowTCP Stream :

./8403f00d6c76bb40829a6c54b0896faf.jpg

5.3. Обмен сообщениями

Напомним, что после первоначального рукопожатия клиент и сервер взаимодействуют по протоколу веб- сокета . Итак, давайте отфильтруем пакеты для websocket . Остальные показанные пакеты показывают соединение и обмен сообщениями:

./606aef7bb95910f51e095b0e22fa7fae.jpg

5.4. Прекращение соединения

Во-первых, давайте отладим завершение соединения на стороне клиента. Запустите захват Wireshark и нажмите кнопку « Отключить » на HTML-странице и проверьте сетевые пакеты:

./c7874c441bc5f4b71fc7088c60e12b35.jpg

Точно так же давайте эмулируем завершение соединения на стороне сервера. Сначала запустите захват пакетов, а затем выключите сервер WebSocket:

./a16bce811d3f74a97b494f105395902c.jpg

6. Почтальон

На сегодняшний день поддержка Postman для WebSockets все еще находится в стадии бета-тестирования . Однако мы все еще можем использовать его для отладки наших веб-сокетов:

Откройте Postman и нажмите Ctrl+N или NewWebSocket Request : ``

./71f227185806007db681c64f5869753e.jpg

Затем в текстовом поле « Введите URL-адрес сервера » введите URL-адрес WebSocket и нажмите « Подключиться » :

./9f6e44e350d712f89829154a52688f13.jpg

6.1. Рукопожатие

После успешного подключения в разделе « Сообщения » щелкните запрос на подключение, чтобы просмотреть сведения о рукопожатии:

./1fc5f56dba45aead2b7bddfe3b3822a6.jpg

6.2. Обмен сообщениями

Теперь давайте проверим обмен сообщениями между клиентом и сервером:

./76e4414b3018a1ecc4924ac7f85d13b8.jpg

Как только клиент подписывается на тему, мы можем видеть поток сообщений между клиентом и сервером.

6.3. Прекращение соединения

Далее посмотрим, как отладить завершение соединения, как клиентом, так и сервером. Сначала нажмите кнопку « Отключить » в Postman, чтобы закрыть соединение со стороны клиента:

./9749adb9278c17a835bc705847de537e.jpg

Аналогично, чтобы проверить завершение соединения с сервером, выключите сервер:

./3fadd1645a8e7315f813af6c1fe948dd.jpg

7. Spring WebSocket-клиент

Наконец, давайте отладим WebSockets с помощью Java-клиента на основе Spring :

WebSocketClient client = new StandardWebSocketClient();
WebSocketStompClient stompClient = new WebSocketStompClient(client);
stompClient.setMessageConverter(new MappingJackson2MessageConverter());
StompSessionHandler sessionHandler = new StompClientSessionHandler();
stompClient.connect(URL, sessionHandler);

Это создает клиент WebSocket, а затем регистрирует обработчик сеанса клиента STOMP.

Далее давайте определим обработчик, который расширяет StompSessionHandlerAdapter . Намеренно класс StompSessionHandlerAdapter не предоставляет реализации, кроме метода getPayloadType . Следовательно, давайте дадим осмысленную реализацию этим методам:

public class StompClientSessionHandler extends StompSessionHandlerAdapter {

@Override
public void afterConnected(StompSession session, StompHeaders connectedHeaders) {
session.subscribe("/topic/ticks", this);
}

// other methods ...
}

Далее, когда мы запускаем этот клиент, мы получаем логи, похожие на:

16:35:49.135 [WebSocketClient-AsyncIO-8] INFO StompClientSessionHandler - Subscribed to topic: /topic/ticks
16:35:50.291 [WebSocketClient-AsyncIO-8] INFO StompClientSessionHandler - Payload -> {MSFT=17, GOOGL=48, AAPL=54, TSLA=73, HPE=89, AMZN=-5}

В логах мы видим соединение и обмен сообщениями. Более того, пока клиент запущен и работает, мы можем использовать Wireshark для перехвата пакетов WebSocket :

./be1edc80b3cbdba63bbbf09f11179a04.jpg

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

В этом руководстве мы узнали, как отлаживать WebSockets, используя некоторые из самых популярных и широко используемых инструментов. Поскольку использование и популярность WebSockets растут с каждым днем, мы можем ожидать, что количество инструментов отладки увеличится и они станут более совершенными.

Как всегда, полный исходный код доступен на GitHub .