PYRONAME://
, PYROLOC://
and
PYROLOCSSL://
URIsbin
directory that will start a Pyro Name Server for you:
pyro-ns
(Name Server)pyro-ns.cmd
pyro-nssvc
(Windows-only Name Server 'NT-service' control script)nssvc.cmd
script to register it as a service. Make sure you have Pyro properly installed in
your Python's site-packages. Or make sure to register the service using an account with the correct PYTHONPATH
setting, so that Pyro can be located. The NS service logs to C:\Pyro_NS_svc.log
, and writes its URI to
C:\Pyro_NS_URI.txt
(C: being your system drive).HKLM\System\CurrentControlSet\Services\PyroNS
, and the value under that key is:
PyroServiceArguments
(REG_SZ, it will be asked and created for you when doing a nssvc.cmd
install
from a command prompt).python -m
to start the tools:python -m Pyro.naming
- start the name serverpython -m Pyro.nsc
- start the nsc tool. Also works with xnsc and wxnsc.pyro-nsc
command (explained in the Usage chapter) you can control a Name Server that is
already running.
Consider setting PYRO_CHECKSUM to 1 before starting the NS. It will communicate more reliably and the overhead is very small.
If you want to start the NS from within your own program, you can ofcourse start it by executing
the start script mentioned above. You could also use the Pyro.naming.NameServerStarter
class to start it
directly (this is what the script also does). Be sure to start it in a separate process or thread because it will run
in its own endless loop. You probably have to wait until the NS has been fully started, call the
waitUntilStarted()
method on the starter object. It returns true if the NS has been started, false if it
is not yet ready. You can provide a timeout argument (in seconds).
Object names can be absolute or relative. Relative object names are searched in the default
group (which has a special name, set by PYRO_NS_DEFAULTGROUP
). Absolute names are always searched
from the root. Absolute object names start with a special character that signifies the root; the colon
(':
'). Relative object names don't have this character at the start.
Object names can be simple or compound. Compound object names consist of multiple parts
separated by a special group separator character: the dot ('.
'). Compound names are used to
search within the namespace hierarchy. Each component of the name is the name of a group. The last name component can
be the name of a group or an object (usually the latter).
Object name parts can only consist of the ASCII characters in the range 33-126 ('!'-'~') and except the backslash (\), dot ('.') and colon (':'). So spaces are also illegal in names, but normal slashes ('/') are okay.
Let's finish with a few examples to clarify all this. Note that by name alone you cannot distinguish a group name or an object name.
: |
The namespace root group |
:TestObj |
The TestObj name in the root (most likely an object name) |
:Test.simple.object1 |
The object1 name in the simple group in the Test group in the root. |
Test.simple.object1 |
The object1 name in the simple group in the Test group in the default group (which is ":Default" if not configured otherwise. This is the Default group in the root). |
object1 |
The object1 name in the default group. |
Pyro.naming.NameServer
)Pyro.naming.PersistentNameServer
)The persistent NS stores its naming database on disk. Currently this is implemented the easy way;
there is a direct mapping between the group names and directories on disk, and between object names
+ URIs and files in these directories on disk. The database by default is stored in a "Pyro_NS_database"
directory that is created in the directory configured by PYRO_STORAGE
.
You can specify a different name if needed (with the '-d' option of the name server start script,
and a parameter to the start method of the NameServerStarter
class in the code).
Usually you don't access the NameServer
or PersistentNameServer
classes directly: there
are scripts to start the right name server. Or you use the NameServerStarter
helper class from the
Pyro.naming
module.
connect
method of the daemon to connect your object instances to the daemon on the server. The daemon will register your
object with the name server too, if you supplied a NS to the daemon and your object isn't transient (it has a name).
But, when using the persistent name server, there is a complication here: if you didn't explicitly remove your object from the NS, the entry will still be there the next time. Your connect attempt will then fail because your object cannot be registered again in the NS.
The solution is to use the connectPersistent
method of the Pyro daemon. Except for the method name,
you call it exactly like the regular connect
method. It tries to find your object in the NS. If it's
there already, the previous URI is used for your object (that also means that the object's GUID is replaced by the
previous GUID that was found in the NS). If it isn't there, the regular connect
call takes over.
Of course you could always play safe and explicitly unregister any possible previous occurrences from the NS before you connect new instances. This is what all examples do by the way, so you can safely run an example again and again.
For your information, the code that starts the Persistent Name Server uses connectPersistent
to
connect the name server object to the daemon. Why? because the name server itself is also registered in the NS
database, and it is necessary that when the NS restarts, it uses the URI of the previous instance if found in the
persistent database.
Paired mode is activated by using the -1 and -2 options when starting the NS. 1
means: this is the first one, 2 means: this is the second one of the pair (this distinction is necessary because of a
slightly different startup procedure depending on being the first or the second).
You can add a hostname:port argument to the -1 and -2 option, that specify the location of the
other name server. So, for instance:
pyro-ns -n atlantis -p 4000 -1 atlantis:5000
to start NS #1,
pyro-ns -n atlantis -p 5000 -2 atlantis:4000
to start NS #2. But usually just -1 or -2 is good enough.
There are three new config items dealing with paired mode NS: PYRO_NS2_HOSTNAME
,
PYRO_NS2_PORT
and PYRO_NS2_BC_PORT
. They can be used to specify non-default values for the
hostname and port number that the second NS will use. See the config chapter.
Resync mechanism: Start A, then B. B remembers A's location (either discovered trough NS lookup or via command line URL). B notifies A that it has started, provides own location, and gets a copy of A's namespace database. A remembers B's location. Any namespace change in A is replicated in B and vice versa, using ONEWAY calls. If an error occurs, the reference to the faulty NS is discarded. If you discover that somehow the namespaces get out-of-sync, just kill the one that is faulty and restart it. It will automatically resync with the 'good' one.
With Identification: If you want to use paired mode together with identification (-i), you must supply the same identification argument to both name servers.
Pyro.naming
package. This object gets a Pyro proxy for the NS for you. Because this is the recommended
(and easiest way) to gain access to the Name Server, you're not interested in the internal name Pyro uses for the
Name Server. But for consistency, it is defined, and the Name Server object itself is known in the Name Server's
namespace under the name available in Pyro.constants.NAMESERVER_NAME
.
There are essentially three ways to get a reference to the Name Server:
NameServerLocator
's broadcast mechanism. This only works if your network supports
broadcasting and the NS is reachable by a broadcast request.
locator = Pyro.naming.NameServerLocator() ns = locator.getNS()
If your network doesn't allow broadcasts, or the broadcast can't reach the NS, this mechanism doesn't work. There
is a simple workaround: just set the PYRO_NS_HOSTNAME
config option to the hostname on which your NS can
be found. This disables the broadcast lookup and uses the one below instead.
For simplicity, if Pyro cannot find the name server using a broadcast search, it tries to contact
it directly on the machine itself and localhost. This allows you to use it even on a system
where the name server is running on localhost (for some reason) without having to set
PYRO_NS_HOSTNAME
to localhost
.
You can override the default broadcast address (255.255.255.255) by setting the bcaddr
parameter:
ns=locator.getNS(bcaddr="192.168.1.255")
NameServerLocator
's direct host mechanism. This only works if you know the host on which
the NS is located. The port
argument is optional. If the NS has been started using a non-default port
number you can use it to specify the port number.
locator = Pyro.naming.NameServerLocator() ns = locator.getNS(host='hostname', port=7777)If you specify the hostname yourself, the locator doesn't attempt to find the NS with the broadcast mechanism, and therefore there is no lookup delay. Also you can specify a port number different from the default port. If you set the
PYRO_NS_HOSTNAME
config option, the locator automatically uses the specified host for a direct lookup.
You don't have to pass Pyro.config.PYRO_NS_HOSTNAME
to the getNS
method.
Pyro_NS_URI
':
uri = open('Pyro_NS_URI','r').read() uri = Pyro.core.PyroURI(uri) # convert string to real URI object ns = Pyro.naming.NameServerProxy(uri) # create a proxy for the NS ... you can now invoke methods, such as ns.ping() ...Note: The URI changes every time a Pyro server or object is created. You cannot use a previously written URI when you have restarted the server.
Pyro.naming.NameServerProxy
) contains all necessary logic
already. So just use that one. If you use the locator (see above) you will get a correct proxy automatically.NameServerProxy
has an optional second argument: the
connection authentication information.
PYRONAME://
, PYROLOC://
and
PYROLOCSSL://
URIsPYRO://
URIs that the Name Server returns,
and where you then get a proxy object for, you use another URI format. This format is as follows: PYRONAME://nshostname:port/objectname
(PYRONAMESSL is not yet
implemented)nshostname
is the name of the host the Name Server is running on, and port
may be a
non-default port the Name Server is listening on. Both may be omitted. objectname
is the name of the
object you want to find! So, the next code fragment will find the NS using the default lookup mechanism, resolve the
object name to a real URI, create a proxy for that, and call a method:Pyro.core.getProxyForURI('PYRONAME://:Test.MyObject').getQuote()So we now have remote object method invocation in one statement :-) There is one important point: each time a
PYRONAME://
URI is used, a lookup for the Name Server has to be performed, and then a lookup for the
object name. This is much slower than the regular method. However, once you've constructed a proxy for this URI,
no more lookups are performed.
There is another special URI, that bypasses the Name Server completely:
PYROLOC://hostname:port/objectname
PYROLOCSSL://hostname:port/objectname
(use this if the server is running in SSL mode)
This time hostname
is required and is the name of the host that your target Pyro object runs on.
port
may be a non-default port the Pyro daemon is running on, and may be omitted.
objectname
is the internal name for the Pyro object you want to access. When you use this URI,
the Name Server is bypassed and the target server is contacted directly to get the regular URI for the desired
object. The advantage of this is that you don't have to have a Pyro Name Server running. The disatvantages are
obvious; you miss all the features of the Name Server and you have to administrate server object names yourself
somehow. You must use the name that is passed to the connect
method of the Daemon. There is no
hierarchical naming scheme because the Name Server is not used at all. Once the object is found, the real URI is
stored and no more lookups need to be done. The next code fragment shows how to call a remote object, without
requiring a Name Server to be present:
Pyro.core.getProxyForURI('PYROLOC://localhost/MyObject').getQuote()(Use
PYROLOCSSL://
if the server is running in SSL mode) Remember that your server does
not have to rely on a Name Server when you want to use this mechanism. When you enable Pyro logging,
you might get a WARN that a Name Server is not specified. You can ignore this. Please also see the
"noNS" example, that shows how to use this URI,
and also how you could connect directly by using an URI string that comes off the server.
resolve
.
There are more methods, see below. One very important thing to realize: all names you supply must be absolute,
i.e. ":Group.Objectname" instead of just "Objectname". The NameServerProxy
that
you'll usually be working with has some logic that takes care of this.
resolve(name)
register(name, URI)
unregister(name)
ping()
list(groupname)
flatlist()
createGroup(name)
deleteGroup(name)
fullName(name)
setMeta(name, meta)
getMeta(name)
nsc.py / xnsc.py
) for more info.