binance-connector-python
binance-connector-python copied to clipboard
SSL connection error when starting large number of streams (100s)
Using latest version (Nov 2023), I'm trying to start kline streams on 100 symbols, but I get SSL error
How can I safely achieve that?
from binance.websocket.spot.websocket_api import SpotWebsocketAPIClient
def message_handler(_, message):
logging.info(message)
my_client = SpotWebsocketAPIClient(on_message=message_handler)
my_client.ticker(symbol="BNBBUSD", type="FULL")
REPEAT ABOVE FOR 100 SYMBOLS:
File ~\code\crypto\src\crypto\exchange\binancelib\binance_sockets_connector.py:17, in start_kline_1m_sockets(symbols, msg_handler, action)
15 for a_symbol in tqdm(symbols, desc=f"Subscribing to {len(symbols)} symbols kline streams"):
16 time.sleep(0.05)
---> 17 my_client.kline(symbol=a_symbol, interval="1m", action=action)
File ~\venvs\cry\Lib\site-packages\binance_connector\websocket\spot\websocket_stream.py:95, in SpotWebsocketStreamClient.kline(self, symbol, interval, id, action)
66 """Kline/Candlestick Streams
67
68 The Kline/Candlestick Stream push updates to the current klines/candlestick every second.
(...)
91 Update Speed: 2000ms
92 """
93 stream_name = "{}@kline_{}".format(symbol.lower(), interval)
---> 95 self.send_message_to_server(stream_name, action=action, id=id)
File ~\venvs\cry\Lib\site-packages\binance_connector\websocket\websocket_client.py:88, in BinanceWebsocketClient.send_message_to_server(self, message, action, id)
85 id = get_timestamp()
87 if action != self.ACTION_UNSUBSCRIBE:
---> 88 return self.subscribe(message, id=id)
89 return self.unsubscribe(message, id=id)
File ~\venvs\cry\Lib\site-packages\binance_connector\websocket\websocket_client.py:97, in BinanceWebsocketClient.subscribe(self, stream, id)
95 stream = [stream]
96 json_msg = json.dumps({"method": "SUBSCRIBE", "params": stream, "id": id})
---> 97 self.socket_manager.send_message(json_msg)
File ~\venvs\cry\Lib\site-packages\binance_connector\websocket\binance_socket_manager.py:64, in BinanceSocketManager.send_message(self, message)
62 def send_message(self, message):
63 self.logger.debug("Sending message to Binance WebSocket Server: %s", message)
---> 64 self.ws.send(message)
File ~\venvs\cry\Lib\site-packages\websocket\_core.py:285, in WebSocket.send(self, payload, opcode)
271 """
272 Send the data as string.
273
(...)
281 Operation code (opcode) to send.
282 """
284 frame = ABNF.create_frame(payload, opcode)
--> 285 return self.send_frame(frame)
File ~\venvs\cry\Lib\site-packages\websocket\_core.py:313, in WebSocket.send_frame(self, frame)
311 with self.lock:
312 while data:
--> 313 l = self._send(data)
314 data = data[l:]
316 return length
File ~\venvs\cry\Lib\site-packages\websocket\_core.py:527, in WebSocket._send(self, data)
526 def _send(self, data: Union[str, bytes]):
--> 527 return send(self.sock, data)
File ~\venvs\cry\Lib\site-packages\websocket\_socket.py:172, in send(sock, data)
170 return sock.send(data)
171 else:
--> 172 return _send()
173 except socket.timeout as e:
174 message = extract_err_message(e)
File ~\venvs\cry\Lib\site-packages\websocket\_socket.py:149, in send.<locals>._send()
147 def _send():
148 try:
--> 149 return sock.send(data)
150 except SSLWantWriteError:
151 pass
File ~\AppData\Local\Programs\Python\Python311\Lib\ssl.py:1243, in SSLSocket.send(self, data, flags)
1239 if flags != 0:
1240 raise ValueError(
1241 "non-zero flags not allowed in calls to send() on %s" %
1242 self.__class__)
-> 1243 return self._sslobj.write(data)
1244 else:
1245 return super().send(data, flags)
SSLEOFError: EOF occurred in violation of protocol (_ssl.c:2427)
The API lacks ! for all klines (as is the case with tickers and minitickers).
The connector itself follows through on this deficiency.
I'm not sure what is the advantage of is_combined argument if all it accepts is one symbol input.
@mathematician02 The code you provided is related to the WebSocket API client, but the error appears to be linked to the WebSocket Stream client.
If you want to run multiple klines with the WebSocket Stream client, I suggest you check out this file: https://github.com/binance/binance-connector-python/blob/master/examples/websocket/spot/websocket_stream/combined_streams.py
To add new klines to the stream, simply add the following format to the array: <symbol>@kline_<interval>. For more details, refer to the Binance Kline/Candlestick Streams documentation.