async def _process_websocket_messages(self,
                                          websocket_assistant: WSAssistant,
                                          queue: asyncio.Queue):
        async for ws_response in websocket_assistant.iter_messages():
            data: Dict[str, Any] = ws_response.data
            decompressed_data = utils.decompress_ws_message(data)
            try:
                if type(decompressed_data) == str:
                    json_data = json.loads(decompressed_data)
                else:
                    json_data = decompressed_data
            except asyncio.CancelledError:
                raise
            except Exception:
                self.logger().warning(
                    f"Invalid event message received through the order book data source "
                    f"connection ({decompressed_data})")
                continue

            if "errorCode" in json_data or "errorMessage" in json_data:
                raise ValueError(
                    f"Error message received in the order book data source: {json_data}"
                )

            await self._process_event_message(event_message=json_data,
                                              queue=queue)
コード例 #2
0
 async def _inner_messages(
         self,
         ws: websockets.WebSocketClientProtocol) -> AsyncIterable[str]:
     try:
         while True:
             try:
                 msg: str = await asyncio.wait_for(
                     ws.recv(), timeout=self.MESSAGE_TIMEOUT)
                 msg = bitmart_utils.decompress_ws_message(msg)
                 yield msg
             except asyncio.TimeoutError:
                 pong_waiter = await ws.ping()
                 await asyncio.wait_for(pong_waiter,
                                        timeout=self.PING_TIMEOUT)
     except asyncio.TimeoutError:
         self.logger().warning(
             "WebSocket ping timed out. Going to reconnect...")
         return
     except websockets.exceptions.ConnectionClosed:
         return
     finally:
         await ws.close()
コード例 #3
0
    async def listen_for_order_book_diffs(self, ev_loop: asyncio.BaseEventLoop, output: asyncio.Queue):
        """
        Listen for orderbook diffs using websocket book channel(all messages are snapshots)
        """
        while True:
            try:
                ws: WSAssistant = await self._api_factory.get_ws_assistant()
                await ws.connect(ws_url=CONSTANTS.WSS_URL,
                                 message_timeout=self.MESSAGE_TIMEOUT,
                                 ping_timeout=self.PING_TIMEOUT)

                for trading_pair in self._trading_pairs:
                    ws_message: WSRequest = WSRequest({
                        "op": "subscribe",
                        "args": [f"spot/depth400:{convert_to_exchange_trading_pair(trading_pair)}"]
                    })
                    await ws.send(ws_message)

                while True:
                    try:
                        async for raw_msg in ws.iter_messages():
                            messages = decompress_ws_message(raw_msg.data)
                            if messages is None:
                                continue

                            messages = ujson.loads(messages)

                            if "errorCode" in messages.keys() or \
                               "data" not in messages.keys() or \
                               "table" not in messages.keys():
                                continue

                            if messages["table"] != "spot/depth5":
                                # Not an order book message
                                continue

                            for msg in messages["data"]:        # data is a list
                                msg_timestamp: float = float(msg["ms_t"])
                                t_pair = convert_from_exchange_trading_pair(msg["symbol"])

                                snapshot_msg: OrderBookMessage = BitmartOrderBook.snapshot_message_from_exchange(
                                    msg=msg,
                                    timestamp=msg_timestamp,
                                    metadata={"trading_pair": t_pair}
                                )
                                output.put_nowait(snapshot_msg)
                        break
                    except asyncio.exceptions.TimeoutError:
                        # Check whether connection is really dead
                        await ws.ping()
            except asyncio.CancelledError:
                raise
            except asyncio.exceptions.TimeoutError:
                self.logger().warning("WebSocket ping timed out. Going to reconnect...")
                await ws.disconnect()
                await asyncio.sleep(30.0)
            except Exception:
                self.logger().network(
                    "Unexpected error with WebSocket connection.",
                    exc_info=True,
                    app_warning_msg="Unexpected error with WebSocket connection. Retrying in 30 seconds. "
                                    "Check network connection."
                )
                await ws.disconnect()
                await self._sleep(30.0)
            finally:
                await ws.disconnect()