当服务器没有 ping 间隔时,Websocket 自动关闭

Websocket closes automatically when server has no ping interval

我看到了很多关于这个问题的问题,但他们都提到了由于服务器的协议而必须 ping 服务器以保持连接活动的想法。下面示例中的服务器没有 ping/pong 的要求。当尝试 Bare.send_stuff 方法中的 send() 时,浏览器自动关闭连接,我收到以下错误:

InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable

客户端(通过 React 打字稿):

export class Bare{

    connections : Map<string,WebSocket>
    constructor(){
        this.connections = new Map<string,WebSocket>();
    }

    setup_connection(name:string){
        let connection = new WebSocket('ws://localhost:50223');
        this.connections.set(name,connection);

    }
    send_stuff(name:string){
        let connection = this.connections.get(name);
        connection.send("stuff");
    }
} 

服务器(Python):

import asyncio
import websockets
import logging
logger = logging.getLogger('websockets')
logger.setLevel(logging.INFO)
logger.addHandler(logging.StreamHandler())

class Main:

    def __init__(self):
        self.host = '127.0.0.1' 
        self.port = 50223

    async def check_declaration(self,websocket,path):
        while True:
            data = await websocket.recv()
            print(data)
            
    def start_server(self):
        loop = asyncio.get_event_loop()
        loop.run_until_complete(
            websockets.serve(self.check_declaration,self.host,self.port,ping_interval=None))
        loop.run_forever()

Main().start_server()

有没有办法在不需要 ping 的情况下在客户端保持连接?

编辑 下面的客户端在服务器上工作得很好:

const connection = new WebSocket('ws://localhost:50223');
const sayHi = () => connection.send('hi');
connection.onopen = () => {
  setInterval(sayHi, 5*60*1000);
  sayHi();
};
connection.onmessage = ({data}) => console.log(data);

这让我相信除非在事件循环中引用连接,否则浏览器不会保持连接打开?不是 100% 确定。

事实证明,如果未引用 WebSocket 连接或未声明连接的回调函数,浏览器将关闭所有 WebSocket 连接。我没有使用 setup_connection 初始化连接然后等待使用 send_stuff 发送数据,而是开始了一个完全不同的任务,该任务按一定间隔运行,因此浏览器客户端不会过早关闭连接。

新客户:

const connection = new WebSocket('ws://localhost:50223');
const sayHi = () => connection.send('hi');
connection.onopen = () => {
  setInterval(sayHi, 5*60*1000);
  sayHi();
};

根据我粗略调查此问题的发现,浏览器不允许您在不引用该连接的情况下建立连接,您需要在连接初始化后立即声明回调。在间隔上声明 .send 函数或声明 .onmessage 回调函数应该使连接保持活动状态。