我有一个机器学习功能,可以实时循环处理视频,如果算法发现视频有故障,我需要向前端发送通知,我正在使用Tornado Web和Python。我使用了Request-Handler和Websocket-Handler,但是该函数阻止服务器正常运行,因为它阻塞了循环。 所以我该如何在服务器中使用此功能。
class DataSource(object):
def __init__(self, initial_data=None):
self._data = initial_data
@property
def data(self):
return self._data
@data.setter
def data(self, new_data):
self._data = new_data
class EventSource(web.RequestHandler):
def initialize(self, source):
self.source = source
self._last = None
self.set_header('content-type', 'text/event-stream')
self.set_header('cache-control', 'no-cache')
@tornado.gen.coroutine
def publish(self, data):
try:
self.write('data: {}\n\n'.format(data))
yield self.flush()
except StreamClosedError:
pass
@tornado.gen.coroutine
def get(self):
while True:
if self.source.data != self._last:
yield self.publish(self.source.data)
self._last = self.source.data
else:
yield tornado.gen.sleep(0.005)
generator = processing.video_processing() #loop function (yields)
publisher = DataSource(next(generator))
def get_next():
publisher.data = next(generator)
print(publisher.data)
checker = PeriodicCallback(lambda: get_next(), 1000.)
checker.start()
class Application(tornado.web.Application):
def __init__(self):
handlers = [
tornado.web.url(r"/charts", ChartPageHandler, name="charts"),
tornado.web.url(r"/historique_images", HistoriqueImagesPageHandler, name="historique_images"),
tornado.web.url(r"/tables", TablePageHandler, name="tables"),
tornado.web.url(r"/streaming",StreamingPageHandler, name="streaming"),
tornado.web.url(r'/ws/', WebSocketHandler, name="websocket"),
tornado.web.url(r'/events', EventSource, dict(source=publisher)),
tornado.web.url(r'/ws_stream/', StreamSocketHandler, name="ws_stream"),
]
settings = dict(
template_path = os.path.join(os.path.dirname(__file__), "templates"),
static_path = os.path.join(os.path.dirname(__file__), "static"),
debug = True,
cookie_secret = "bZJc2sWbQLKos6GkHn/VB9oXwQt8S0R0kRvJ5/xJ89E=",
login_url = "/login",
xsrf_cookies = True,
)
super(Application, self).__init__(handlers, **settings)
if __name__ == "__main__":
options.parse_command_line()
app = Application()
server = HTTPServer(app)
server.listen(config.PORT)
signal.signal(signal.SIGINT, lambda x, y:IOLoop.instance().stop())
IOLoop.instance().start()