全部博文(921)
分类: Python/Ruby
2012-04-06 23:57:06
I've been using Twisted's Perspective Broker to manage networking for my Python program. Perspective Broker allows me to run a Python program on a remote machine and perform remote method calls on an object in the Python program. It also allows me to serialize objects and transfer them over TCP.
Once I got a Perspective Broker server and client running, I wanted to create a "Twisted Application" and run it using twistd, the Twisted Daemon. Two major options are: creating a .tac file and creating a twistd plugin. Below, I show the steps I took to create a .tac application script and a twistd plugin using a simple Perspective Broker example.
Basic Perspective Broker server and clientHere is a simple Perspective Broker server and client example which I adapted from Twisted's examples page. The PB server code lives in pbsimpleserver.py:
Here is a simple PB client, pbsimpleclient.py:
This code connects the client to the server using port 8789. It sends a message by calling the server's remote_echo method with an argument of "hello network". The server prints the message and returns the same message to the client. The client then prints the message.
To test the code, I ran both client and server on my local machine. I ran python pbsimpleserver.py in one terminal shell, then ran python pbsimpleclient.py in another shell. In the server shell, I got:
and in the client shell I got:
To stop the client and server, I hit CTRL-C in both shells
Converting to a Twisted Application (.tac script)To create a Twisted application, I used the twisted.application.service.Application object. When converting the example code above to an Application, I replaced twisted.internet.reactor.listenTCP with twisted.application.internet.TCPServer and twisted.internet.reactor.connectTCP with twisted.application.internet.TCPClient. Below is my server application, pbsimpleserver_app.py. (Note: the two files below are considered .tac files even though the filename doesn't end in .tac. From the documentation, .tac files are Python files which configure an Application object and assign this object to the top-level variable "application".)
from twisted.spread import pb from twisted.application.internet import TCPServer from twisted.application.service import Application class Echoer(pb.Root): def remote_echo(self, st): print 'echoing:', st return st serverfactory = pb.PBServerFactory(Echoer()) application = Application("echo") echoServerService = TCPServer(8789, serverfactory) echoServerService.setServiceParent(application)Here is my client application, pbsimpleclient_app.py:
from twisted.spread import pb from twisted.application.internet import TCPClient from twisted.application.service import Application class EchoClient(object): def send_msg(self, result): d = result.callRemote("echo", "hello network") d.addCallback(self.get_msg) def get_msg(self, result): print "server echoed: ", result e = EchoClient() clientfactory = pb.PBClientFactory() d = clientfactory.getRootObject() d.addCallback(e.send_msg) application = Application("echo") echoClientService = TCPClient("localhost", 8789, clientfactory) echoClientService.setServiceParent(application)To run these as daemons with twistd, I executed:
twistd -l server.log --pidfile server.pid -y pbsimpleserver_app.pythen:
twistd -l client.log --pidfile client.pid -y pbsimpleclient_app.pyThis created the log file, server.log:
2008-10-27 00:08:35-0700 [-] Log opened. 2008-10-27 00:08:35-0700 [-] twistd 8.1.0 (/usr/bin/python 2.5.2) starting up 2008-10-27 00:08:35-0700 [-] reactor class: 2008-10-27 00:08:35-0700 [-] twisted.spread.pb.PBServerFactory starting on 8789 2008-10-27 00:08:35-0700 [-] Starting factory 2008-10-27 00:08:53-0700 [Broker,0,127.0.0.1] echoing: hello networkand client.log:
2008-10-27 00:08:53-0700 [-] Log opened. 2008-10-27 00:08:53-0700 [-] twistd 8.1.0 (/usr/bin/python 2.5.2) starting up 2008-10-27 00:08:53-0700 [-] reactor class: 2008-10-27 00:08:53-0700 [-] Starting factory 2008-10-27 00:08:53-0700 [Broker,client] server echoed: hello network
In order to pass command line arguments to my Twisted application daemon, I need to create a twistd plugin. The following is how I implemented my plugin after reading the Writing a twistd plugin documentation. Here is my directory structure. EchoProj is located in ~/Projects.
EchoProj |-- echoproj | |-- __init__.py | |-- pbsimpleclient.py | `-- pbsimpleserver.py `-- twisted `-- plugins |-- echoclient_plugin.py `-- echoserver_plugin.pypbsimpleserver.py:
pbsimpleclient.py:
echoserver_plugin.py:
echoclient_plugin.py:
I set the PYTHONPATH to include the top-level project directory:
export PYTHONPATH="$HOME/Projects/EchoProj:$PYTHONPATH"Running twistd --help now showed "echoserver" and "echoclient" in the list of commands. To run my server and client as daemons using port 8790 on my local machine, I executed:
twistd -l server.log --pidfile server.pid echoserver -p 8790and
twistd -l client.log --pidfile client.pid echoclient -p 8790This produced the logfiles, server.log:
2008-10-27 11:49:12-0700 [-] Log opened. 2008-10-27 11:49:12-0700 [-] twistd 8.1.0 (/usr/bin/python 2.5.2) starting up 2008-10-27 11:49:12-0700 [-] reactor class: 2008-10-27 11:49:12-0700 [-] twisted.spread.pb.PBServerFactory starting on 8790 2008-10-27 11:49:12-0700 [-] Starting factory 2008-10-27 11:49:17-0700 [Broker,0,127.0.0.1] echoing: hello networkand client.log:
2008-10-27 11:49:17-0700 [-] Log opened. 2008-10-27 11:49:17-0700 [-] twistd 8.1.0 (/usr/bin/python 2.5.2) starting up 2008-10-27 11:49:17-0700 [-] reactor class: 2008-10-27 11:49:17-0700 [-] Starting factory 2008-10-27 11:49:17-0700 [Broker,client] server echoed: hello networkfrom:
http://www.saltycrane.com/blog/2008/10/running-twisted-perspective-broker-example-twistd/