Multithreaded websocket client does not exit properly
<p>I wrote a multithreaded web-socket client class so that the user's (main) thread does not blocks on the <code>run_forever()</code> method call. The code seems to work fine, except in the end, when I am stopping the thread, it does not close the web-socket cleanly and my process does not exit. I have to do a <code>kill -9</code> each time to get rid of it. I tried calling the thread's <code>join()</code> method to make sure the main thread waits for the the child to complete its execution, but that did not help.</p>

<p>The code looks like below. Can you please help me make the exit/stopping of the thread graceful?</p>

<pre><code>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...'
</code></pre>