TwistedNetstring
JSON-RPC over TCP
Dependencies
- Twisted
- simplejson
Notes
This version was built from the adytum.twisted.web2.jsonrpc code by essentially replacing the HTTP-related code with twisted.protocols.basic.NetstringReceiver code.
One of the benefits of using Netstrings for this are string-length checks. There is a default maximum length that can be sent to the server. If you are sending large JSON strings to the server, you may need to override the default (1024 bytes).
The tests for adytum.twisted.web2.jsonrpc were also included/adapted and pass successfully.
Import
>>> from txjsonrpc.netstring import jsonrpc
Usage
Server
The server setup is a little different than with the HTTP versions. In particular, the manner of setting up subhandlers has changed. But first, let's look at a server example:
from twisted.application import service, internet from txjsonrpc.netstring import jsonrpc class Example(jsonrpc.JSONRPC): """An example object to be published.""" def jsonrpc_echo(self, x): """Return all passed args.""" return x class Testing(jsonrpc.JSONRPC): def jsonrpc_getList(self): """Return a list.""" return [1,2,3,4,'a','b','c','d'] class Math(jsonrpc.JSONRPC): def jsonrpc_add(self, a, b): """Return sum of arguments.""" return a + b # Setup the subhandlers for our RPC API factory = jsonrpc.RPCFactory(Example) factory.putSubHandler('math', Math) factory.putSubHandler('testing', Testing) # Let's add introspection, just for fun factory.addIntrospection() application = service.Application("Example JSON-RPC Server") jsonrpcServer = internet.TCPServer(7080, factory) jsonrpcServer.setServiceParent(application)
With the HTTP versions, you create instances of your JSONRPC subclasses when adding them as subhandlers:
top = Example() top.addSubHandler('math', Math()) top.addSubHandler('testing', Testing())
But for the TCP version, you can see that we add the JSONRPC _subclasses_ to the *factory* instead:
factory = jsonrpc.RPCFactory(Example) factory.putSubHandler('math', Math) factory.putSubHandler('testing', Testing)
As for adding the introspection, there are two ways to do it with the TCP version. One way is how we did it in the example server above. The other way is similar to the HTTP RPC servers:
addIntrospection(factory)
But note that you are passing the _factory_ and not the parent instance.
Save the server code from above as server_subhandled.tac and run with the following command:
$ twistd -noy server_subhandled.tac
Client
Here is example client code for the server above:
from twisted.internet import reactor from twisted.internet import defer from txjsonrpc.netstring.jsonrpc import Proxy def printValue(value): print "Result: %s" % str(value) def printError(error): print 'error', error def shutDown(data): print "Shutting down reactor..." reactor.stop() print "Making remote calls..." proxy = Proxy('127.0.0.1', 7080) dl = [] d = proxy.callRemote('system.listMethods') d.addCallbacks(printValue, printError) dl.append(d) d = proxy.callRemote('echo', 'bite me') d.addCallbacks(printValue, printError) dl.append(d) d = proxy.callRemote('testing.getList') d.addCallbacks(printValue, printError) dl.append(d) d = proxy.callRemote('math.add', 3, 5) d.addCallbacks(printValue, printError) dl.append(d) dl = defer.DeferredList(dl) dl.addCallback(shutDown) reactor.run()
Save this file as client_subhandled.py and run it from the command line. You should see output something like this:
Making remote calls... Result: [u'echo', u'math.add', u'system.listMethods', u'system.methodHelp', u'system.methodSignature', u'testing.getList'] Result: [1, 2, 3, 4, u'a', u'b', u'c', u'd'] Result: 8 Result: bite me Shutting down reactor...
txJSON-RPC/TwistedNetstring (last edited 2008-08-06 16:59:59 by localhost)