问题的本质是:考虑到代码应该运行并且只有在进行远程过程调用时才被中断,是否可以在支持 Python 2.7 和 3.4 的 Django 应用程序中使用 WAMP 通知?(也就是说,它不仅仅是在等待一个 RPC 的到来)
我们想如何使用 WAMP:该程序有一个 Javascript 前端和一个 Python/Django 后端。我们要做的一件事是在单击前端的按钮时在后端启动一个函数。不过,这有时会花费太多时间,因此我们允许用户通过单击另一个按钮来取消它。这会进行远程过程调用,这将导致函数提前停止(它会更改在函数中检查的变量)。将来也可能对 RPC 或 Pub/Sub 有其他需求。
我们使用autobahn_sync模块让它与 Python 2.7 一起工作,但它使用了 Twisted,它还没有完全移植到 Python 3.x。这就是为什么我们需要另一种方法来让 WAMP 通知在 3.x 上工作。
支持 asyncio 并且从crossbar 文档看来它可以用来代替 Twisted,但是如果不阻塞应该并行运行的代码(代码添加在下面),我们就无法让它工作。而且似乎没有类似 autobahn_sync 使用 asyncio 而不是 Twisted 的东西。
我们是 WAMP 的新手,可能缺少一些东西。
这是我们使用 asyncio 测试的代码(使用 Python 3.4)。它阻止了其余的功能:
from asyncio import coroutine, new_event_loop, set_event_loop
from autobahn.asyncio.wamp import ApplicationSession, ApplicationRunner
class MyComponent(ApplicationSession):
@wamp.register("com.function.cancel")
def cancel(self):
print("called cancel procedure")
# do things here
return "Canceled"
@coroutine
def onJoin(self, details):
res = yield from self.register(self)
print("{} procedures registered.".format(len(res)))
def function_triggered_in_frontend():
loop = new_event_loop()
set_event_loop(loop)
runner = ApplicationRunner(url=u"ws://localhost:8080/ws", realm=u"realm1")
runner.run(MyComponent)
# and now the function should continue working on other things, but does't because it doesn't return from runner.run().
print("do stuff")
我们如何注册主题并从 runner.run 调用返回?在 Python 2.7 测试中,使用 autobahn_sync 我们可以简单地执行以下操作:
from autobahn_sync import register, run, AlreadyRunningError
@register('com.function.cancel')
def cancel_generate_jobs():
print("called cancel procedure")
@register('com.function.cancel')
# def cancel_generate_jobs():
def function_triggered_in_frontend():
try:
run(realm=u"realm1")
except AlreadyRunningError:
logger.info('AutbahnSync instance already started.')
# and then the code would continue being processed here, as we want