1. 概述

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 Boot配置

创建配置类启用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>

使用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

效果:股票数据每3秒自动更新,无需页面刷新或轮询。

至此我们完成了基础应用搭建,接下来进入调试环节。

3. Mozilla Firefox调试

Firefox内置WebSocket调试工具,可通过以下方式打开:

  • Windows/Linux: Ctrl + Shift + IF12 或菜单 → 更多工具 → Web开发者工具
  • macOS: Cmd + Opt + I

在开发者工具中点击网络监控器 → WS标签页:

Firefox调试界面

3.1. 握手分析

访问http://localhost:8080,在开发者工具中查看HTTP握手请求:

Firefox握手分析

Headers标签页可看到协议升级等WebSocket相关请求/响应头。

3.2. 消息交换

握手完成后开始消息传递,点击Response标签页查看通信内容:

Firefox消息交换

  • 表示客户端请求
  • 表示服务端响应

3.3. 连接终止

WebSocket支持任意方主动关闭连接:

  1. 客户端关闭:点击HTML页面的断开按钮,在Response标签页可见终止请求: 客户端关闭

  2. 服务端关闭:停止服务器模拟服务端异常,连接自动断开: 服务端关闭

根据RFC6455协议定义

  • 1000 – 正常关闭
  • 1001 – 服务宕机或用户离开页面

4. Google Chrome调试

Chrome的WebSocket调试功能与Firefox类似,打开方式:

  • Windows/Linux: Ctrl + Shift + ICtrl + Shift + JF12
  • macOS: Cmd + Opt + I

在开发者工具中选择网络 → WS标签页:

Chrome调试界面

4.1. 握手分析

访问http://localhost:8080,点击请求查看握手详情:

Chrome握手分析

Headers标签页包含所有WebSocket握手头信息。

4.2. 消息交换

切换到Messages标签页查看消息流:

Chrome消息交换

可清晰看到CONNECTSUBSCRIBEMESSAGE交互过程。

4.3. 连接终止

  1. 客户端关闭:点击断开按钮后显示优雅关闭: Chrome客户端关闭

  2. 服务端关闭:停止服务器后连接中断: Chrome服务端关闭

5. Wireshark抓包分析

Wireshark是强大的网络协议分析工具,适合深度调试WebSocket流量。

5.1. 流量捕获

与其他工具不同,需先捕获流量再分析:

  • Windows:启动Wireshark后选择正确的网络接口(本地服务选回环适配器): Wireshark接口选择

  • Linux:使用tcpdump生成抓包文件:

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

    然后用Wireshark打开websocket.pcap文件。

5.2. 握手分析

初始握手基于HTTP协议,过滤http包查看握手详情:

Wireshark握手分析

右键选择Follow → TCP Stream查看完整握手过程:

TCP流分析

5.3. 消息交换

握手后切换到websocket协议,过滤查看消息流:

Wireshark消息交换

5.4. 连接终止

  1. 客户端关闭:点击断开按钮后捕获终止包: 客户端关闭抓包

  2. 服务端关闭:停止服务器后捕获连接中断包: 服务端关闭抓包

6. Postman调试

Postman的WebSocket功能仍处于Beta阶段,但已能满足基本调试需求。

6.1. 基础操作

  1. Ctrl + N或选择New → WebSocket Request
  2. 输入服务器URL(如ws://localhost:8080/stock-ticks)并点击连接: Postman连接

6.2. 握手分析

连接成功后,在Messages区域点击连接请求查看握手详情:

Postman握手分析

6.3. 消息交换

订阅主题后可实时查看消息流:

Postman消息交换

6.4. 连接终止

  1. 客户端关闭:点击Disconnect按钮: Postman客户端关闭

  2. 服务端关闭:停止服务器后连接自动中断: Postman服务端关闭

7. Spring WebSocket客户端

最后介绍使用Java客户端调试WebSocket

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

创建自定义会话处理器:

public class StompClientSessionHandler extends StompSessionHandlerAdapter {
 
    @Override
    public void afterConnected(StompSession session, StompHeaders connectedHeaders) {
        session.subscribe("/topic/ticks", this);
    }
 
    // 其他方法实现...
}

运行客户端输出日志示例:

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抓包分析

Java客户端抓包

8. 总结

本教程演示了使用主流工具调试WebSocket的实用技巧。随着WebSocket应用日益普及,调试工具也在持续进化,掌握这些方法能显著提升开发效率。

完整源代码请参考:GitHub仓库


原始标题:Debugging WebSockets | Baeldung