多线程websocket客户端无法正确退出

2024-09-29 22:22:07 发布

您现在位置:Python中文网/ 问答频道 /正文

我编写了一个多线程websocket客户机类,这样用户的(主)线程不会阻塞run_forever()方法调用。代码似乎运行得很好,除了最后,当我停止线程时,它没有干净地关闭web套接字,我的进程也不会退出。我每次都得做一个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...'

Tags: runimportselfurlmessagedatawstime
1条回答
网友
1楼 · 发布于 2024-09-29 22:22:07

在评论中总结我们通过扩展讨论发现的解决方案(并给你一个机会接受并投票支持我的答案)。;-)

要解决这个问题,您需要调用WebSocketClientstop()方法中的self.ws.close(),而不是仅仅设置self.ws.keep_running = False。这样,web套接字将被完全关闭。在

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

相关问题 更多 >

    热门问题