Сode exits after unsubscribing

This code establishes a WebSocket connection to the Binance streaming API and listens for messages. The code uses the websocket library and the json module.

The code defines several functions:

  1. on_message_fiat: This function is called when a message is received through the WebSocket connection. It parses the JSON message, extracts relevant information, and performs certain actions based on the content of the message.
  2. on_open: This function is called when the WebSocket connection is established. It sends a subscribe request to the Binance API for a list of symbol pairs.
  3. on_close: This function is called when the WebSocket connection is closed. It cancels the subscription for the specified symbol pairs.

The main part of the code initializes a dictionary l_ST_symbol_pair containing symbol pairs and their corresponding status and parameters. It then constructs a WebSocket URL using the symbol pairs with a specific format and creates a WebSocket connection using the WebSocketApp class from the websocket library. Finally, it runs the WebSocket connection indefinitely, continuously receiving and handling messages from the Binance API.

import websocket
import json

def on_message_fiat(wss, message, l_ST_symbol_pair):
    pars = json.loads(message)
    name_pair = pars['stream'].split("@d")[0].upper()
    if l_ST_symbol_pair[name_pair][1] == 'start':

        for key, value in l_ST_symbol_pair.items():
            if value[1] != 'start':
                if value[3].get(name_pair) is not None:
                    value[3][name_pair] = True

        filtered_keys = [key for key, value in l_ST_symbol_pair.items() if all(v == True for v in value[3].values()) and value[1] != 'start']
        if len(filtered_keys) > 0:
            on_open(wss, filtered_keys)

    if l_ST_symbol_pair[name_pair][1] == '2_SA':
        l_ST_symbol_pair[name_pair] = (False,l_ST_symbol_pair[name_pair][1], l_ST_symbol_pair[name_pair][2], {key: False for key, val in l_ST_symbol_pair[name_pair][3].items()})
        on_close(wss, [name_pair])

def on_open(ws, spisok):
    params = {"method": "SUBSCRIBE", "params": [item.lower() + '@depth10@1000ms' for item in spisok], "id": 1}
    ws.send(json.dumps(params))

def on_close(ws, spisok):
    print('cancel_task'+' '+spisok[0])
    params = {"method": "UNSUBSCRIBE", "params": [item.lower() + '@depth10@1000ms' for item in spisok], "id": 1}
    ws.send(json.dumps(params))

if __name__ == "__main__":
    l_ST_symbol_pair = {'ETHBTC':(False, '2_SA', None, {'BTCAUD': False, 'ETHAUD': False}),
'BNBBTC':(False, '2_SA', None, {'BTCAUD': False, 'BNBAUD': False}),
'BNBETH':(False, '2_SA', None, {'ETHAUD': False, 'BNBAUD': False}),
'BTCUSDT':(False, '2_SA', None, {'BTCAUD': False, 'AUDUSDT': False}),
'ETHUSDT':(False, '2_SA', None, {'ETHAUD': False, 'AUDUSDT': False}),
'XRPBTC':(False, '2_SA', None, {'BTCAUD': False, 'XRPAUD': False}),
'XRPETH':(False, '2_SA', None, {'ETHAUD': False, 'XRPAUD': False}),
'BNBUSDT':(False, '2_SA', None, {'BNBAUD': False, 'AUDUSDT': False}),
'ADABTC':(False, '2_SA', None, {'BTCAUD': False, 'ADAAUD': False}),
'ADAETH':(False, '2_SA', None, {'ETHAUD': False, 'ADAAUD': False}),
'ADAUSDT':(False, '2_SA', None, {'AUDUSDT': False, 'ADAAUD': False}),
'ADABNB':(False, '2_SA', None, {'BNBAUD': False, 'ADAAUD': False}),
'XRPUSDT':(False, '2_SA', None, {'XRPAUD': False, 'AUDUSDT': False}),
'XRPBNB':(False, '2_SA', None, {'XRPAUD': False, 'BNBAUD': False}),
'DOGEBTC':(False, '2_SA', None, {'BTCAUD': False, 'DOGEAUD': False}),
'DOGEUSDT':(False, '2_SA', None, {'AUDUSDT': False, 'DOGEAUD': False}),
'BNBBUSD':(False, '2_SA', None, {'AUDBUSD': False, 'BNBAUD': False}),
'BTCBUSD':(False, '2_SA', None, {'BTCAUD': False, 'AUDBUSD': False}),
'BUSDUSDT':(False, '2_SA', None, {'AUDBUSD': False, 'AUDUSDT': False}),
'XRPBUSD':(False, '2_SA', None, {'AUDBUSD': False, 'XRPAUD': False}),
'ETHBUSD':(False, '2_SA', None, {'ETHAUD': False, 'AUDBUSD': False}),
'ADABUSD':(False, '2_SA', None, {'AUDBUSD': False, 'ADAAUD': False}),
'BUSDTRY':(False, '1_SA', 'nic', {'AUDBUSD': False}),
'EURBUSD':(False, '1_SA', 'nic', {'AUDBUSD': False}),
'GBPBUSD':(False, '1_SA', 'nic', {'AUDBUSD': False}),
'DOGEBUSD':(False, '2_SA', None, {'AUDBUSD': False, 'DOGEAUD': False}),
'BTCAUD':(False, 'start', None, {}),
'ETHAUD':(False, 'start', None, {}),
'AUDBUSD':(False, 'start', None, {}),
'XRPAUD':(False, 'start', None, {}),
'BNBAUD':(False, 'start', None, {}),
'AUDUSDT':(False, 'start', None, {}),
'DOGEAUD':(False, 'start', None, {}),
'ADAAUD':(False, 'start', None, {})}
    
    wss_url = 'wss://stream.binance.com:9443/stream?streams=%s' % ['/'.join(key.lower() + '@depth10@1000ms' for key,value in l_ST_symbol_pair.items() if value[1] == 'start')][0]
    wss = websocket.WebSocketApp(wss_url,on_message=lambda wss, message: on_message_fiat(wss, message, l_ST_symbol_pair))
    wss.run_forever()

When on_close is called, it is expecting that the connection is already not healthy or disconnected, then calling ws.send may not success. So you can UNSUBSCRIBE when ws has the connection, then you can exist the app.

Thanks for your reply. if you remove the unsubscribe code, there is a 20% chance that the code will be executed within a second. If the code runs and runs for more than a second, then everything will continue to work. What could be the reason for this behavior, and how to bring the probability of complete code operation to 100% ?