【问题标题】:Correct use of streamz with websocket正确使用 streamz 和 websocket
【发布时间】:2021-03-21 17:38:04
【问题描述】:

我正在尝试找出使用streamz 处理流数据的正确方法。我的流数据是使用websocket-client 加载的,之后我这样做:

# open a stream and push updates into the stream
stream = Stream()

# establish a connection
ws = create_connection("ws://localhost:8765")

# get continuous updates
from tornado import gen
from tornado.ioloop import IOLoop

async def f():
    while True:
        await gen.sleep(0.001)
        data = ws.recv()
        stream.emit(data)
        
IOLoop.current().add_callback(f)

虽然这可行,但我发现我的流无法跟上流数据的速度(因此我在流中看到的数据比流数据落后几秒钟,这既是高容量又是高频率的数据)。我尝试将gen.sleep(0.001) 设置为较小的值(删除它会完全停止 jupyter 实验室),但问题仍然存在。

这是使用 websocket 连接 streamz 和流数据的正确方法吗?

【问题讨论】:

    标签: websocket tornado streamz


    【解决方案1】:

    我不认为 websocket-client 提供异步 API,因此它会阻塞事件循环。

    您应该使用异步 websocket 客户端,例如 Tornado provides

    from tornado.websocket import websocket_connect
    
    ws = websocket_connect("ws://localhost:8765")
    
    async def f():
        while True:
            data = await ws.read_message()
    
            if data is None:
                break
            else:
                await stream.emit(data)
    
            # considering you're receiving data from a localhost
            # socket, it will be really fast, and the `await` 
            # statement above won't pause the while-loop for 
            # enough time for the event loop to have chance to 
            # run other things.
            # Therefore, sleep for a small time to suspend the 
            # while-loop.
    
            await gen.sleep(0.0001) 
    

    如果您正在从/向远程连接接收/发送数据,那么您不需要休眠,因为远程连接的速度足以在 await 语句处暂停 while 循环。

    【讨论】:

    • 非常感谢,只是为了澄清您对sleep 的评论,这只是在jupyter lab 中运行它的问题,对吧?如果我在一个没有其他任何事情发生的独立脚本中运行它,那么循环中就没有其他事件,所以不需要睡眠?
    猜你喜欢
    • 2018-06-18
    • 2020-09-17
    • 2019-12-12
    • 1970-01-01
    • 2022-08-14
    • 2012-02-17
    • 2017-10-20
    • 2017-08-21
    • 2011-06-16
    相关资源
    最近更新 更多