123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 |
- import tornado.websocket
- import time, json
- from collections import defaultdict, OrderedDict
- from .framework import Global, Msg, Task
- from os.path import abspath, dirname
- from tornado.web import StaticFileHandler
- from tornado.gen import coroutine, sleep
- from tornado.log import gen_log
- import logging
- project_dir = dirname(abspath(__file__))
- def start_ioloop(coro_func, port=8080):
- class EchoWebSocket(tornado.websocket.WebSocketHandler):
- def check_origin(self, origin):
- return True
- def get_compression_options(self):
- # Non-None enables compression with default options.
- return {}
- @coroutine
- def open(self):
- print("WebSocket opened")
- self.set_nodelay(True)
- ############
- self.coros = {} # coro_id -> coro
- self.callbacks = OrderedDict() # UI元素时的回调, key -> callback, mark_id
- self.mark2id = {} # mark_name -> mark_id
- self._closed = False
- self.inactive_coro_instances = [] # 待激活的协程实例列表
- self.main_task = Task(coro_func(), ws=self)
- self.coros[self.main_task.coro_id] = self.main_task
- self.step_task(self.main_task)
- def step_task(self, task, result=None):
- task.step(result)
- if task.task_finished:
- gen_log.debug('del self.coros[%s]', task.coro_id)
- del self.coros[task.coro_id]
- while self.inactive_coro_instances:
- coro = self.inactive_coro_instances.pop()
- task = Task(coro, ws=self)
- self.coros[task.coro_id] = task
- task.step()
- if self.coros[task.coro_id].task_finished:
- gen_log.debug('del self.coros[%s]', task.coro_id)
- del self.coros[task.coro_id]
- if self.main_task.task_finished:
- for t in self.coros:
- t.cancel()
- self.close()
- def on_message(self, message):
- print('on_message', message)
- # { event:, coro_id:, data: }
- data = json.loads(message)
- coro_id = data['coro_id']
- coro = self.coros.get(coro_id)
- if not coro_id:
- gen_log.error('coro not found, coro_id:%s', coro_id)
- return
- self.step_task(coro, data)
- def on_close(self):
- self._closed = True
- print("WebSocket closed")
- def closed(self):
- return self._closed
- handlers = [(r"/test", EchoWebSocket),
- (r"/(.*)", StaticFileHandler,
- {"path": '%s/html/' % project_dir,
- 'default_filename': 'index.html'})]
- gen_log.setLevel(logging.DEBUG)
- app = tornado.web.Application(handlers=handlers, debug=True)
- http_server = tornado.httpserver.HTTPServer(app)
- http_server.listen(port)
- print('Open http://localhost:%s/ in Web browser' % port)
- tornado.ioloop.IOLoop.instance().start()
|