2

概要

WAMP アプリケーション用の単純なコマンドライン インターフェイスを実装しようとしています。

WAMP の実装には、autobahnpython パッケージが使用されます。

インタラクティブなシェルが欲しいので、cmdモジュールを使用して入力を解析することにしました。残念ながら、 のasyncio性質をautobahnループと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()、シェル自体ではないため、await を使用できませんasync

解決の試み

私は見つけましasynccmdたが、それを使用する方法を理解できませんでしautobahnasyncio.

単純なループの使用

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完全に正常に機能するため、私の問題にもシンプルで無駄のない解決策が必要だと感じています。

どんな提案でも大歓迎です!

4

1 に答える 1