spring websocket客户端没有检测到网络连接丢失

Posted

技术标签:

【中文标题】spring websocket客户端没有检测到网络连接丢失【英文标题】:spring websocket client does not detect network connection loss 【发布时间】:2022-01-06 23:08:48 【问题描述】:

Spring @ClientEndpoint websocket 客户端未检测到由于电缆拔出而导致的网络断开。我还实现了一个 ping/pong 机制。有人可以帮我解决发生了什么吗? 但是,我在重新连接电缆后看到以下异常,仅供参考,所有设置均为默认设置。此外,我正在连接到没有任何控制权的第 3 方远程端点。

xxxxxException: closed with code : CLOSED_ABNORMALLY reason: CloseReason: code [1006], reason [java.io.IOException: Connection reset by peer]
    at xxxxxx.onClose(WSClient.java:xx)

@ClientEndpoint
public class WSClient 
    private Session session;
    private int i = 0;

    @OnOpen
    public void open(Session session) 
        System.out.println("Connected to the server");
        this.session = session;
    

    @OnClose
    public void close(Session session, CloseReason closeReason) 
        System.out.println("connection closed " + closeReason.getReasonPhrase());
    

    @OnError
    public void error(Session session, Throwable t) 
        System.out.println(session.getId());
        System.out.println("Error in connection " + t.getMessage());
    

    @OnMessage
    public void message(Session session, String message) 
        System.out.println("message received: " + message + " " + i++);
    

    public void send(String message)
        try 
            if(session.isOpen()) 
                this.session.getBasicRemote().sendPing(ByteBuffer.wrap(message.getBytes()));
                System.out.println("socket is open " + i++);
             else 
                System.out.println("socket closed");
            
         catch (IOException e) 
            e.printStackTrace();
        
    


@Component
public class ClientApp implements ApplicationListener<ApplicationReadyEvent> 

    private void startConnection() throws Exception 
        WebSocketContainer container = ContainerProvider.getWebSocketContainer();
        WSClient client = new WSClient();
        container.connectToServer(client, new URI("ws://wshost:8080/ping"));

        while (true) 
            client.send("ping");
            TimeUnit.SECONDS.sleep(3);
        
    

    @Override
    public void onApplicationEvent(ApplicationReadyEvent event) 
        try 
            startConnection();
         catch (Exception e) 
            System.out.println(e);
        
    

【问题讨论】:

【参考方案1】:

可以通过将以下代码添加到WSClient 来解决此问题。

@OnMessage
public void pongMessage(Session session, PongMessage msg) 
    LOGGER.debug("Pong message received: " + Instant.now());
    //schedule a timeout task, and raise an event or so if timed out.

当远程端点发送 pong 消息作为对发送的 ping 消息的响应时,将调用上述 sn-p。基本上会有两个方法用@OnMessage注解,一个是接收用户消息载荷,另一个是框架发送的pong消息载荷。

【讨论】:

以上是关于spring websocket客户端没有检测到网络连接丢失的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 spring+stomp+sockjs 获得 websocket 响应

带有 Sockjs 和 Spring 4 但没有 Stomp 的 WebSocket

WebSocket 心跳检测和重连机制

websocket检测服务器是否断开-来游戏手游解答

Spring:向 websocket 客户端发送消息

hpsocket默认心跳