JavaScript的WebSockets在打开后立即关闭

huangapple go评论83阅读模式
英文:

Javascript websockets closing immediately after opening

问题

以下是翻译好的内容:

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

connection.onopen = function(){
   alert('连接已打开!');
}


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

connection.onclose = function() {
    alert("WebSocket连接已关闭")
}

与服务器的连接已建立,并显示了一个提示框,内容为"连接已打开!"。然而,连接立即关闭。服务器没有调用close方法,控制台中也没有其他错误信息。这在Chrome和Firefox浏览器中都发生了。

我查看了许多类似的网络示例,但没有成功解决问题。

英文:
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")
}

The connection to the server is established and an alert is displayed for Connection open! However immediately afterwards the connection closes. The server does not call close and there seem to be no other errors in the console. This is happening in both chrome and firefox.

I looked at a bunch of different similar examples on the web but to no avail.

答案1

得分: 12

为了保持WebSocket连接打开,防止处理程序通过在connection.onmessage中使用return false;来返回,可以像下面这样写:

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

这样,当接收到消息时,会弹出服务器发送的消息,并且通过return false;来阻止处理程序继续执行。

英文:

to Keep Websocket Opened prevent handler from returning by return false; in connection.onmessage
like this :

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

答案2

得分: 9

我相信我已经找到了OP找到但未能解释清楚的解决方案。我没有足够的声望来发表评论,否则我会回应所有困惑的评论,要求对OP的回答进行澄清。

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

事实证明,我的服务器会自动关闭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中的循环来解决这个问题。希望这对某个人有所帮助。

英文:

I believe I've stumbled across the solution that OP found but failed miserably to explain. I don't have enough reputation to comment, otherwise I'd be responding to all of the confused comments begging for clarification on OP's response.

The short version is that I think OP was referring to his server-side connection handler when he said "All I had to do was block the handler from returning before the websocket connection closes".

It turns out my server was closing the webSocket automatically because I didn't understand how a certain webSocket function worked. Specifically, I was using a Python server script with asyncio/websockets and the following code:

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)

The idea was that websockets.serve would use handleClient to begin the connection and do some setup, then create a new task with receiveCommandsLoop that would take over the job of communication.

But it turns out: when you call websockets.serve, Python expects that when your handler (in this case, handleClient) returns, you must be done with the socket, and it closes it automatically.

Thus, by the time receiveCommandsLoop was run, handleClient had returned, and the webSocket had been automatically closed.

I was able to fix this by simply modifying my handleClient function to directly run the loop originally contained in receiveCommandsLoop. Hope this helps someone out there.

答案3

得分: 0

这也可能是在尝试通过 WebSocket 连接发送二进制数据时出现的情况,但某一方(客户端或服务器)试图将其解释为文本 - 除非你明确指定要使用二进制数据,否则许多库和框架都会这样做。

英文:

This also could be the case when you're trying to send binary data over a websocket connection, but some side (client or server) is trying to interpret it as a text - many libraries and frameworks do it unless you explicitly specify you do want binary data.

答案4

得分: 0

这可能也是一个登录问题。WebSocket会自动关闭需要身份验证的网站,但没有提供身份验证信息。

英文:

It could also be a login problem. The websocket will automatically close the website required authentication but no authentication information was provided.

答案5

得分: 0

从这篇帖子和其他帖子中整合线索,我找到了一个解决方案,适用于使用在各处都能找到的包含以下内容的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代码与原帖中的代码等效,我不需要做任何更改就能使其工作。

不幸的是,我无法解释为什么async for data in websocket:会使其实际上永远等待并在每次接收到消息时自动运行内部代码块,但对我来说确实如此,并且我在Python服务器端和客户端JavaScript控制台上都得到了所有预期的日志消息。

如果对这个主题更了解的人能够评论一下这是否是一个适用于一般用途的解决方案,或者是否有什么需要注意的地方,将不胜感激。

英文:

Piecing together hints from this post and others, I found a solution that works when using the python websocket server example found everywhere that includes something like:

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

To those of us new to websocket, I think the assumption is that the handler function will be called each time the client sends a message, which turns out not to be the case. As others mention, the connection closes as soon as the handler function returns once. The solution I found is to change it to:

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

My client-side javascript code is equivalent to the OP's and I didn't have to change anything for this to work.

Unfortunately I can't explain why async for data in websocket: makes it actually wait forever and spontaneously run the inner code block each time a message is received, but it does for me and I get all the expected log messages both on the python server side and the client javascript console.

If anyone more knowledgeable on this topic can comment on whether this is a good-for-general-use solution or if there's a gotcha to look out for here, it would be much appreciated.

答案6

得分: -7

已修复!

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

英文:

Fixed it!

All I had to do was block the handler from returning before the websocket connection closes

huangapple
  • 本文由 发表于 2014年4月29日 14:20:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/23356983.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定