繁体   English   中英

打开后立即关闭的Javascript websockets

[英]Javascript websockets closing immediately after opening

connection = new WebSocket("ws://localhost:1050/join?username=test")

connection.onopen = function(){
   alert('Connection open!');
}


connection.onmessage = function(e){
   var server_message = e.data;
   alert(server_message);
}

connection.onclose = function() {
    alert("websocket closing")
}

与服务器的连接已建立,并显示连接打开的警报。 但是紧接着连接关闭。 服务器没有调用关闭,控制台中似乎没有其他错误。 这在 chrome 和 firefox 中都发生了。

我在网上看了一堆不同的类似例子,但无济于事。

保持 Websocket 打开防止处理程序通过return false; connection.onmessage像这样:

connection.onmessage = function(e){
   var server_message = e.data;
   alert(server_message);
   return false;
}

我相信我偶然发现了 OP 找到但未能解释清楚的解决方案。 我没有足够的声誉来发表评论,否则我将回应所有要求澄清 OP 回应的混乱评论。

简短的说法是,当他说“我所要做的就是在 websocket 连接关闭之前阻止处理程序返回”时,我认为 OP 指的是他的服务器端连接处理程序

原来我的服务器正在自动关闭 webSocket,因为我不明白某个 webSocket 函数是如何工作的。 具体来说,我使用的是带有 asyncio/websockets 的 Python 服务器脚本和以下代码:

async def receiveCommandsLoop(player):
    while True:
        msg = await player.websocket.recv()
        print(command)

async def handleClient(websocket, path):
    username = await websocket.recv()
    player = players[username]

    ...

    #Start task to listen for commands from player
    asyncio.get_event_loop().create_task(receiveCommandsLoop(player))

start_server = websockets.serve(handleClient, '', 8765)

这个想法是 websockets.serve 将使用 handleClient 开始连接并进行一些设置,然后使用 receiveCommandsLoop 创建一个新任务,该任务将接管通信工作。

但事实证明:当您调用 websockets.serve 时,Python 期望当您的处理程序(在本例中为 handleClient)返回时,您必须完成套接字并自动关闭它。

因此,到运行 receiveCommandsLoop 时,handleClient 已经返回,并且 webSocket 已自动关闭。

我能够通过简单地修改我的 handleClient 函数来直接运行最初包含在 receiveCommandsLoop 中的循环来解决这个问题。 希望这可以帮助那里的人。

当您尝试通过 websocket 连接发送二进制数据时,也可能是这种情况,但某些端(客户端或服务器)试图将其解释为文本 - 许多库和框架都会这样做,除非您明确指定您确实想要二进制数据。

也可能是登录问题。 websocket 会自动关闭需要认证的网站,但没有提供认证信息。

将这篇文章和其他文章的提示拼凑在一起,我找到了一个解决方案,该解决方案在使用随处可见的 python websocket 服务器示例时有效,其中包括:

async def handler(websocket, path):
    data = await websocket.recv()
    reply = f"Data recieved as: {data}!"
    await websocket.send(reply)

对于我们这些刚接触 websocket 的人来说,我认为假设每次客户端发送消息时都会调用handler函数,但事实并非如此。 正如其他人提到的那样,处理函数返回一次后连接就会关闭。 我找到的解决方案是将其更改为:

async def handler(websocket, path):
    async for data in websocket:
        reply = f"Data recieved as: {data}!"
        print(data)
        await websocket.send(reply)

我的客户端 javascript 代码等同于 OP,我无需更改任何内容即可工作。

不幸的是,我无法解释为什么async for data in websocket:让它实际上永远等待并在每次收到消息时自发地运行内部代码块,但它对我有用,我在 python 服务器上得到了所有预期的日志消息端和客户端 javascript 控制台。

如果任何对此主题有更多了解的人可以评论这是否是一个适合通用的解决方案,或者这里是否有需要注意的地方,我们将不胜感激。

修复!

我所要做的就是在 websocket 连接关闭之前阻止处理程序返回

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM