【问题标题】:1006 Connection closed abnormally error with python 3.7 websocketspython 3.7 websockets的1006连接异常关闭错误
【发布时间】:2019-06-03 17:50:15
【问题描述】:

我遇到了与 python websockets 的这个 github 问题相同的问题: https://github.com/aaugustin/websockets/issues/367

但建议的解决方案对我不起作用。我得到的错误是:

websockets.exceptions.ConnectionClosed:WebSocket连接关闭:code = 1006(连接异常关闭[内部]),无原因

这是我的代码:

async def get_order_book(symbol):
    with open('test.csv', 'a+') as csvfile:
        csvw = csv.writer(csvfile, delimiter=',', quotechar='|', quoting=csv.QUOTE_MINIMAL)
        DT = Data(data=data, last_OB_id=ob_id, last_TR_id=tr_id, sz=10, csvw=csvw)

        while True:
            if not websocket.open:
                print('Reconnecting')
                websocket = await websockets.connect(ws_url)
            else:
                resp = await websocket.recv()
                update = ujson.loads(resp)
                DT.update_data(update)

async def get_order_books():
    r = requests.get(url='https://api.binance.com/api/v1/ticker/24hr')
    await asyncio.gather(*[get_order_book(data['symbol']) for data in r.json()])

if __name__ == '__main__':
    asyncio.run(get_order_books())

我一直在测试它的方式是关闭我的互联网连接,但延迟十秒后它仍然返回 1006 错误。

我正在运行 Python 3.7 和 Websockets 7.0。

请告诉我你的想法,谢谢!

【问题讨论】:

    标签: python python-3.x websocket python-asyncio


    【解决方案1】:

    我遇到了同样的问题。 挖掘了一段时间后,我发现了多个版本的答案,告诉我只需重新连接,但我认为这不是一条合理的路线,所以我又挖了一些。

    启用 DEBUG 级别的日志记录我发现 python websockets 默认发送 ping 数据包,并且未能收到响应,导致连接超时。我不确定这是否符合标准,但至少 javascript websockets 在我的 python 脚本超时的服务器上完全没问题。

    解决方法很简单:在connect 中添加另一个 kw 参数:

    websockets.connect(uri, ping_interval=None)
    

    同样的参数也应该适用于服务器端函数serve

    更多信息https://websockets.readthedocs.io/en/stable/api.html

    【讨论】:

      【解决方案2】:

      所以我找到了解决方案:

      当连接关闭时,它会出于某种原因跳出 while 循环。所以为了保持 websocket 运行,你必须包围

      resp = await websocket.recv()
      

      with try ... except and have

      print('Reconnecting')
      websocket = await websockets.connect(ws_url)
      

      在异常处理部分。

      【讨论】:

      • 这是有史以来最糟糕的解决方案
      【解决方案3】:

      我可能晚了一年,但我只是遇到了这个问题。我的 html5 websocket 客户端上没有连接问题,但 .py 测试客户端会在大约一分钟后崩溃(客户端和服务器也都引发 1006 异常)。作为测试,我开始在客户端发送的每一帧之后await connection.recv()ing。没有更多的问题。我不需要为我的 .py 测试客户端接收数据,但如果你让它建立起来显然会导致问题。这也可能是我的网络版本运行良好的原因,因为我正在处理 .onmessage 回调。

      我很确定这就是发生此错误的原因。所以这种只接收数据的解决方案是一个实际的解决方案,而不是禁用 ping 和搞砸协议的重要功能。

      【讨论】:

      • 这为我解决了问题。我开始在我的电脑上敲我的头,想知道为什么我的套接字会这样关闭。非常感谢
      • @Directory,如果您可以粘贴相关代码,是否有可能?提前致谢。
      【解决方案4】:

      我遇到了同样的问题。 shinola 的解决方案工作了一段时间,但有时我仍然会出错。

      为了处理这个问题,我将连接放入while True: 循环中,并添加了两个单独的 try except 块。 consumer 变量是一个处理从 websocket 连接接收到的消息的函数。

      async def websocketConnect(uri, payload, consumer):
          websocket = await websockets.connect(uri, ssl=True)
          await websocket.send(json.dumps(payload))
          while True:
              if not websocket.open:
                  try:
                      print('Websocket is NOT connected. Reconnecting...')
                      websocket = await websockets.connect(uri, ssl=True)
                      await websocket.send(json.dumps(payload))
                  except:
                      print('Unable to reconnect, trying again.')
              try:
                  async for message in websocket:
                      if message is not None:
                          consumer(json.loads(message))
              except:
                  print('Error receiving message from websocket.')
      
      

      我使用以下方式开始连接:

      def startWebsocket(uri, payload, consumer):
          asyncio.run(websocketConnect(uri, payload, consumer))
      

      【讨论】:

      • 如果` ping_interval=None` 不能解决问题,对我来说,您的建议只会陷入无限循环。 : (
      • 一旦程序进入循环它应该永远运行,试图重新连接。这就是为什么我们在程序的其余部分初始化后启动websocket连接并使用回调函数来处理数据。我们还使用threading 将 websocket 连接与我们的其他应用程序进程分开。如果在出现大量错误后需要中断循环,可以在 try 语句中添加重试计数器。因此,它会在中断循环之前重试 x 次。
      【解决方案5】:

      我想他们在这里解释了:https://websockets.readthedocs.io/en/stable/faq.html

      这意味着 TCP 连接丢失。因此, WebSocket 连接在没有收到关闭帧的情况下关闭,这 不正常。

      您可以捕获并处理 ConnectionClosed 以防止它被 记录。

      长期连接可能会丢失有几个原因:

      最终用户设备往往会经常失去网络连接,并且 出乎意料的是,因为它们可以移出无线网络覆盖范围, 从有线网络中拔出,进入飞行模式,进入 睡觉等等。

      未配置为长期使用的 HTTP 负载平衡器或代理 连接可能会在短时间内终止连接, 通常是 30 秒。

      【讨论】:

        【解决方案6】:

        我通过uvicornhypercorn 解决了这个问题。

        hypercorn app:app
        

        【讨论】:

          猜你喜欢
          • 2021-01-25
          • 1970-01-01
          • 2014-05-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-08
          • 2018-11-27
          相关资源
          最近更新 更多