Tìm hiểu về jsonrpclib

1. Tổng quan

  • Thư viện jsonrpclib cho phép người sử dụng dễ dàng tạo ra một server đơn giản cũng như gọi request đến một server
  • jsonrpclib hỗ trợ cả Json-rpc 1.0 và 2.0 bao gồm:
    • Batch submission (thông qua MultiCall)
    • Keyword arguments
    • Notifications (cả trong 1 batch lẫn 'normal')
    • Class translation sử dụng 'jsonclass'.
  • jsonrpclib hỗ trợ cjson và simplejson, và tìm kiếm các parsers cũng theo thứ tự đó (tìm kiếm đầu tiên cho cjson, sau đó cho simplejson được "built-in" như json 2.6+, và sau đó là thư viện simplejson) và một trong số những thư viện kể trên phải được cài đặt nếu muốn sử dụng jsonrpclib, một lưu ý nhỏ rằng cjson được coi là nhanh nhất
  • jsonrpclib có một module là "SimpleJSONRPCServer" được dùng để thay thế "SimpleXMLRPCServer" mặc định của Python

2.Cài đặt

Có 3 cách để cài đặt jsonrpclib Bạn có thể install từ PyPI với chỉ 1 commands: easy_install jsonrpclib pip install jsonrpclib Hoặc download source từ github http://github.com/joshmarshall/jsonrpclib: git clone git://github.com/joshmarshall/jsonrpclib.git cd jsonrpclib python setup.py install

3.Request

  • jsonrpclib sử dụng method Server để khai báo server cho các request sử dụng object này, sau đó sử dụng các method để tạo request
>>> server = jsonrpclib.Server('http://localhost:8080')
>>> server.add(5,6)
11
>>> print jsonrpclib.history.request
{"jsonrpc": "2.0", "params": [5, 6], "id": "gb3c9g37", "method": "add"}
>>> print jsonrpclib.history.response
{'jsonrpc': '2.0', 'result': 11, 'id': 'gb3c9g37'}
>>> server.add(x=5, y=10)
15
>>> server._notify.add(5,6)
# No result returned...
>>> batch = jsonrpclib.MultiCall(server)
>>> batch.add(5, 6)
>>> batch.ping({'key':'value'})
>>> batch._notify.add(4, 30)
>>> results = batch()
>>> for result in results:
>>> ... print result
11
{'key': 'value'}

Nếu bạn muốn sử dụng json-rpc 1.0 thì chỉ cần set version thành 1.0:

>>> jsonrpclib.config.version
2.0
>>> jsonrpclib.config.version = 1.0
>>> server = jsonrpclib.Server('http://localhost:8080')
>>> server.add(7, 10)
17
>>> print jsonrpclib..history.request
{"params": [7, 10], "id": "thes7tl2", "method": "add"}
>>> print jsonrpclib.history.response
{'id': 'thes7tl2', 'result': 17, 'error': None}
>>> 
  • Giống như funtion loads và dumps có sẵn, .jsonrpclib bổ sung thêm 3 arguments: rpcid: 'id', version để xác định version JSON-RPC và notify nếu bạn muốn request là notification
  • Ngoài ra, các method loads cũng không trả lại params và method như xmlrpclib, thay vào đó là errors, ProtocolErrors, và structure của request

4.SimpleJSONRPCServer

  • jsonrpclib sử dụng SimpleJSONRPCServer để khởi tạo một server. Trong python ta cũng SimpleXMLRPCServer giống như SimpleJSONRPCServer, tuy nhiên SimpleJSONRPCServer có thêm 3 argv: rpcid, version json-rpc và notify

server = SimpleJSONRPCServer(('localhost', 8080))
server.register_function(pow)
server.register_function(lambda x,y: x+y, 'add')
server.register_function(lambda x: x, 'ping')
server.serve_forever()

Ta cũng có thể cài đặt func GET, POST, PUT, DELETE cho server cũng như header cho respone

5. Class Translation

  • jsonrpclib hỗ trợ class translation tự động (mặc định của python, class translation sẽ bị tắt), do vậy class translation sẽ khiến hệ thống bị chậm nếu không được sử dụng đúng cách. Cả client và server đều phải dùng use_jsonclass và các thư viện tương tự nhau.

Nếu bạn dùng quá nhiều argv thì cách tốt nhất là sử dụng jsonrpclib.jsonclass.dump / jsonrpclib.jsonclass.load

#test_obj.py
class TestObj(object):
    foo = 'bar'

class TestSerial(object):
    foo = 'bar'
    def __init__(self, *args):
        self.args = args
    def _serialize(self):
        return (self.args, {'foo':self.foo,})

# user class translation
import jsonrpclib
import test_obj

jsonrpclib.config.use_jsonclass = True

testobj1 = test_obj.TestObj()
testobj2 = test_obj.TestSerial()
server = jsonrpclib.Server('http://localhost:8080')
# The 'ping' just returns whatever is sent
ping1 = server.ping(testobj1)
ping2 = server.ping(testobj2)
print jsonrpclib.history.request
# {"jsonrpc": "2.0", "params": [{"__jsonclass__": ["test_obj.TestSerial", ["foo"]]}], "id": "a0l976iv", "method": "ping"}
print jsonrpclib.history.result
# {'jsonrpc': '2.0', 'result': <test_obj.TestSerial object at 0x2744590>, 'id': 'a0l976iv'}

6. Python 3x

Thư viện jsonrpclib chưa hỗ trợ cho python 3x tuy nhiên bạn cũng có thể sử dụng jsonrpclib bằng cách tìm file jsonrpc.py và sửa như sau Sửa

from xmlrpclib import SafeTransport as XMLSafeTransport
from xmlrpclib import ServerProxy as XMLServerProxy
from xmlrpclib import _Method as XML_Method

thành:

from xmlrpc.client import SafeTransport as XMLSafeTransport
from xmlrpc.client import ServerProxy as XMLServerProxy
from xmlrpc.client import _Method as XML_Method