<previous | contents | next> | Pyro Manual |
pyroc
, the proxy compiler, you generate static client proxy code for your Python class.
pyroc
) and create static proxies for the obtained URI, or just create a Pyro Dynamic proxy.
nsc
tool to unregister them, or restart the NS.
protect +es #?
. If it doesn't work, try executing them as regular python scripts, for instance: python nsc list
.
All scripts have to be called from a shell command prompt. Most of them accept command line parameters, see below.
genguid
(GUID generator)
pyroc
(Proxy compiler)
ns, rns
(Name Server)
nsc
(Name Server Control tool)
xnsc
(Graphical NS control tool)
nsc
command-line tool. Currently it needs Tk for the GUI, so you have to have a Tk-enabled Python on your system. It doesn't work on AmigaPython for instance.
The GUI is simple and should explain itself. You can enter the hostname in the textbox at the top and press <enter> to contact the NS at that host, or just press the 'Auto Discover' button at the top right. If the NS has been found, the rest of the buttons are enabled.
__init__
method. You should use a regular initialization method that you must call explicitly after binding to the remote object. The __init__
method will only be called on the server side when the object is created.
pyroc
can't yet deal fully with Python packages.
pyroc
. So you need to distribute these additional source files when you want to use static proxies. So why should you even use a static proxy?
pyroc
generates can deal with all of them. It might turn out that the dynamic proxy accepts things that will fail with the static version. Only time will tell.
Pyro.naming.NameServerProxy
). Luckily this is no big deal.
pyroc
) also supports direct attribute access.
Pyro.core.initServer()If you provide the argument '0', no banner is printed, otherwise a short message is printed on the standard output. If the tracelevel is not zero, a startup message is written to the log. This message shows the active configuration options.
daemon = Pyro.core.Daemon() daemon.useNameServer(ns)You can provide several arguments when creating the Daemon:
protocol | the protocol to use (defaults to "PYRO") |
host | the hostname to bind the server on (defaults to '' - the default host). This may be necessary in the case where your system has more than one hostname/IP address, for instance, when it has multiple network adapters. With this argument you can select the specific hostname to bind the server on. |
port | the socket number to use (defaults to the PYRO_PORT configuration item)
|
norange | whether or not to try a range of sockets (leave this at the default value, 0) |
publishhost | the hostname that the daemon will use when publishing URIs, in case of a firewall setup. See the Features chapter. Defaults to the value given to the host parameter.
|
ns
is a proxy for the NS, see the next paragraph how to get this proxy).
It's possible to omit this call but the Daemon will no longer be able to register your objects with the NS. If you didn't register them yourself, it is impossible to find them.
The daemon will log a warning if it doesn't know your NS.
locator = Pyro.naming.NameServerLocator() ns = locator.getNS()
ns
now contains a reference. There are more advanced ways to get a
reference to the NS, please read the chapter about the Name Server to
find out about them.
Pyro.core.ObjBase
.
There are three ways to achieve this:
Pyro.core.ObjBase
and your original class.
The class body can be a simple 'pass
'. If you want to add a custom __init__
method, make sure you call the __init__
method of Pyro.core.ObjBase
and of your own class, if it has one.
class ObjectImpl(Pyro.core.ObjBase, test.MyClass): def __init__(self): Pyro.core.ObjBase.__init__(self) test.MyClass.__init__(self) ... obj = ObjectImpl() ... use obj ...
Pyro.core.ObjBase
you just create that object and tell it to use your own object as a delegate, by calling the delegateTo
method.
obj = Pyro.core.ObjBase() myobj = MyClass() obj.delegateTo(myobj) ... use obj ...
Pyro.core.ObjBase
. This is the least hassle but you have to change existing code if
you want to make classes suitable for Pyro.
class MyPyroObj(Pyro.core.ObjBase): def __init__(self): Pyro.core.ObjBase.__init__(self) ...obj init here... ... obj = MyPyroObj() ... use obj ...
Pyro.core.ObjBase
gives us). But Pyro still knows nothing about them.
We have to let Pyro know we've created some objects and how they are called. Only then can they be accessed by remote client programs. So let's connect our objects with the Pyro Daemon we've created before (see above):
daemon.connect(obj,'our_object')That done, the daemon has registered our object with the NS too (if you told it where to find the NS, see above). The NS will now have an entry in its table that connects the name "our_object" to our specific object.
connect
method actually returns the URI that will identify this object. You can ignore this if you don't want to use it immediately without having to consult the name service.
In contrast to the simple (flat) name shown above ("our_object"), Pyro's Name Server supports a hierarchical object naming scheme. For more information about this, see the Name Server chapter.
daemon.requestLoop()
is enough.
For finer control, you can give a few arguments to the function:
requestLoop(condition, timeout, others, callback)All arguments are optional. The default is that
requestLoop
enters
an endless loop waiting and handling Pyro requests.
You can specify a condition
callable object (for instance, a lambda function)
that is evaluated each cycle of the loop to see if the loop should continue (the condition
must evaluate to 1).
The timeout
can be used to adjust the timeout between loop cycles (default=3 seconds).
The others
and callbacks
can be used to add your own socket or file
objects to the request handling loop, and act on them if they trigger.
For more details, see the paragraph below.
For those that like to have more control over the request handling loop,
there is also handleRequests
. Usually your loop will look something like this:
while continueLoop: daemon.handleRequests(3.0) ... do something when a timeout occured ...The timeout value in this example is three seconds. The call to
handleRequests
returns when the timeout period has passed, or when at least one request was processed.
You could use '0
' for timeout, but this means the call returns directly if no requests are pending. If you want infinite timeout, use 'None
'.
You can also provide additional objects the daemon should wait on (multiplexing), to avoid having to split
your program into multiple threads.
You pass those objects, including a special callback function, as follows:
daemon.handleRequests(timeout, [obj1,obj2,obj3], callback_func)The second argument is a list of objects suitable for passing as ins list to the
select
system call. The last argument is a callback function.
This function will be called when one of the objects in your list triggers. The function is called with one argument: the list of ready objects.
For more information about this multiplexing issue, see the manual page about the Un*x select
system call.
This concludes our server. Full listings can be found in the Example chapter.
Pyro.core.initClient()If you provide the argument '0', no banner is printed, otherwise a short message is printed on the standard output. If the tracelevel is not zero, a startup message is written to the log. This message shows the active configuration options.
ns
now contains the proxy for the NS.
uri = ns.resolve(`my_object')
PyroURI
object before you use it. Just pass it to the constructur of PyroURI
and you'll be fine.
PYRONAME://
or PYROLOC://
URI strings.
The first is a shortcut to the Name Server, the second bypasses the Name Server completely.
Read more about them in the chapter on the Name Server, "The special PYRONAME:// and PYROLOC:// URIs".
pyroc
has generated the mymodule_proxy.py
proxy module.
obj = Pyro.core.getProxyForURI(uri) # get a dynamic proxy obj = Pyro.core.getAttrProxyForURI(uri) # get a dyn proxy with attribute support obj = mymodule_proxy.myobject(uri) # get a static proxy (also w/ attrib support)
obj.method(arg1, arg2) print obj.getName() a = obj.answerQuestion('What is the meaning of life?') # the following statements only work with a attribute-capable proxy: attrib = obj.attrib obj.sum = obj.sum+1or whatever methods your objects provide. The only thing to keep in mind is that you need a proxy object whose methods you call.
This concludes our client. Full listings can be found in the Example chapter. For information on using Pyro's logging/tracing facility, see Runtime control and Logging, below.
ns
utility.
See Pyro script tools. After starting it will print some information and then the Name Server sits in a loop waiting for requests:
irmen@atlantis:~ > projects/Pyro/bin/ns *** Pyro Name Server *** Pyro Server Initialized. Using Pyro V2.4 Will accept shutdown requests. URI written to: /home/irmen/Pyro_NS_URI URI is: PYRO://10.0.0.150:9090/0a000096-08620ada-6697d564-62110a9f Name Server started.The NS writes its URI to a file, as it says. This file can be read by other programs, and this is another -very portable- way to discover the NS. Usually you'll want to use the default mechanism from the
NameServerLocator
(automatic discovery using broadcasting). This is easier. But if your network doesn't support broadcasting, or the NS can't be reached by a broadcast
(because it sits on another subnet, for instance), you have to use another method to reach the NS.
nsc
command-line utility or the xnsc
graphical tool for this purpose,
see Pyro script tools.
Pyro.util.Log
object, which is an instance of Pyro.util.SystemLogger
. System log tracelevel is configured using the PYRO_TRACELEVEL
config item, the logfile location is configured using the PYRO_LOGFILE
config item.
Pyro.util.UserLogger
instance. User log tracelevel is configured using the PYRO_USER_TRACELEVEL
config item, the user logfile location is configured using the PYRO_USER_LOGFILE
config item.
msg(source, *args)
- log a simple message (note). source
is a string that identifies the source of the log entry, after that, any argument may follow to be printed in the logfile.
error(source, *args)
- log an error. source
is a string that identifies the source of the log entry, after that, any argument may follow to be printed in the logfile.
warn(source, *args)
- log a warning. source
is a string that identifies the source of the log entry, after that, any argument may follow to be printed in the logfile.
raw(string)
- log a string (unformatted). string
is the string to write to the logfile. This logging is done unconditionally, the tracelevel setting has no influence here.
2002-01-16 16:45:02 ** ERR! ** NameServerLocator ** Name Server not responding
"raw
method can have any format, including multiple lines.
These chapters contain invaluable information about the more detailed aspects and possibilities of Pyro.
<previous | contents | next> | Pyro Manual |