调试Websocket
1. 概述
WebSocket 在客户端和服务器之间提供了一个事件驱动的、双向的、全双工的连接。WebSocket 通信涉及握手、消息传递(发送和接收消息)和关闭连接。
在本教程中,我们将学习使用浏览器 和其他流行工具调试 WebSocket 。
2. 构建 WebSocket
让我们从构建 一个向客户端推送股票代码更新的 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. Spring 配置
接下来,让我们定义启用 WebSocket 支持所需的*@Configuration* :
@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>
接下来,让我们使用SockJS 连接到 WebSocket 服务器:
function connect() {
let socket = new SockJS('/stock-ticks');
stompClient = Stomp.over(socket);
stompClient.connect({}, function (frame) {
stompClient.subscribe('/topic/ticks', function (ticks) {
...
});
});
}
在这里,我们使用 SockJS 打开一个 WebSocket,然后订阅主题/topic/ticks。最终,当服务器产生消息时,客户端消费并在用户界面上显示消息。
2.4. 示范
让我们启动服务器并在浏览器中打开应用程序:
mvn spring-boot:run
结果,我们看到股票报价每三秒变化一次,而无需刷新页面或进行服务器轮询:
到目前为止,我们已经构建了一个在 WebSocket 上接收股票报价的应用程序。接下来,让我们学习如何调试这个应用程序。
3. 火狐浏览器
Mozilla Firefox 有一个 WebSocket 检查器以及其他 Web 开发工具。在 Firefox 中,我们可以通过多种方式启用开发者工具:
- Windows 和 Linux:
Ctrl + Shift + I
或F12
或应用程序菜单 → 更多工具 → Web 开发人员工具 - macOS:
Cmd + Option + I
接下来,单击Network Monitor → WS打开 WebSockets 窗格:
随着 WebSocket 检查器处于活动状态,让我们进一步探索它。
3.1. 握手
在 Firefox 中打开 URL http://localhost:8080 。打开开发人员工具后,我们现在可以看到 HTTP 握手。点击请求分析握手:
在Headers选项卡下,我们可以看到带有协议升级和其他 WebSocket 标头的请求和响应标头。
3.2. 消息交换
随后,握手之后,消息交换开始。单击Response选项卡以查看消息交换:
在“Response”窗格中,a
显示客户端请求,a 表示服务器响应。
3.3. 连接终止
在 WebSockets 中,客户端或服务器都可以关闭连接。
首先,让我们模拟客户端连接终止。单击HTML 页面上的Disconnect 按钮并查看Response选项卡:
在这里,我们将看到来自客户端的连接终止请求。
接下来,让我们关闭服务器以模拟服务器端连接关闭。由于无法访问服务器,连接将关闭:
- 1000 – 正常关闭
- 1001 - 服务器已关闭,或用户已导航离开页面
4. 谷歌浏览器
Google Chrome 有一个 WebSocket 检查器,它是开发人员工具的一部分,类似于 Firefox。我们可以通过以下几种方式激活 WebSocket 检查器:
- Windows 和 Linux:
Ctrl + Shift + I
或F12
或应用程序菜单 → 更多工具 → 开发工具 - macOS:
Cmd + Option + I
接下来,点击Network → WS面板打开 WebSocket 面板:
4.1. 握手
现在,在 Chrome 中打开 URL http://localhost:8080 并在开发者工具中点击请求:
在Headers选项卡下,我们注意到所有 WebSocket 标头,包括握手。
4.2. 消息交换
接下来,让我们检查客户端和服务器之间的消息交换。在开发人员工具上,单击“*Messages *”选项卡:
和Firefox一样,我们可以查看消息交换,包括CONNECT请求、SUBSCRIBE请求和MESSAGE交换。
4.3. 连接终止
最后,我们将调试客户端和服务器端的连接终止。但是,首先,让我们关闭客户端连接:
我们可以看到客户端和服务器之间的连接正常终止。接下来,让我们模拟一个终止连接的服务器:
成功的连接终止结束客户端和服务器之间的消息交换。
5. Wireshark
Wireshark 是最流行、最广泛和使用最广泛的网络协议嗅探工具。那么接下来,让我们看看如何使用 Wireshark 嗅探和分析 WebSocket 流量。
5.1. 捕获流量
与其他工具不同,我们必须为 Wireshark 捕获流量,然后对其进行分析。所以,让我们从捕获流量开始。
在 Windows 中,当我们打开 Wireshark 时,它会显示所有可用的网络接口以及实时网络流量。因此,选择正确的网络接口来捕获网络数据包至关重要。
*通常,如果 WebSocket 服务器作为*localhost (127.0.0.1)运行,则网络接口将是一个环回适配器:
接下来,要开始捕获数据包,请双击该界面。一旦选择了正确的接口,我们就可以根据协议进一步过滤数据包。
在 Linux中,使用tcpdump 命令捕获网络流量。例如,打开一个 shell 终端并使用此命令生成一个数据包捕获文件websocket.pcap:
tcpdump -w websocket.pcap -s 2500 -vv -i lo
然后,使用 Wireshark 打开websocket.pcap文件。
5.2. 握手
让我们尝试分析一下目前捕获的网络数据包。首先,由于初始握手是在 HTTP 协议上,让我们过滤http协议的数据包:
接下来,要获得握手的详细视图,请右键单击数据包 → Follow → TCP Stream:
5.3. 消息交换
回想一下,在初始握手之后,客户端和服务器通过 websocket 协议进行通信。 因此,让我们过滤 websocket 的数据包。 显示的其余数据包揭示了连接和消息交换:
5.4. 连接终止
首先,让我们调试客户端连接终止。 启动Wireshark抓包,点击HTML页面上的Disconnect按钮,查看网络数据包:
同样,让我们模拟服务器端连接终止。 首先,启动数据包捕获,然后关闭 WebSocket 服务器:
6. Postman
截至目前,Postman 对 WebSockets 的支持仍处于测试阶段。 但是,我们仍然可以使用它来调试 WebSocket:
打开 Postman 并按 Ctrl + N
或 New → WebSocket Request:
接下来,在 Enter Server URL 文本框中,输入 WebSocket URL 并单击 Connect:
6.1. 握手
连接成功后,在 Messages 部分,单击连接请求以查看握手详细信息:
6.2. 消息交换
现在,让我们检查一下客户端和服务器之间的消息交换:
一旦客户端订阅了该主题,我们就可以看到客户端和服务器之间的消息流。
6.3. 连接终止
此外,让我们看看如何调试客户端和服务器的连接终止。 首先,点击Postman中的Disconnect按钮,从客户端关闭连接:
同样,要检查服务器连接终止,请关闭服务器:
7. Spring WebSocket Client
最后,让我们使用基于 Spring 的 Java 客户端 调试 WebSockets:
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 数据包: