Web Sockets 客户端一旦开始接收数据就会抛出异常

Posted

技术标签:

【中文标题】Web Sockets 客户端一旦开始接收数据就会抛出异常【英文标题】:Web Sockets client throwing an exception once it starts receiving data 【发布时间】:2017-10-30 10:31:27 【问题描述】:

我正在尝试建立到服务器的 Web-Socket 连接并进入接收模式。一旦客户端开始接收数据,它会立即关闭连接并出现以下异常

    webSoc_Received = await websocket.recv()
  File "/root/envname/lib/python3.6/site-packages/websockets/protocol.py", line 319, in recv
    raise ConnectionClosed(self.close_code, self.close_reason)
websockets.exceptions.ConnectionClosed: WebSocket connection is closed: code = 1007, no reason.

客户端代码片段:

import asyncio
import websockets

async def connect_ws():

    print("websockets.client module defines a simple WebSocket client API::::::")        
    async with websockets.client.connect(full_url,extra_headers=headers_conn1) as websocket:

        print ("starting")
        webSoc_Received = await websocket.recv()
        print ("Ending")
        Decode_data = zlib.decompress(webSoc_Received)      
        print(Decode_data)

asyncio.get_event_loop().run_until_complete(connect_ws())

对此有什么想法吗?

【问题讨论】:

【参考方案1】:

您使用run_until_complete(),它在您启动流程后完成。您应该使用.run_forever()。它将使您的套接字保持打开状态,直到您关闭它。 编辑: 你可以这样做:

loop = asyncio.get_event_loop()
loop.call_soon(connect_ws)  # Calls connect_ws once the event loop starts
loop.run_forever()

或者:

loop = asyncio.get_event_loop()
loop.run_until_complete(connect_ws())
loop.run_forever()

或者如果前面的例子没有成功,你可以试试下面的代码:

import asyncio

@asyncio.coroutine
def periodic():
  while True:
    print("websockets.client module defines a simple WebSocket client API::::::")        
    with websockets.client.connect(full_url,extra_headers=headers_conn1) as websocket:
       print ("starting")
       webSoc_Received = websocket.recv()
       print ("Ending")
       Decode_data = zlib.decompress(webSoc_Received)      
       print(Decode_data)

def stop():
  task.cancel()

task = asyncio.Task(periodic())
loop = asyncio.get_event_loop()
loop.call_later(5, stop)

try:
   loop.run_until_complete(task)
except asyncio.CancelledError:
   pass

【讨论】:

谢谢,但它抛出错误,因为我必须在其中调用函数 asyncio.get_event_loop().run_forever(connect_ws()) TypeError: run_forever() 需要 1 个位置参数,但给出了 2 个。任何关于这部分的想法? 使用第一种方法,它只是卡住了,从不接收数据,卡在下面/usr/local/lib/python3.6/asyncio/events.py:127: RuntimeWarning: coroutine 'connect_ws'从未等待 self._callback(*self._args)。与第二个相同的行为它实际上永远不会永远运行 根据您的第三个建议,它抛出相同的错误引发 ConnectionClosed(self.close_code, self.close_reason) websockets.exceptions.ConnectionClosed: WebSocket connection is closed: code = 1007, no reason. 与第二个例子相同:( @CoolNetworking,我的错。我已经为服务器端编写了代码。您能否提供 websockets 的服务器端代码。我认为应该是这样的websockets.readthedocs.io/en/stable/intro.html#basic-example【参考方案2】:

据我所知,您当前的代码将在收到第一条消息后退出。

尝试将您的代码更改为消费者模式,如此处的 websocket 文档中所述:

https://websockets.readthedocs.io/en/stable/intro.html#common-patterns

import asyncio
import websockets

async def connect_ws():
        print("websockets.client module defines a simple WebSocket client API::::::")    
        async with websockets.client.connect(full_url,extra_headers=headers_conn1) as websocket:
                while True:
                        print ("starting")
                        webSoc_Received = await websocket.recv()
                        print ("Ending")
                        Decode_data = zlib.decompress(webSoc_Received)      
                        print(Decode_data)

【讨论】:

以上是关于Web Sockets 客户端一旦开始接收数据就会抛出异常的主要内容,如果未能解决你的问题,请参考以下文章

使用 Sockets 发送和接收数据

JAVA中Sockets长连接时使用read()阻塞的问题!急救!

一旦 GPS 更新开始,Android GPSListener 就会收到通知

Winsock 仅在程序关闭时发送数据

什么是使用 .NET 3.5 异步 System.Net.Sockets.Socket 停止数据流?

Web Sockets - 向所有客户端发送消息