• 正确主动关闭websocket,异常关闭处理


    CloseEvent.code

    下面是一个示例的WebSocket错误码表格,包括错误码、错误处理方法和错误码说明:

    错误码错误如何处理错误码说明
    1000关闭连接正常关闭连接
    1001关闭连接后几秒后重连终端离开或刷新页面
    1002关闭连接上报日志给开发者协议错误
    1003关闭连接上报日志给开发者数据类型错误
    1005关闭连接提示未知的错误几秒后重连无关闭状态码
    1006关闭连接 几秒后重连连接意外中断
    1007关闭连接上报日志给开发者,几秒后重连非法数据
    1008关闭连接笙宝日志给开发者,几秒后重连消息内容违反策略
    1009关闭连接,上报日志给开发者,几秒后重连消息过大
    1010关闭连接,上报日志给开发者,几秒后重连扩展协商失败
    1011关闭连接服务器内部错误
    1012-1014关闭连接保留未使用的错误码
    1015关闭连接TLS握手失败
    • 0-999 暂未使用
    关闭状态码简称原因
    1000正常关闭连接成功地完成了创建它的目的。
    1001离开端点消失了,可能是因为服务器故障,也可能是因为浏览器离开了打开连接的页面。
    1002协议错误由于协议错误,端点正在终止连接。
    1003不支持的数据由于端点接收到的数据类型无法接受,连接被终止。(例如,纯文本端点接收二进制数据
    1004暂时保留保留。将来可能会定义一个含义。
    1005No Status RcvdReserved. Indicates that no status code was provided even though one was expected.
    1006Abnormal ClosureReserved. Indicates that a connection was closed abnormally (that is, with no close frame being sent) when a status code is expected.
    1007Invalid frame payload dataThe endpoint is terminating the connection because a message was received that contained inconsistent data (e.g., non-UTF-8 data within a text message).
    1008Policy ViolationThe endpoint is terminating the connection because it received a message that violates its policy. This is a generic status code, used when codes 1003 and 1009 are not suitable.
    1009Message Too BigThe endpoint is terminating the connection because a data frame was received that is too large.
    1010Mandatory Ext.The client is terminating the connection because it expected the server to negotiate one or more extension, but the server didn’t.
    1011Internal ErrorThe server is terminating the connection because it encountered an unexpected condition that prevented it from fulfilling the request.
    1012Service RestartThe server is terminating the connection because it is restarting.
    1013Try Again LaterThe server is terminating the connection due to a temporary condition, e.g. it is overloaded and is casting off some of its clients.
    1014Bad GatewayThe server was acting as a gateway or proxy and received an invalid response from the upstream server. This is similar to 502 HTTP Status Code.
    1015TLS handshakeReserved. Indicates that the connection was closed due to a failure to perform a TLS handshake (e.g., the server certificate can’t be verified).
    1016–2999For definition by future revisions of the WebSocket Protocol specification, and for definition by extension specifications.
    3000–3999For use by libraries, frameworks, and applications. These status codes are registered directly with IANA. The interpretation of these codes is undefined by the WebSocket protocol.
    4000–4999For private use, and thus can’t be registered. Such codes can be used by prior agreements between WebSocket applications. The interpretation of these codes is undefined by the WebSocket protocol.

    后面的不想翻译,请读者自行翻译,帮你贴一个翻译传送门

    在这里插入图片描述

    关闭监听

    TS

    WebSocket.onclose = (event) => {
      console.log(event.code);
    };
    
    • 1
    • 2
    • 3

    java

        @Override
        public void onClosed(WebSocket webSocket, int code, String reason) {
            super.onClosed(webSocket, code, reason);
            // todo 根据状态码执行重连
            if(code != 1000){
            
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    JavaScript (Node.js):

    const WebSocket = require('ws');
    
    const ws = new WebSocket('ws://localhost:8080');
    
    ws.on('open', () => {
      // WebSocket连接成功
    });
    
    ws.on('message', (data) => {
      // 处理接收到的消息
    });
    
    ws.on('close', () => {
      // WebSocket连接关闭
    });
    
    ws.on('error', (error) => {
      // 处理WebSocket错误
      ws.close();
    
      // 执行重连逻辑
      setTimeout(() => {
        const newWs = new WebSocket('ws://localhost:8080');
        // ...
      }, 5000);
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    Python:

    import websocket
    
    def on_message(ws, message):
        # 处理接收到的消息
    
    def on_close(ws):
        # WebSocket连接关闭
    
    def on_error(ws, error):
        # 处理WebSocket错误
        ws.close()
    
        # 执行重连逻辑
        time.sleep(5)
        new_ws = websocket.WebSocketApp("ws://localhost:8080", on_open=on_open, on_message=on_message, on_close=on_close, on_error=on_error)
        # ...
    
    def on_open(ws):
        # WebSocket连接成功
    
    ws = websocket.WebSocketApp("ws://localhost:8080", on_open=on_open, on_message=on_message, on_close=on_close, on_error=on_error)
    ws.run_forever()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    Java Android:

    import javax.websocket.*;
    
    @ClientEndpoint
    public class WebSocketClient {
        @OnOpen
        public void onOpen(Session session) {
            // WebSocket连接成功
        }
    
        @OnMessage
        public void onMessage(String message) {
            // 处理接收到的消息
        }
    
        @OnClose
        public void onClose(Session session, CloseReason closeReason) {
            // WebSocket连接关闭
        }
    
        @OnError
        public void onError(Session session, Throwable error) {
            // 处理WebSocket错误
            try {
                session.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            // 执行重连逻辑
            try {
                Thread.sleep(5000);
                WebSocketContainer container = ContainerProvider.getWebSocketContainer();
                Session newSession = container.connectToServer(WebSocketClient.class, URI.create("ws://localhost:8080"));
                // ...
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    ###. C#:

    using System;
    using System.Net.WebSockets;
    using System.Threading;
    using System.Threading.Tasks;
    
    public class WebSocketClient {
        private ClientWebSocket _client;
    
        public async Task Connect() {
            _client = new ClientWebSocket();
            await _client.ConnectAsync(new Uri("ws://localhost:8080"), CancellationToken.None);
    
            // WebSocket连接成功
    
            // 接收消息
            while (_client.State == WebSocketState.Open) {
                var buffer = new ArraySegment<byte>(new byte[4096]);
                WebSocketReceiveResult result = await _client.ReceiveAsync(buffer, CancellationToken.None);
    
                if (result.MessageType == WebSocketMessageType.Text) {
                    string message = Encoding.UTF8.GetString(buffer.Array, buffer.Offset, result.Count);
                    // 处理接收到的消息
                }
            }
        }
    
        public async Task Close() {
            await _client.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closing", CancellationToken.None);
    
            // WebSocket连接关闭
    
            // 执行重连逻辑
            await Task.Delay(5000);
            await Connect();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    以下是使用Kotlin和Swift语言实现关闭WebSocket并根据异常执行重连的示例:

    Kotlin:

    import okhttp3.*
    import okhttp3.WebSocket
    import okhttp3.WebSocketListener
    import java.util.concurrent.TimeUnit
    
    class WebSocketClient : WebSocketListener() {
        private lateinit var webSocket: WebSocket
    
        fun connect() {
            val okHttpClient = OkHttpClient.Builder()
                .retryOnConnectionFailure(true)
                .pingInterval(10, TimeUnit.SECONDS)
                .build()
    
            val request = Request.Builder()
                .url("ws://localhost:8080")
                .build()
    
            webSocket = okHttpClient.newWebSocket(request, this)
        }
    
        override fun onOpen(webSocket: WebSocket, response: Response) {
            // WebSocket连接成功
        }
    
        override fun onMessage(webSocket: WebSocket, text: String) {
            // 处理接收到的消息
        }
    
        override fun onClosed(webSocket: WebSocket, code: Int, reason: String) {
            // WebSocket连接关闭
        }
    
        override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
            // 处理WebSocket错误
            webSocket.close(1000, null)
    
            // 执行重连逻辑
            Thread.sleep(5000)
            connect()
        }
    }
    
    fun main() {
        val client = WebSocketClient()
        client.connect()
        // ...
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    Swift:

    import Foundation
    import Starscream
    
    class WebSocketClient: WebSocketDelegate {
        private var socket: WebSocket?
    
        func connect() {
            socket = WebSocket(url: URL(string: "ws://localhost:8080")!)
            socket?.delegate = self
            socket?.connect()
        }
    
        func websocketDidConnect(socket: WebSocketClient) {
            // WebSocket连接成功
        }
    
        func websocketDidReceiveMessage(socket: WebSocketClient, text: String) {
            // 处理接收到的消息
        }
    
        func websocketDidDisconnect(socket: WebSocketClient, error: Error?) {
            // WebSocket连接关闭
    
            // 执行重连逻辑
            DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
                self.connect()
            }
        }
    
        func websocketDidReceiveData(socket: WebSocketClient, data: Data) {
            // 处理接收到的数据
        }
    }
    
    let client = WebSocketClient()
    client.connect()
    // ...
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
  • 相关阅读:
    Android 8.0网络DNS
    离线环境harbor 搭建及使用
    【Qt控件之QLineEdit、QPlainTextEdit 、QTextEdit 、QTextBrowser】使用及区别
    VL33-非整数倍数据位宽转换8to12,实现先到的数据应置于输出的 高bit 位。
    iwebsec靶场 文件包含漏洞通关笔记8-php://input伪协议利用
    C++11标准模板(STL)- 算法(std::partition_point)
    Python 小贴士(1)
    Leetcode:前缀和系列
    Azure DevOps(二)Azure Pipeline 集成 SonarQube 维护代码质量和安全性
    C/S - Exploits 学习笔记
  • 原文地址:https://blog.csdn.net/gao511147456/article/details/127887179