This page describes the Ice router facility.
On this page:
A router is an Ice object that provides information to the Ice run time to allow routing messages between clients and servers. In a client, configuring a proxy to use a router produces a routed proxy on which all invocations are sent to the router for forwarding to the target server. The endpoints in a routed proxy are ignored by the Ice run time, at least for the purposes of connection establishment. Instead, the Ice run time in the client establishes a connection to the router and may pass along the proxy's endpoints so that the router can establish its own connection to the target server. Ice typically opens only one connection to a router and reuses that connection for invocations on all of the routed proxies configured to use the same router.
The Ice distribution includes two router implementations that serve different purposes:
- Glacier2 is a sophisticated routing service that is commonly used as a single point of entry through which clients on public networks access back-end services on an internal network, with support for application-specific session management and access control.
- IceBridge is a simpler service that facilitates bridging connections over different transports.
Both services implement the
Ice::Router interface, which the Ice run time requires of any router implementation.
A communicator can be configured with a default router. The most common way to configure the default router is to set the property
Ice.Default.Router. The value of this property is a proxy for the router's primary Ice object, as shown in the example below for Glacier2:
You can also specify a default router by calling
setDefaultRouter on the communicator, and obtain the current setting using
Proxies created with this communicator are configured with this router by default (see below). Object adapters created with this communicator are not affected by the default router.
Configuring a Router for Client Invocations
Setting a default router as described above means every proxy created by the communicator will be configured to use the router by default. If your client needs to use a router more selectively, you can use the
ice_router proxy method to obtain a routed proxy:
As with all proxy factory methods,
ice_router returns a new proxy with the requested configuration.
Another way to configure a router is with a proxy property:
In this example, calling
propertyToProxy("MyProxy") on a communicator returns a proxy that is already configured to use Glacier2.
Configuring a Client for Callbacks
A client that needs to receive callbacks from the server through the router creates an object adapter that hosts callback objects and associates the router with this object adapter. You create this object adapter-router association using the property
adapter.Router (in the object adapter's configuration), or by creating the object adapter with
This is a one-to-one association: an object adapter can be associated with a single router and likewise a router can be associated with only one object adapter.
When the object adapter is created, it calls
setAdapter on the connection between the client and the router. This connection is either reused (if a connection to the router already existed) or established during the creation of the object adapter. Later, when the server calls on a proxy to the callback object, the router forwards the request to the object adapter over this bidirectional connection between the client and the router.
There are two differences between an object adapter that you configure for bidirectional dispatch (with
setAdapter on a connection) and an object adapter configured with a router:
- You can call
setAdapterwith the same object adapter on multiple connections, whereas you can have only one router associated with a given object adapter.
- The endpoints of the proxies created by an object adapter with a configured router are the endpoints of the proxy returned by
getServerProxy, which typically point to the "server-side" of the router. Endpoints and published endpoints configured for this object adapter are ignored. This way, the client can give these proxies to the server (via the router), and when the server sends a request using such a proxy, the request is directed to the router and then forwarded to the client's object adapter. An object adapter configured for bidirectional dispatch (without a router) uses
PublishedEndpointsas usual to compute the published endpoints of the proxies it creates; usually you will leave
PublishedEndpointsempty and the object adapter will create proxies with no endpoints at all.
See Callbacks through Glacier2 for an example.
A router implementation may optionally maintain an internal routing table that the Ice client run time populates automatically by calling
For example, Glacier2 uses a routing table because it can forward requests to any number of back-end servers, whereas IceBridge does not use a routing table because each IceBridge instance is statically configured to forward requests to a single server. When a client makes an initial invocation on a routed proxy, and the configured router uses a routing table, the Ice run time in the client needs to send that routed proxy to the router so that the router has the endpoint information necessary to establish a connection to the back-end server. The Ice run time in the client also maintains its own local version of the routing table in order to minimize overhead; Ice only sends each routed proxy to the router once. Furthermore, Ice keeps its table synchronized with the router's by tracking any proxies that the router might have evicted from its table (the proxies returned by the call to
Ice uses object identities as the keys in its routing table, which means it's important that your Ice objects use unique identities.
If a router receives an invocation to be forwarded for an object identity that is not in its routing table (e.g., it may have been recently evicted), the router raises
Ice::ObjectNotExistException and sets the
operation member to the reserved value
ice_add_proxy in order to notify the Ice run time in the client that the routed proxy is unknown. The Ice client run time must therefore register the proxy with the router and retry the invocation.