1
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
3
<!-- $Id: 8-example.html,v 2.21.2.2 2008/06/28 23:41:02 irmen Exp $ -->
5
<title>PYRO - Example</title>
6
<link rel="stylesheet" type="text/css" href="pyromanual_print.css" media="print">
7
<link rel="stylesheet" type="text/css" href="pyromanual.css" media="screen">
14
<td align="left"><a href="7-features.html"><previous</a> | <a href="PyroManual.html">contents</a> | <a href=
15
"9-security.html">next></a></td>
17
<td align="right">Pyro Manual</td>
23
In this chapter you'll find a short but complete example that shows how Pyro must be used
24
and how it works. However, much more interesting examples can be found in the <code>examples</code> directory.
25
For the real impatient people, I recommend the "quickstart" example, because you'll see that you
26
can eliminate very much of the (already little!) extra work you have to do to make a Pyro application.
28
<p>For the really impatient, first two minimalist Pyro examples.</p>
30
<h3>Minimalist's Pyro - not using a Name Server</h3>
39
class JokeGen(Pyro.core.ObjBase):
41
Pyro.core.ObjBase.__init__(self)
43
return "Sorry "+name+", I don't know any jokes."
45
Pyro.core.initServer()
46
daemon=Pyro.core.Daemon()
47
uri=daemon.connect(JokeGen(),"jokegen")
49
print "The daemon runs on port:",daemon.port
50
print "The object's uri is:",uri
62
# you have to change the URI below to match your own host/port.
63
jokes = Pyro.core.getProxyForURI("PYROLOC://localhost:7766/jokegen")
65
print jokes.joke("Irmen")
70
<h3>Minimalist's Pyro - using a Name Server</h3>
80
class JokeGen(Pyro.core.ObjBase):
82
Pyro.core.ObjBase.__init__(self)
84
return "Sorry "+name+", I don't know any jokes."
86
Pyro.core.initServer()
87
ns=Pyro.naming.NameServerLocator().getNS()
88
daemon=Pyro.core.Daemon()
89
daemon.useNameServer(ns)
90
uri=daemon.connect(JokeGen(),"jokegen")
101
# finds object automatically if you're running the Name Server.
102
jokes = Pyro.core.getProxyForURI("PYRONAME://jokegen")
104
print jokes.joke("Irmen")
109
<h3>There we go with the complete example:</h3>
112
<li>Write a module 'testmod.py' containing a class 'testclass', which will be accessed remotely.
115
def mul(s, arg1, arg2): return arg1*arg2
116
def add(s, arg1, arg2): return arg1+arg2
117
def sub(s, arg1, arg2): return arg1-arg2
118
def div(s, arg1, arg2): return arg1/arg2
122
<li>Write a server, testserver.py, that creates one or more instances of the 'testclass', and registers them with
123
the Pyro Name Server.
127
from Pyro.errors import PyroError,NamingError
131
###### testclass Pyro object
133
class testclass(Pyro.core.ObjBase, testmod.testclass):
136
###### main server program
139
Pyro.core.initServer()
140
daemon = Pyro.core.Daemon()
142
locator = Pyro.naming.NameServerLocator()
143
print 'searching for Name Server...'
145
daemon.useNameServer(ns)
147
# connect a new object implementation (first unregister previous one)
149
# 'test' is the name by which our object will be known to the outside world
150
ns.unregister('test')
154
# connect new object implementation
155
daemon.connect(testclass(),'test')
157
# enter the server loop.
158
print 'Server object "test" ready.'
161
if __name__=="__main__":
166
<li>To make it interesting, the shortest client possible looks someting like:
169
o=Pyro.core.getProxyForURI('PYRONAME://:Default.test')
171
</pre>... But for educational purposes, we use the long way around. Read on.
174
<li>Write a client, testclient.py, that will find the Name Server.
176
import Pyro.naming, Pyro.core
177
from Pyro.errors import NamingError
180
locator = Pyro.naming.NameServerLocator()
181
print 'Searching Name Server...',
183
</pre>(... continued ...)
186
<li>Let the client query the NS for the object's URI. Then create a proxy for the remote object. Because the proxy
187
appears the same as the real 'testclass', the client can now invoke methods on the remote objects.
189
<p>(...continued from above...)</p>
191
# resolve the Pyro object
192
print 'finding object'
194
URI=ns.resolve('test')
196
except NamingError,x:
197
print 'Couldn\'t find object, nameserver says:',x
200
# create a proxy for the Pyro object, and return that
201
test = Pyro.core.getProxyForURI(URI)
203
print test.mul(111,9)
204
print test.add(100,222)
205
print test.sub(222,100)
206
print test.div(2.0,9.0)
207
print test.mul('*',10)
208
print test.add('String1','String2')
212
<li>Run the application in the network. First, start the Name Server on one computer.
214
irmen@atlantis:~ > pyro-ns
215
*** Pyro Name Server ***
216
Pyro Server Initialized. Using Pyro V3.7
217
URI is: PYRO://10.0.0.150:9090/0a00009604005c6282a8a516d79917fd
218
URI written to: e:\Pyro_NS_URI
223
<li>Start the server on another computer (or in a different shell).
225
irmen@atlantis:~/ex > python testserver.py
226
Pyro Server Initialized. Using Pyro V3.5
227
searching for Name Server...
228
Server object "test" ready.
232
<li>Finally, run the client on a third computer (or in a different shell).
234
irmen@atlantis:~/ex > python testclient.py
235
Pyro Client Initialized. Using Pyro V3.5
236
Searching Name Server... finding object
237
URI: PYRO://10.0.0.150:7766/0a0000960c545c62a91e3021bceb7f26
247
<li>You might want to peek in the Name Server:
249
irmen@atlantis:~/ex > pyro-nsc listall
250
Locator: searching Pyro Name Server...
251
NS is at 10.0.0.150 (isengard.lan) port 9090
252
-------------- START DATABASE
253
:Default.test --> PYRO://10.0.0.150:7766/0a0000960c545c62a91e3021bceb7f26
254
:Pyro.NameServer --> PYRO://10.0.0.150:9090/0a00009604005c6282a8a516d79917fd
259
<li>And if you're interested you may want to try the logging facility of Pyro. First, set the tracelevel to
260
something other than the default, 0. See the chapter on configuration how to do that. Usually you'll set the
261
environment variable <code>PYRO_TRACELEVEL</code> to 3 (=maximum logging). Then, when you start Pyro programs (like
262
the nameserver), they will write something like this to the logfile:
264
------------------------------------------------------------ NEW SESSION
265
2005-03-13 13:23:40 Pyro Initializing, version 3.7
267
Configuration settings are as follows:
268
PYROSSL_CA_CERT = ca.pem
269
PYROSSL_CERTDIR = E:\temp\certs
270
PYROSSL_CLIENT_CERT = client.pem
271
PYROSSL_SERVER_CERT = server.pem
277
PYRO_DETAILED_TRACEBACK = 0
279
PYRO_ES_BLOCKQUEUE = 1
280
PYRO_ES_QUEUESIZE = 1000
281
PYRO_LOGFILE = E:\temp\Pyro_log
282
PYRO_MAXCONNECTIONS = 200
284
PYRO_MULTITHREADED = 1
285
PYRO_NS2_BC_PORT = 9091
286
PYRO_NS2_HOSTNAME = None
288
PYRO_NS_BC_PORT = 9090
289
PYRO_NS_DEFAULTGROUP = :Default
290
PYRO_NS_HOSTNAME = None
292
PYRO_NS_URIFILE = E:\temp\Pyro_NS_URI
293
PYRO_PICKLE_FORMAT = 2
295
PYRO_PORT_RANGE = 100
296
PYRO_PRINT_REMOTE_TRACEBACK = 0
297
PYRO_SOCK_KEEPALIVE = 1
299
PYRO_STDLOGGING_CFGFILE = logging.cfg
300
PYRO_STORAGE = E:\temp
301
PYRO_TCP_LISTEN_BACKLOG = 200
303
PYRO_USER_LOGFILE = E:\temp\Pyro_userlog
304
PYRO_USER_TRACELEVEL = 0
305
PYRO_XML_PICKLE = None
307
----------------------------------------------------------------------
308
2005-03-13 13:23:44 [1084:MainThread] ** NOTE ** NameServer ** created group :Pyro
309
2005-03-13 13:23:44 [1084:MainThread] ** NOTE ** NameServer ** created group :Default
310
2005-03-13 13:23:44 [1084:MainThread] ** NOTE ** NameServer ** Running in single mode
311
2005-03-13 13:23:44 [1084:MainThread] ** NOTE ** NameServer ** registered NameServer with URI PYRO://10.0.0.150:9090/0a000096043c5c63117eead5b89ea267
312
2005-03-13 13:23:44 [1084:MainThread] ** NOTE ** NameServer ** URI written to E:\temp\Pyro_NS_URI
313
2005-03-13 13:23:44 [1084:MainThread] ** NOTE ** NS daemon ** This is the Pyro Name Server.
314
2005-03-13 13:23:44 [1084:MainThread] ** NOTE ** NS daemon ** Starting on isengard port 9090 broadcast server on port 9090
322
<td align="left"><a href="7-features.html"><previous</a> | <a href="PyroManual.html">contents</a> | <a href=
323
"9-security.html">next></a></td>
325
<td align="right">Pyro Manual</td>