I made a python script that fetches and manages a local orderbook from Binance for both SPOT and Futures and it works fine.
The problem though is that after 24h the websocket is being disconnected. This is a huge problem, because upon reconnecting to the websocket i miss some updates to the orderbook that occurred during this time. If i fetch the depth snapshot from scratch and reconnect to the websocket, then i have lost the entire orderbook , because unfortunately the only way to get it fully is by let it run for some time.
I have searched everywhere how to handle this type of problem and did not find anything. All solutions are not taking this into account.
To address the problem of websocket disconnections after 24 hours and potentially missing updates, the key is to implement a controlled reconnection strategy and possibly synchronize the order book immediately after reconnection. Here’s a simplified and generalized strategy along with an example code snippet:
Strategy:
Pre-emptive Disconnection: Instead of waiting for the server to disconnect after 24 hours, proactively disconnect and reconnect the websocket at a set interval slightly before this limit.
Order Book Sync: Upon reconnection, immediately synchronize the order book. Consider using Binance’s REST API to fetch the latest snapshot of the order book and then continue receiving updates via the websocket.
Keep-Alive Mechanism: Send regular ping messages or use Binance’s method to keep the websocket alive and check its connectivity.
Generalized Code:
Here’s how you could implement a simplified version of the websocket management with planned disconnection and reconnection:
[ If you can share more specifics about how you handle the order book and manage API keys without revealing sensitive information, I can try to tailor the solution further.]
async def manage_websocket_connection(websocket):
while True:
try:
message = await asyncio.wait_for(websocket.recv(), timeout=60) # Receive messages
print(“Received message:”, message)
except asyncio.TimeoutError:
logging.warning(“No message received in the last 60 seconds. Sending ping…”)
pong_waiter = await websocket.ping()
await asyncio.wait_for(pong_waiter, timeout=10)
logging.info(“Ping successful, connection still alive.”)
async def main(client):
while True:
try:
await connect_websocket(client)
except websockets.exceptions.ConnectionClosed:
logging.error(“Connection closed, reconnecting…”)
finally:
# Delete listen key and wait before reconnecting
listen_key = ‘your_listen_key’ # This should be handled better in actual use
await delete_listen_key(client, listen_key)
logging.info(“Sleeping before reconnecting…”)
await asyncio.sleep(RECONNECTION_INTERVAL)
Dummy client object, replace with actual Binance client
client = None
asyncio.run(main(client))
Explanation:
connect_websocket: Establishes a websocket connection and subscribes to a stream.
manage_websocket_connection: Handles messages from the websocket and sends pings if no messages are received within 60 seconds.
main: Handles the reconnection logic and cycles the websocket connection every 23 hours.
Next Steps:
You should replace the dummy functions create_listen_key and delete_listen_key with actual implementations using the Binance API.
Handle the listen key and API details securely and ensure error handling is robust to manage edge cases.
This code provides a foundation to customize based on specific requirements, like managing order book updates and handling API switching logic.
Well if it helps you, this is my generalized code but I have additional modifications to the code which is API rotation, multi parallel connection after certain time interval to receive kline and fail safe for stale Kline and detection… now all these if I put here, chances are you will be overwhelmed (no intention to undermine your capabilities) but given the problem you have asked is quite well know rule of Binance websocket… so a generalized code!