SimpleXMLRPCServer
SimpleXMLRPCServerを使ってみます。
- 引数で (アドレス, ポート) というタプルを与えてSimpleXMLRPCServerのインスタンスを作る
- register_instance、register_functionで公開するAPIをインスタンスに登録
- serve_foreverでlisten
基本的にはこれだけです。簡単ですね。
# server.py class Foo: def add(self, a, b): return a+b def get_list(self, *a): return [str(i)+'!' for i in a] def get_dict(self): return {'a': 'apple', 'b': 'banana', 'o': 'orange', } def hello(self): print 'hello' return True def sub(a, b): return a-b import SimpleXMLRPCServer SimpleXMLRPCServer.SimpleXMLRPCServer.allow_reuse_address=True s = SimpleXMLRPCServer.SimpleXMLRPCServer(('localhost', 12345)) s.register_instance(Foo()) s.register_function(sub) s.register_function(lambda x, y: x*y, 'mul') s.serve_forever()
# client.py import xmlrpclib s = xmlrpclib.ServerProxy('http://localhost:12345') print s.add(1, 2) print s.sub(10, 9) print s.mul(11, 11) print s.get_list(1, 2, 3, 4, 5, 6, 'foo', 'bar') print s.get_dict() s.hello()
実行結果は以下のようになります
> python server.py
> python client.py 3 1 121 ['1!', '2!', '3!', '4!', '5!', '6!', 'foo!', 'bar!'] {'a': 'apple', 'b': 'banana', 'o': 'orange'}
> python server.py localhost - - [22/Oct/2006 23:22:33] "POST /RPC2 HTTP/1.0" 200 - localhost - - [22/Oct/2006 23:22:33] "POST /RPC2 HTTP/1.0" 200 - localhost - - [22/Oct/2006 23:22:33] "POST /RPC2 HTTP/1.0" 200 - localhost - - [22/Oct/2006 23:22:33] "POST /RPC2 HTTP/1.0" 200 - localhost - - [22/Oct/2006 23:22:33] "POST /RPC2 HTTP/1.0" 200 - hello localhost - - [22/Oct/2006 23:22:33] "POST /RPC2 HTTP/1.0" 200 -
localhost - -... というのはアクセスログです。鬱陶しい場合はサーバインスタンス生成時に
s = SimpleXMLRPCServer.SimpleXMLRPCServer(('localhost', 12345), logRequests=False)
とすることでログを表示しないようになります。helloと表示されているのはクライアントがメソッド hello() を呼び出した結果です。
また、
SimpleXMLRPCServer.SimpleXMLRPCServer.allow_reuse_address=True
とすることで サーバ起動 -> 停止 -> サーバ起動 を短い時間で行ったときに出がちなエラー、Address already in use を殺しています。
気がついたことなど
- サーバに登録するインスタンスメソッド/関数はNone以外の値を返す必要がある
- hello()で返り値を書かなかったら呼び出し時に例外が起きた
- 文字列や数値だけではなく、リストや辞書なども結果として返すことができる