Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/347.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python-将tornado连接处理到while循环中_Python_Loops_Websocket_Tornado - Fatal编程技术网

python-将tornado连接处理到while循环中

python-将tornado连接处理到while循环中,python,loops,websocket,tornado,Python,Loops,Websocket,Tornado,我有一个服务器运行一个从设备读取数据的循环,我想把它们发送给所有连接到tornado上websocket的客户端。 我试着把循环放在open函数中,但是它不能处理on_close函数或新的连接 这样做的最佳实践是什么 #!/usr/bin/env python import tornado.httpserver import tornado.websocket import tornado.ioloop import tornado.web import socket class MyWeb

我有一个服务器运行一个从设备读取数据的循环,我想把它们发送给所有连接到tornado上websocket的客户端。 我试着把循环放在open函数中,但是它不能处理on_close函数或新的连接

这样做的最佳实践是什么

#!/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()

谢谢

这里有一个完整的示例,介绍如何在单独的线程中运行阻塞代码,并向所有连接的客户端广播消息

...

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()

阅读时不需要
,只需在消息
上添加另一个功能
。查看官方文档:我知道on_消息功能,但在while循环中,我从设备读取数据,需要通过websocket发送。您如何读取while循环中的数据?似乎该代码正在阻止服务器。在while循环中,有一个代码可以连续从通过USB连接到串行IC的设备读取数据。我需要while循环,因为我需要以大约50Hz@Miky是的,
循环中的代码正在阻塞服务器,即当服务器开始运行时,其他任何东西都无法运行。尝试在使用
ThreadPoolExecutor
的单独线程中运行
循环。几个问题:1)为什么要循环
连接而不是使用
self。编写消息(msg)
?2)我如何才能用键盘中断线程?@Miky 1)如果你只做
self.write_message
,它只会将消息写入当前客户端。在你的问题中,你说你想将消息发送给所有连接的客户端,这就是为什么我循环使用
连接
。2) 如果键盘中断,整个过程将停止-Tornado服务器以及线程
执行器
。如果您只想停止线程
executor
,您可以捕获
键盘中断
异常并使用
executor.shutdown()
,它将停止线程。如果我想添加线程,例如定期监视cpu温度?@Miky So添加线程。我不明白这有什么混淆。所以我只需要设置
max\u workers=2
并添加
executor.submit(监控cpu温度、循环、消息回调)
来运行函数并能够通过ws发送数据,对吗?