python-binance icon indicating copy to clipboard operation
python-binance copied to clipboard

Correct way to handle multiple socket messages?

Open cverwey opened this issue 4 years ago • 4 comments

import asyncio

from binance import AsyncClient, BinanceSocketManager


async def trade_handler(res):
    print(f'Do something with trade socket: {res}')


async def trade_listener(bsm):
    async with bsm.trade_socket('BNBBTC') as stream:
        while True:
            res = await stream.recv()
            await trade_handler(res)


async def kline_handler(res):
    print(f'Do something with kline socket: {res}')


async def kline_listener(bsm):
    async with bsm.kline_socket('BNBBTC', interval=AsyncClient.KLINE_INTERVAL_1MINUTE) as stream:
        while True:
            res = await stream.recv()
            await kline_handler(res)


async def main():
    client = await AsyncClient.create()
    bsm = BinanceSocketManager(client)

    await asyncio.gather(
        trade_listener(bsm),
        kline_listener(bsm),
    )


if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())

I'm very new to asyncio coding, but after scouring the web for an entire day this is the only way I could come up with to receive both streams at the same time via the gather method.

Is this the best way to do it? Any advise on code improvements would be appreciated.

cverwey avatar May 19 '21 18:05 cverwey

Recently I started to develop with this library and here is what I found: Because Binance support Multiplex Socket, IMO the efficient way to handle your case is to use this feature to get all data over 1 connection stream. There is a method which you can use to get combined data (Multiplex Socket) over 1 socket connection read here to understand how to use it. in short you should just pass array of stream keywords:


from binance import AsyncClient, BinanceSocketManager


async def getAllData(bsm):
    async with bsm.multiplex_socket(['bnbbtc@trade','bnbbtc@kline_1m']) as stream:
        while True:
            res = await stream.recv()
            print(res)

I hope it help

async def main():
    client = await AsyncClient.create()
    bsm = BinanceSocketManager(client)
    
    await asyncio.gather(getAllData(bsm))

if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())

I hope it helps.

rezaghazeli avatar May 19 '21 19:05 rezaghazeli

@Twister7 This does not work for user stream though right? Any idea how I can listen simultaneously to marketdata streams and user streams? I need to listen to the orderbook while checking if my order is filled at the same time

Karlheinzniebuhr avatar Mar 30 '22 14:03 Karlheinzniebuhr

@Karlheinzniebuhr I have the same issue!

AIvashka avatar May 18 '22 21:05 AIvashka

@Karlheinzniebuhr I have the same issue!

I found a solution among the closed issues. Can't find it now to link it

Karlheinzniebuhr avatar May 23 '22 18:05 Karlheinzniebuhr