代码之家  ›  专栏  ›  技术社区  ›  stas stas

BinanceSocketManager如何正确处理连接中断?

  •  0
  • stas stas  · 技术社区  · 2 年前

    一天中的好时光,告诉我我无论如何都无法战胜下一种疾病。我通过WS信道实时接收找到的ohlcv。有时,我的互联网连接会消失,有时当WS连接太久时,Binance本身就会断开连接。我想确保在断开连接的情况下,我的程序会尝试再次连接。为了做到这一点,我做了一个Try-except块——如果其中发生了不好的事情,我只需要再次尝试调用connect函数。这听起来似乎合乎逻辑,应该可行。然而,在测试过程中,我出现了一个错误

    达到最大重新连接次数5:CANCEL read_loop

    起初,这个错误看起来像是我设法捕捉到的,但随后调用堆栈跟进,程序崩溃

    Traceback (most recent call last):
      File "/home/master/PycharmProjects/PROJECT/venv/lib/python3.10/site-packages/aiohttp/connector.py", line 1155, in _create_direct_connection
        hosts = await asyncio.shield(host_resolved)
      File "/home/master/PycharmProjects/PROJECT/venv/lib/python3.10/site-packages/aiohttp/connector.py", line 874, in _resolve_host
        addrs = await self._resolver.resolve(host, port, family=self._family)
      File "/home/master/PycharmProjects/PROJECT/venv/lib/python3.10/site-packages/aiohttp/resolver.py", line 33, in resolve
        infos = await self._loop.getaddrinfo(
      File "/usr/lib/python3.10/asyncio/base_events.py", line 863, in getaddrinfo
        return await self.run_in_executor(
      File "/usr/lib/python3.10/concurrent/futures/thread.py", line 58, in run
        result = self.fn(*self.args, **self.kwargs)
      File "/usr/lib/python3.10/socket.py", line 955, in getaddrinfo
        for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
    socket.gaierror: [Errno -3] Temporary failure in name resolution
    
    The above exception was the direct cause of the following exception:
    
    Traceback (most recent call last):
      File "/home/master/PycharmProjects/PROJECT/main.py", line 43, in <module>
        loop.run_until_complete(main())
      File "/usr/lib/python3.10/asyncio/base_events.py", line 649, in run_until_complete
        return future.result()
      File "/home/master/PycharmProjects/PROJECT/main.py", line 35, in main
        await asyncio.gather(stream.live_kline(), interrupt_sys.listen(), display(memory))
      File "/home/master/PycharmProjects/PROJECT/kernel/market/stream.py", line 45, in live_kline
        await self.connect()
      File "/home/master/PycharmProjects/PROJECT/kernel/market/stream.py", line 21, in connect
        self.__client = await AsyncClient.create(self.config.system_api_public_key,
      File "/home/master/PycharmProjects/PROJECT/venv/lib/python3.10/site-packages/binance/client.py", line 7866, in create
        await self.ping()
      File "/home/master/PycharmProjects/PROJECT/venv/lib/python3.10/site-packages/binance/client.py", line 7988, in ping
        return await self._get('ping', version=self.PRIVATE_API_VERSION)
      File "/home/master/PycharmProjects/PROJECT/venv/lib/python3.10/site-packages/binance/client.py", line 7953, in _get
        return await self._request_api('get', path, signed, version, **kwargs)
      File "/home/master/PycharmProjects/PROJECT/venv/lib/python3.10/site-packages/binance/client.py", line 7916, in _request_api
        return await self._request(method, uri, signed, **kwargs)
      File "/home/master/PycharmProjects/PROJECT/venv/lib/python3.10/site-packages/binance/client.py", line 7897, in _request
        async with getattr(self.session, method)(uri, **kwargs) as response:
      File "/home/master/PycharmProjects/PROJECT/venv/lib/python3.10/site-packages/aiohttp/client.py", line 1141, in __aenter__
        self._resp = await self._coro
      File "/home/master/PycharmProjects/PROJECT/venv/lib/python3.10/site-packages/aiohttp/client.py", line 536, in _request
        conn = await self._connector.connect(
      File "/home/master/PycharmProjects/PROJECT/venv/lib/python3.10/site-packages/aiohttp/connector.py", line 540, in connect
        proto = await self._create_connection(req, traces, timeout)
      File "/home/master/PycharmProjects/PROJECT/venv/lib/python3.10/site-packages/aiohttp/connector.py", line 901, in _create_connection
        _, proto = await self._create_direct_connection(req, traces, timeout)
      File "/home/master/PycharmProjects/PROJECT/venv/lib/python3.10/site-packages/aiohttp/connector.py", line 1169, in _create_direct_connection
        raise ClientConnectorError(req.connection_key, exc) from exc
    aiohttp.client_exceptions.ClientConnectorError: Cannot connect to host api.binance.com:443 ssl:default [Temporary failure in name resolution]
    
    Process finished with exit code 1
    

    告诉我怎么回事——感觉“尝试除外”根本不起作用。或者是发生了什么我不明白的事情

    我该如何测试?我只是启动应用程序,然后关闭网卡1分钟以上,以模拟连接中断。

    import asyncio
    from binance import Client, AsyncClient, ThreadedWebsocketManager, ThreadedDepthCacheManager, BinanceSocketManager
    
    
    class Stream:
    
        def __init__(self):
            self.__ts = None
            self.__chanel_name = None
            self.__bsm = None
            self.__client = None
    
        async def connect(self):
            self.__client = await AsyncClient.create('','')
            self.__bsm = BinanceSocketManager(self.__client, 60)
            self.__chanel_name = 'btcusdt@kline_1m'
            self.__ts = self.__bsm.futures_multiplex_socket([self.__chanel_name])
    
        async def live_kline(self):
            while True:
                try:
                    async with self.__ts as tscm:
                        while True:
                            stream = await tscm.recv()
                            # Updates order statuses in real time
                            if stream['stream'] == self.__chanel_name:
                                Stream.process_message(stream)
                except Exception as e:
                    print(f"An error occurred: {e}. Reconnecting...")
                    await self.__client.close_connection()
                    await asyncio.sleep(1)
                    await self.connect()
                    continue
    
        @staticmethod
        def process_message(msg: dict):
    
            pass
    
    async def main():
        stream = Stream()
        await stream.connect()
        await asyncio.gather(stream.live_kline())
        loop.stop()
        
    if __name__ == '__main__':
        loop = asyncio.new_event_loop()
        loop.run_until_complete(main())
    
    1 回复  |  直到 2 年前
    推荐文章