瀏覽代碼

实现 2/7

wangweimin 5 年之前
父節點
當前提交
b03be6eaac
共有 6 個文件被更改,包括 40 次插入52 次删除
  1. 4 1
      doc/log.md
  2. 4 1
      doc/表单交互.md
  3. 6 5
      test.py
  4. 2 14
      wsrepl/framework.py
  5. 5 16
      wsrepl/interact.py
  6. 19 15
      wsrepl/ioloop.py

+ 4 - 1
doc/log.md

@@ -7,4 +7,7 @@
 
 
 设计哲学:下区,阻塞等待回应区,同步交互,栈式结构;上区,瀑布流UI区,通过回调函数交互。
 设计哲学:下区,阻塞等待回应区,同步交互,栈式结构;上区,瀑布流UI区,通过回调函数交互。
 
 
-
+2/8
+需要 msg_id,  或者说是 coro_id/thread_id
+每个ws连接维护一个coros字典,每次根据消息的coro_id判断进入哪一个coro;前端维护form字典,根据指令coro_id判断作用于哪一个表单,并将其置顶。
+触发上区的一些事件回调时,产生新的coro;前端当前表单未提交成功又来新表单时,当前表单隐藏,显示新表单

+ 4 - 1
doc/表单交互.md

@@ -10,5 +10,8 @@ onblur:
     
     
 >>>
 >>>
 
 
-    
+
+
+<<< 
+callback:
     
     

+ 6 - 5
test.py

@@ -3,9 +3,10 @@ from tornado.ioloop import IOLoop
 from tornado import websocket
 from tornado import websocket
 import json
 import json
 
 
-
 from wsrepl.ioloop import start_ioloop
 from wsrepl.ioloop import start_ioloop
 from wsrepl.interact import *
 from wsrepl.interact import *
+from tornado.gen import sleep
+
 
 
 # 业务逻辑 协程
 # 业务逻辑 协程
 def say_hello():
 def say_hello():
@@ -14,6 +15,10 @@ def say_hello():
     name = yield from text_input_coro('input your name')
     name = yield from text_input_coro('input your name')
     text_print("Hello %s!" % name)
     text_print("Hello %s!" % name)
 
 
+    for i in range(3):
+        yield sleep(1)
+        text_print("%s" % i)
+
     age = yield from text_input_coro('input your age')
     age = yield from text_input_coro('input your age')
     if int(age) < 30:
     if int(age) < 30:
         text_print("Wow. So young!!")
         text_print("Wow. So young!!")
@@ -21,8 +26,4 @@ def say_hello():
         text_print("Old man~")
         text_print("Old man~")
 
 
 
 
-
 start_ioloop(say_hello)
 start_ioloop(say_hello)
-
-
-

+ 2 - 14
wsrepl/framework.py

@@ -4,22 +4,10 @@ from collections import defaultdict
 
 
 
 
 class Future:
 class Future:
-    def __init__(self):
-        self.result = None
-        self._callbacks = []
-
-    def add_done_callback(self, fn):
-        # todo Future已完成时,立即回调fn
-        self._callbacks.append(fn)
-
-    def set_result(self, result):
-        self.result = result
-        for fn in self._callbacks:
-            fn(self)
 
 
     def __iter__(self):
     def __iter__(self):
-        yield self
-        return self.result
+        result = yield
+        return result
 
 
     __await__ = __iter__  # make compatible with 'await' expression
     __await__ = __iter__  # make compatible with 'await' expression
 
 

+ 5 - 16
wsrepl/interact.py

@@ -4,31 +4,20 @@ from collections import defaultdict
 from .framework import Future, Msg, Global
 from .framework import Future, Msg, Global
 
 
 
 
-def _get_response(cmd, spec, gen_msg_id=False):
-    """
-    yield出来的为Future对象,每次yield前注册event,event的callback为给该Future对象set-result
-    yield的返回值为改Future对象的值
-    :return:
-    """
-
-    # 注册event
-    msg_id = Msg.gen_msg_id()
-    spec['msg_id'] = msg_id
-    msg = dict(command=cmd, spec=spec)
-    f = Future()
-    Msg.add_callback(msg_id, f.set_result)
+def _get_response(cmd, spec):
 
 
+    msg = dict(command=cmd, spec=spec)
     Global.active_ws.write_message(json.dumps(msg))
     Global.active_ws.write_message(json.dumps(msg))
 
 
-    response_msg = yield from f
-    Msg.unregister_msg(msg_id)
+    response_msg = yield from Future()
 
 
     return response_msg
     return response_msg
 
 
 
 
 # 非阻塞协程工具库
 # 非阻塞协程工具库
 def text_input_coro(prompt):
 def text_input_coro(prompt):
-    input_text = yield from _get_response("text_input", spec=dict(prompt=prompt))
+    data = yield from _get_response("text_input", spec=dict(prompt=prompt))
+    input_text = data['data']
     return input_text
     return input_text
 
 
 
 

+ 19 - 15
wsrepl/ioloop.py

@@ -1,9 +1,10 @@
 import tornado.websocket
 import tornado.websocket
 import time, json
 import time, json
-from collections import defaultdict
+from collections import defaultdict, OrderedDict
 from .framework import Global, Msg, Task
 from .framework import Global, Msg, Task
 from os.path import abspath, dirname
 from os.path import abspath, dirname
 from tornado.web import StaticFileHandler
 from tornado.web import StaticFileHandler
+from tornado.gen import coroutine,sleep
 
 
 project_dir = dirname(abspath(__file__))
 project_dir = dirname(abspath(__file__))
 
 
@@ -21,27 +22,30 @@ def start_ioloop(coro, port=8080):
             print("WebSocket opened")
             print("WebSocket opened")
             self.set_nodelay(True)
             self.set_nodelay(True)
             ############
             ############
-            self.sid = int(time.time())
-            self.coro = coro()
 
 
-            Global.active_ws = self
-            self.task = Task(self.coro)
-            self.task.on_task_finish = self.on_task_finish
+            self.coros = [coro()]
+            self.callbacks = OrderedDict()  # UI元素时的回调, key -> callback, mark_id
+            self.mark2id = {}  # 锚点 -> id
 
 
-        def on_task_finish(self, result):
-            print('Task finish, return: %s' % result)
-            self.close()
+            Global.active_ws = self
+            next(self.coros[-1])
 
 
+        @coroutine
         def on_message(self, message):
         def on_message(self, message):
             print('on_message', message)
             print('on_message', message)
-            # self.write_message(u"You said: " + message)
-            # { msg_id: , data: }
+            # { event: , data: }
             data = json.loads(message)
             data = json.loads(message)
+            try:
+                Global.active_ws = self
+                res = self.coros[-1].send(data)
+                while res is not None:
+                    print('get not none form coro ', res)
+                    yield res
+                    Global.active_ws = self
+                    res = self.coros[-1].send(data)
 
 
-            Global.active_ws = self
-            callbacks = Msg.get_callbacks(data['msg_id'])
-            for c in callbacks:
-                c(data['data'])
+            except StopIteration:
+                self.close()
 
 
         def on_close(self):
         def on_close(self):
             print("WebSocket closed")
             print("WebSocket closed")