2015年1月22日木曜日

Python SimpleXMLRPCServerでHTTP/1.1による永続接続

え?まだ1.1使ってるの?いやいやその前に今時XMLRPCなの?という本質的な疑問はとりあえず横に置いておいて。

XMLRPCを使ったプロトタイプをPythonで作る場合、Python付属のSimpleXMLRPCServerxmlrpclibを使うのが一番簡単な方法ではないかと思います。Pythonのドキュメントにもこれらのライブラリを使ったXMLRPCサーバーおよびクライアントの解説があります。

ドキュメントに書かれている内容に従ってサーバーを実装すると、HTTPバージョンとして1.0が使われます。もちろん、普通に動作するのですが、RPCの度にTCP (HTTP) 接続を確立するので効率が気になります。短時間に大量のRPCを発行する場合は特にそうです。HTTPバージョン1.1では一度確立したHTTP接続で何度でもコマンドのやりとりが出きるので、できればHTTPバージョン1.1を使いたいと思っていたのですが、軽く検索してみてもなかなかこれといった情報が見つからず、かといって自前でHTTPバージョン1.1対応するのも面倒で放置していました。

先日Pythonのドキュメントを見ていたら、BaseHTTPRequestHandlerprotocol_versionという変数があり、これをHTTP/1.1に設定することでBaseHTTPRequestHandlerを使っているSimpleHTTPServerなどがHTTPバージョン1.1対応になるという記述を公式ドキュメントに発見しました。対象ライブラリの説明だけでなく、きちんと親クラスの説明も読まないとダメですね。SimpleXMLRPCServerもPRCリクエストの処理にBaseHTTPRequestServer由来のSimpleXMLRPCRequestHandlerを使っているのでなんとかなりそうです。


from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler

class HTTP11SimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
    protocol_version = 'HTTP/1.1'

class RPCMethods(object):
    def add(self, a, b):
        return a + b

server = SimpleXMLRPCServer(('', 8000), requestHandler=
HTTP11SimpleXMLRPCRequestHandler)

server.register_instance(RPCMethods())
server.serve_forever()


これでめでたくXMLRPCサーバーがHTTPバージョン1.1で応答するようになりました。xmlrpclibを用いたクライアントの方は、どうやら標準でHTTPバージョン1.1を使うらしく、サーバー側を対応するだけで永続接続が使えるようになります。

検索してでてこないということは、誰も使っていない (あるいは当たり前すぎて質問もされない) ということかもしれませんが、将来の自分のためのメモとして残しておきます。


0 件のコメント: