簡體   English   中英

Python:cmd和asyncio的組合(用於WAMP /高速公路)

[英]Python: Combination of cmd and asyncio (for WAMP / autobahn)

總覽

我正在嘗試為WAMP應用程序實現一個簡單的命令行界面。

對於WAMP實施,使用了autobahn python軟件包。

我想要一個交互式外殼,所以我決定使用cmd模塊來解析輸入。 不幸的是,我無法將autobahnasyncio特性與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-synccrochet包裝器,用於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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM