我正在尝试同时在python中运行两个ComplexTypeModelBinderProvider
。以前,我使用this post's answer中建议的修改高速公路库来完成此操作。我现在
需要更专业的解决方案。
在谷歌搜索了一段时间后this post appeared quite promising,但使用了autobahn.asyncio.wamp.ApplicationSession
库,而不是twisted
。我无法为asyncio
库的asyncio
分支找到类似的解决方案,因为它似乎没有使用autobahn
。
我遇到的主要问题是Reactors
正在阻塞(这就是我之前将其外包给线程的原因),所以我不能在它之后运行第二个ApplicationRunner.run()
。
我确实需要同时访问2个websocket频道,单身ApplicationRunner
似乎无法做到这一点。
我的代码到目前为止:
ApplicationSession
我对from autobahn.asyncio.wamp import ApplicationSession
from autobahn.asyncio.wamp import ApplicationRunner
from asyncio import coroutine
import time
channel1 = 'BTC_LTC'
channel2 = 'BTC_XMR'
class LTCComponent(ApplicationSession):
def onConnect(self):
self.join(self.config.realm)
@coroutine
def onJoin(self, details):
def onTicker(*args, **kwargs):
print('LTCComponent', args, kwargs)
try:
yield from self.subscribe(onTicker, channel1)
except Exception as e:
print("Could not subscribe to topic:", e)
class XMRComponent(ApplicationSession):
def onConnect(self):
self.join(self.config.realm)
@coroutine
def onJoin(self, details):
def onTicker(*args, **kwargs):
print('XMRComponent', args, kwargs)
try:
yield from self.subscribe(onTicker, channel2)
except Exception as e:
print("Could not subscribe to topic:", e)
def main():
runner = ApplicationRunner("wss://api.poloniex.com:443", "realm1", extra={})
runner.run(LTCComponent)
runner.run(XMRComponent) # <- is not being called
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
quit()
except Exception as e:
print(time.time(), e)
库的了解有限,我担心文档不会改善我的情况。我在这里俯瞰什么吗?一个函数,一个参数,它可以让我复合我的组件或同时运行它们吗?
也许是与provided here类似的解决方案,它实现了替代autobahn
?
相关主题
Running two ApplicationSessions in twisted
Running Autobahn ApplicationRunner in Thread
Autobahn.wamp.ApplicationSession Source
Autobahn.wamp.Applicationrunner Source
如同要求的那样,来自@ stovfl使用ApplicationRunner
代码回答的追溯:
multithreading
答案 0 :(得分:2)
正如我从traceback
看到的那样,我们只能达到第4步的第2步
来自 asyncio 文档:
该模块提供了使用协同程序编写单线程并发代码的基础结构,通过套接字和其他资源多路复用I / O访问
所以我使用multithreading
删除了我的第一个提案
我可以想象以下三个选项:
multiprocessing
代替multithreading
coroutine
asyncio loop
执行此操作
channels
def onJoin(self, details)
之间切换
醇>
第二个提案,使用multiprocessing
的第一个选项
我可以开始两个asyncio loops
,因此appRunner.run(...)
应该有用。
如果class ApplicationSession
是唯一的不同,您可以使用一个 channel
。
如果您需要传递不同的class ApplicationSession
,请将其添加到args=
class __ApplicationSession(ApplicationSession):
# ...
try:
yield from self.subscribe(onTicker, self.config.extra['channel'])
except Exception as e:
# ...
import multiprocessing as mp
import time
def ApplicationRunner_process(realm, channel):
appRunner = ApplicationRunner("wss://api.poloniex.com:443", realm, extra={'channel': channel})
appRunner.run(__ApplicationSession)
if __name__ == "__main__":
AppRun = [{'process':None, 'channel':'BTC_LTC'},
{'process': None, 'channel': 'BTC_XMR'}]
for app in AppRun:
app['process'] = mp.Process(target = ApplicationRunner_process, args = ('realm1', app['channel'] ))
app['process'].start()
time.sleep(0.1)
AppRun[0]['process'].join()
AppRun[1]['process'].join()
答案 1 :(得分:1)
遵循方法you linked for twisted,通过异步设置 start_loop = False
,我设法获得了相同的行为import asyncio
from autobahn.asyncio.wamp import ApplicationSession, ApplicationRunner
runner1 = ApplicationRunner(url, realm, extra={'cli_id': 1})
coro1 = runner1.run(MyApplicationSession, start_loop=False)
runner2 = ApplicationRunner(url, realm, extra={'cli_id': 2})
coro2 = runner2.run(MyApplicationSession, start_loop=False)
asyncio.get_event_loop().run_until_complete(coro1)
asyncio.get_event_loop().run_until_complete(coro2)
asyncio.get_event_loop().run_forever()
class MyApplicationSession(ApplicationSession):
def __init__(self, cfg):
super().__init__(cfg)
self.cli_id = cfg.extra['cli_id']
def onJoin(self, details):
print("session attached", self.cli_id)