[英]Python: Combination of cmd and asyncio (for WAMP / autobahn)
我正在嘗試為WAMP應用程序實現一個簡單的命令行界面。
對於WAMP實施,使用了autobahn
python軟件包。
我想要一個交互式外殼,所以我決定使用cmd
模塊來解析輸入。 不幸的是,我無法將autobahn
的asyncio
特性與cmd
循環結合起來。
因此,總的來說,我想擁有的東西與此類似:
import argparse
import autobahn.asyncio.wamp as wamp
import cmd
class Shell(cmd.Cmd):
intro = 'Interactive WAMP shell. Type help or ? to list commands.\n'
prompt = '>> '
def __init__(self, caller, *args):
super().__init__(*args)
self.caller = caller
def do_add(self, arg):
'Add two integers'
a, b = arg.split(' ')
res = self.caller(u'com.example.add2', int(a), int(b))
res = res.result() # this cannot work and yields an InvalidStateError
print('call result: {}'.format(res))
class Session(wamp.ApplicationSession):
async def onJoin(self, details):
Shell(self.call).cmdloop()
def main(args):
url = 'ws://{0}:{1}/ws'.format(args.host, args.port)
print('Attempting connection to "{0}"'.format(url))
try:
runner = wamp.ApplicationRunner(url=url, realm=args.realm)
runner.run(Session)
except OSError as err:
print("OS error: {0}".format(err))
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('realm', type=str)
parser.add_argument('host', type=str)
parser.add_argument('port', type=int)
main(parser.parse_args())
這顯然是行不通的,因為將來調用result()
時結果還沒有准備好,但是由於Shell本身不是async
,所以我不能使用await。
我已經找到asynccmd
但是我asynccmd
如何在autobahn
上使用它的問題,並且總體上,我仍然對asyncio
的內部結構有點不知所措。
使用一個簡單的循環
try:
while(True):
a = int(input('a:'))
b = int(input('b:'))
res = await self.call(u'com.example.add2', a, b)
print('call result: {}'.format(res))
except Exception as e:
print('call error: {0}'.format(e))
內部的onJoin
函數可以很好地工作,所以我覺得我的問題也必須有一個簡單而精益的解決方案。
我們歡迎所有的建議!
事實證明,已經有解決此問題的方法。
autobahn
有兩個版本,一個使用aysncio
,另一個使用來自twisted
異步回調。
crochet
程序包允許使用同步上下文中的twisted
回調,因此提供了一種解決方案。
軟件包autobahn-sync
是crochet
包裝器,用於autobahn,可從cmd.Cmd
(或其他任何地方)內調用RCP變得很簡單:
import autobahn_sync
autobahn_sync.run(url='example.com', realm='myrealm')
autobahn_sync.call(u'com.example.add2', a, b)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.