在Python

时间:2018-03-23 02:04:13

标签: python python-3.x asynchronous websocket async-await

我有一个订阅websocket流的异步函数。从这个函数将接收到的数据传递给程序的其他部分的最佳方法是什么?

下面是一个简短的示例代码。它将通过Bitfinex交换机上的websocket订阅BTCUSD和BTCETH对订单簿渠道,并将数据打印到stdout。我需要分配给message的数据,以便从程序的其他部分检索。

import json
import asyncio
import websockets

async def subscribe(ws_host, subscribe_request):
    async with websockets.connect(ws_host) as ws:
        request = json.dumps(subscribe_request)
        await ws.send(request)
        while True:
            try:
                message = await ws.recv()
                print(message)
            except websockets.exceptions.ConnectionClosed:
                print("Connection was closed")

if __name__ == '__main__':
    ws_host = 'wss://api.bitfinex.com/ws/2'
    subscribe_request_btc = dict( 
                            event='subscribe',
                            channel='book',
                            symbol='tBTCUSD',
                            prec='P0',
                            freq='F1',
                            len='25' 
                            )
    subscribe_request_eth = dict( 
                            event='subscribe',
                            channel='book',
                            symbol='tETHUSD',
                            prec='P0',
                            freq='F1',
                            len='25' 
                            )

    loop = asyncio.get_event_loop()
    tasks = [subscribe(ws_host, subscribe_request_btc), subscribe(ws_host, subscribe_request_eth)]
    loop.run_until_complete(asyncio.wait(tasks))
    loop.close()

1 个答案:

答案 0 :(得分:0)

这是我到目前为止所提出的。为每个websocket通道创建队列,启动一个监听websocket通道的守护程序线程并将消息写入适当的队列。主线程不断检查队列中是否有新值并将它们出列。

import json
import asyncio
import websockets
import queue
import threading

async def subscribe(ws_host, subscribe_request, q):
    async with websockets.connect(ws_host) as ws:
        request = json.dumps(subscribe_request)
        await ws.send(request)
        while True:
            try:
                message = await ws.recv()
                q.put(message)
            except websockets.exceptions.ConnectionClosed:
                print("Connection was closed")


if __name__ == '__main__':
    ws_host = 'wss://api.bitfinex.com/ws/2'
    subscribe_request_btc = dict( 
                            event='subscribe',
                            channel='book',
                            symbol='tBTCUSD',
                            prec='P0',
                            freq='F1',
                            len='25' 
                            )
    subscribe_request_eth = dict( 
                            event='subscribe',
                            channel='book',
                            symbol='tETHUSD',
                            prec='P0',
                            freq='F1',
                            len='25' 
                            )
    q_btc = queue.Queue()
    q_eth = queue.Queue()
    loop = asyncio.get_event_loop()
    tasks = [subscribe(ws_host, subscribe_request_btc, q_btc), subscribe(ws_host, subscribe_request_eth, q_eth)]
    t1 = threading.Thread(target=loop.run_until_complete, args=(asyncio.wait(tasks),), daemon=True)
    t1.start()
    while True:
        try:
            message_btc = q_btc.get(block=False)
            print('BTC channel: ', message_btc)
        except queue.Empty:
            pass
        try:
            message_eth = q_eth.get(block=False)
            print('ETH channel', message_eth)
        except queue.Empty:
            pass
    loop.close()

随意添加答案,显示更有效的方法。