【问题标题】:Threaded, non-blocking websocket client线程化、非阻塞的 websocket 客户端
【发布时间】:2015-05-22 14:49:22
【问题描述】:

我想在 Python 中运行一个程序,每秒通过网络套接字向 Tornado 服务器发送一条消息。我一直在使用 websocket-client 上的示例;

这个例子不起作用,因为ws.run_forever()会停止while循环的执行。

谁能给我一个示例,说明如何正确地将其实现为一个线程类,我既可以调用它的发送方法,也可以接收消息?

import websocket
import thread
import time

def on_message(ws, message):
    print message

def on_error(ws, error):
    print error

def on_close(ws):
    print "### closed ###"

def on_open(ws):
    pass

if __name__ == "__main__":
    websocket.enableTrace(True)
    ws = websocket.WebSocketApp("ws://echo.websocket.org/", on_message = on_message, on_error = on_error, on_close = on_close)
    ws.on_open = on_open
    ws.run_forever()

    while True:
        #do other actions here... collect data etc.
        for i in range(100):
            time.sleep(1)
            ws.send("Hello %d" % i)
        time.sleep(1)

【问题讨论】:

    标签: python multithreading websocket


    【解决方案1】:

    在他们的github page 中有一个例子就是这样做的。似乎您从该示例开始,并从 on_open 中获取每秒发送消息的代码并将其粘贴在 run_forever 调用之后,BTW 一直运行到套接字已断开连接。

    也许您对这里的基本概念有疑问。总会有一个线程专门用于监听套接字(在这种情况下,主线程进入 run_forever 内的循环等待消息)。如果您想进行其他操作,则需要另一个线程。

    下面是他们的示例代码的不同版本,其中没有使用主线程作为“套接字侦听器”,而是创建了另一个线程,run_forever 在那里运行。我认为它有点复杂,因为您必须编写代码以确保套接字已连接,而您可以使用 on_open 回调,但也许它会帮助您理解。

    import websocket
    import threading
    from time import sleep
    
    def on_message(ws, message):
        print message
    
    def on_close(ws):
        print "### closed ###"
    
    if __name__ == "__main__":
        websocket.enableTrace(True)
        ws = websocket.WebSocketApp("ws://echo.websocket.org/", on_message = on_message, on_close = on_close)
        wst = threading.Thread(target=ws.run_forever)
        wst.daemon = True
        wst.start()
    
        conn_timeout = 5
        while not ws.sock.connected and conn_timeout:
            sleep(1)
            conn_timeout -= 1
    
        msg_counter = 0
        while ws.sock.connected:
            ws.send('Hello world %d'%msg_counter)
            sleep(1)
            msg_counter += 1
    

    【讨论】:

    • 整个服务器然后运行在一个线程中?如果这个线程饱和了怎么办?
    • @Paul:这里的“饱和”是什么意思?
    • 我的意思是,如果它使用多个线程,它每秒可以处理更多的数据。使用一个线程,我觉得您并没有使用整个 CPU,并且该线程可能会相对较快地被数据淹没。
    • @Paul - 在不涉及等待的情况下,线程不会提高效率;归根结底,GIL 确保您仍在运行一个线程
    • python 绝对不是多线程的。如果你想处理大量的连接,你应该使用 asyncio 和 multiprocessing 将消息传递给其他完成工作的进程。当您想将结果返回给客户端时,您可以将其填充到回复队列中,该队列被主异步进程拾取并返回
    猜你喜欢
    • 2015-07-04
    • 2014-11-26
    • 1970-01-01
    • 1970-01-01
    • 2017-04-18
    • 2019-09-20
    • 2017-01-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多