Skip to main content
 首页 » 编程设计

python之多线程 websocket 客户端无法正常退出

2025年05月04日43arxive

我编写了一个多线程 web-socket 客户端类,这样用户的(主)线程就不会阻塞 run_forever() 方法调用。代码似乎工作正常,除了最后,当我停止线程时,它不会干净地关闭网络套接字并且我的进程不会退出。我每次都必须执行 kill -9 才能摆脱它。我尝试调用线程的 join() 方法来确保主线程等待子线程完成其执行,但这没有帮助。

代码如下所示。你能帮我优雅地退出/停止线程吗?

import thread 
import threading 
import time 
import websocket 
 
class WebSocketClient(threading.Thread): 
 
    def __init__(self, url): 
        self.url = url 
        threading.Thread.__init__(self) 
 
    def run(self): 
 
        # Running the run_forever() in a seperate thread. 
        #websocket.enableTrace(True) 
        self.ws = websocket.WebSocketApp(self.url, 
                                         on_message = self.on_message, 
                                         on_error = self.on_error, 
                                         on_close = self.on_close) 
        self.ws.on_open = self.on_open 
        self.ws.run_forever() 
 
    def send(self, data): 
 
        # Wait till websocket is connected. 
        while not self.ws.sock.connected: 
            time.sleep(0.25) 
 
        print 'Sending data...', data 
        self.ws.send("Hello %s" % data) 
 
    def stop(self): 
        print 'Stopping the websocket...' 
        self.ws.keep_running = False 
 
    def on_message(self, ws, message): 
        print 'Received data...', message 
 
    def on_error(self, ws, error): 
        print 'Received error...' 
        print error 
 
    def on_close(self, ws): 
        print 'Closed the connection...' 
 
    def on_open(self, ws): 
        print 'Opened the connection...' 
 
if __name__ == "__main__": 
 
    wsCli = WebSocketClient("ws://localhost:8888/ws") 
    wsCli.start() 
    wsCli.send('Hello') 
    time.sleep(.1) 
    wsCli.send('World') 
    time.sleep(1) 
    wsCli.stop() 
    #wsCli.join() 
    print 'After closing client...' 

请您参考如下方法:

总结通过我们在评论中的扩展讨论发现的解决方案(并让您有机会接受并赞成我的回答。;-)

要解决此问题,您需要在 WebSocketClient 类的 stop() 方法中调用 self.ws.close() 而不是仅仅设置 self.ws.keep_running = False。这样网络套接字将被干净地关闭。

我还建议您将线程的 daemon 属性设置为 True,这样当主线程因任何原因终止时线程将自动停止——以防出现完全意外的情况发生了。