tornado.py 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. import json
  2. from collections import OrderedDict
  3. import tornado
  4. import tornado.websocket
  5. from tornado.gen import coroutine
  6. from tornado.log import gen_log
  7. from wsrepl.framework import Task
  8. from wsrepl import project_dir
  9. STATIC_PATH = '%s/html' % project_dir
  10. def ws_handler(coro_func):
  11. class WSHandler(tornado.websocket.WebSocketHandler):
  12. def check_origin(self, origin):
  13. return True
  14. def get_compression_options(self):
  15. # Non-None enables compression with default options.
  16. return {}
  17. @coroutine
  18. def open(self):
  19. print("WebSocket opened")
  20. self.set_nodelay(True)
  21. ############
  22. self.coros = {} # coro_id -> coro
  23. # self.callbacks = OrderedDict() # UI元素时的回调, callback_id -> (coro, save)
  24. # self.mark2id = {} # mark_name -> mark_id
  25. self._closed = False
  26. self.inactive_coro_instances = [] # 待激活的协程实例列表
  27. self.main_task = Task(coro_func(), ws=self)
  28. self.coros[self.main_task.coro_id] = self.main_task
  29. self.step_task(self.main_task)
  30. def step_task(self, task, result=None):
  31. task.step(result)
  32. if task.task_finished:
  33. gen_log.debug('del self.coros[%s]', task.coro_id)
  34. del self.coros[task.coro_id]
  35. while self.inactive_coro_instances:
  36. coro = self.inactive_coro_instances.pop()
  37. task = Task(coro, ws=self)
  38. self.coros[task.coro_id] = task
  39. task.step()
  40. if self.coros[task.coro_id].task_finished:
  41. gen_log.debug('del self.coros[%s]', task.coro_id)
  42. del self.coros[task.coro_id]
  43. if self.main_task.task_finished:
  44. for t in self.coros:
  45. t.cancel()
  46. self.close()
  47. def on_message(self, message):
  48. # print('on_message', message)
  49. data = json.loads(message)
  50. coro_id = data['coro_id']
  51. coro = self.coros.get(coro_id)
  52. if not coro:
  53. gen_log.error('coro not found, coro_id:%s', coro_id)
  54. return
  55. self.step_task(coro, data)
  56. def on_close(self):
  57. self._closed = True
  58. print("WebSocket closed")
  59. def closed(self):
  60. return self._closed
  61. return WSHandler