简体   繁体   中英

python - handle tornado connections into while loop

I have a server running a loop that reads data from a device and I want to send them to all clients who connect on a websocket on tornado. I tried putting the loop inside the open function but then it can't handle on_close function or new connections.

What is best practice to do that?

#!/usr/bin/env python

import tornado.httpserver
import tornado.websocket
import tornado.ioloop
import tornado.web
import socket

class MyWebSocketServer(tornado.websocket.WebSocketHandler):
    def open(self):
        print('new connection'+self.request.remote_ip)
        try:
            while True:
                '''
                read and send data
                '''
        except Exception,error:
            print "Error on Main: "+str(error)

    def on_close(self):
        print('connection closed'+self.request.remote_ip)

application=tornado.web.Application([(r'/ws',MyWebSocketServer),])

if __name__=="__main__":
    http_server = tornado.httpserver.HTTPServer(application)
    http_server.listen(8000)
    print('start')
    tornado.ioloop.IOLoop.instance().start()

Thanks

Here's a full example about running your blocking code in a separate thread and broadcasting messages to all connected clients.

...

from concurrent.futures import ThreadPoolExecutor

executor = ThreadPoolExecutor(max_workers=1) # spawn only 1 thread


class MyWebSocketServer(tornado.websocket.WebSocketHandler):
    connections = set() # create a set to hold connections

    def open(self):
        # put the new connection in connections set
        self.connections.add(self)

    def on_close(self):
        print('connection closed'+self.request.remote_ip)
        print('new connection'+self.request.remote_ip)
        # remove client from connections
        self.connections.remove(self)

    @classmethod
    def send_message(cls, msg):
        for client in cls.connections:
            client.write_message(msg)


def read_from_serial(loop, msg_callback):
    """This function will read from serial 
    and will run in aseparate thread

    `loop` is the IOLoop instance
    `msg_allback` is the function that will be 
    called when new data is available from usb
    """
    while True:
        # your code ...
        # ...
        # when you get new data
        # tell the IOLoop to schedule `msg_callback`
        # to send the data to all clients

        data = "new data"
        loop.add_callback(msg_callback, data)

...

if __name__ == '__main__':
    loop = tornado.ioloop.IOLoop.current()

    msg_callback = MyWebSocketServer.send_message

    # run `read_from_serial` in another thread
    executor.submit(read_from_serial, loop, msg_callback)

    ...

    loop.start()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM