The OMG agreed protocol for ORB interoperability is called the General Inter-ORB Protocol (GIOP). GIOP defines the on-the-wire data representation and message formats; it also makes general assumptions about the nature of the transport layerin particular, that it is connection-oriented. A goal of the GIOP specification is to allow different ORB implementations to communicate without restricting ORB implementation flexibility.
The OMG defines a specialisation of GIOP that uses TCP/IP as the transport layer. This specialisation is called the Internet Inter-ORB Protocol (IIOP). Specialised protocols for different transports (for example, OSI, Netware, IPX) or for new features (such as security) are expected to be defined by the OMG in due course.
There are many reasons why interoperability between the products of different ORB vendors is desirable. The core CORBA specification defines a standard for making invocations on an object via an ORB. A natural extension of this standard is that conforming implementations should allow invocations on objects from other conforming implementations. Within an organisation different ORBs may coexist reflecting separate development effort or different ORB requirements by different parts of the organisation and at some point, these ORBs may need to communicate.
We give an overview of the GIOP and IIOP specifications in section 9.1. Section 9.2 shows an example of using IIOP in OrbixWeb.
9.1 Overview of GIOP
This section provides an overview of the elements of the GIOP specification.1 It is provided primarily as background information.
9.1.1 Coding
The GIOP defines a transfer syntax known as Common Data Representation (CDR). CDR defines a coding for all IDL data types: basic types, structured types (including exceptions), object references and pseudo-objects such as TypeCode
s. 9.1.2 Message Formats
Seven message types are defined by GIOP. A common message header is defined for all messages which includes the message size, a version number indicating the version of GIOP being used, the byte ordering and the message type. Messages are exchanged between clients and servers. In this context, a client is an agent that opens connections and originates requests. A server is an agent that accepts connections and receives requests. The type of a message is one of the following:
Reply A Reply message is sent by a server to a client. A Reply message encodes an operation invocation response, including
inout
and out
parameters and exceptions. A server receiving a Request message may not be able to provide direct access to the target object. This may be because the target object has moved or because the server receiving the Request message provides a location service. To indicate this, a Reply may contain a
LOCATION_FORWARD
status and will also contain an indication of the new location. CancelRequest A CancelRequest message may be sent from a client to a server to notify the server that a reply to a particular pending Request or LocateRequest message is no longer expected.
LocateRequest A LocateRequest message may be used to probe for the location of a remote object. This might be appropriate where an operation's parameters are too large to transmit in a Request message that might return a
LOCATION_FORWARD
status. A LocateRequest message determines whether the target object reference is valid, whether the server can handle requests for that object or, if it returns a LOCATION_FORWARD
status indicates the location to which invocation on the reference should be sent.LocateReply A LocateReply message is sent by a server to a client in response to a LocateRequest message. It may contain a new IOR.
CloseConnection A CloseConnection message is sent by a server to inform clients that it intends to close the connection. Any messages for which clients have not received a reply may be reissued (on another connection).
MessageError A MessageError message may be sent by a client or a server in response to any message whose message type or version number is unknown to the receiver of the message or whose message header is not properly formed.
LOCATE_FORWARD
status in a Reply message by transparently reissuing the call. Similarly, use of the LocateRequest
message is an optional optimization.
An object accessible via IIOP is identified by an interoperable object reference (IOR). Since the format of normal object reference is not prescribed by the OMG, the format of an IOR includes an ORB's internal object reference as well as an internet host address and a port number. An IOR is managed internally by the interoperating ORBsit is not necessary for an application programmer to know the structure of an IOR.
As described in Chapter 7, "Publishing Object References in Servers", there are several ways in which a server can publish an object reference or IOR for retrieval by clients. Again, in this respect the protocol used does not affect the options available to application programmers.
However, IIOP has two important advantage over the Orbix protocol: the first is simply interoperability with other ORBs, and the second is the availability of servers which have no platform-specific requirementswhich is especially important in the Java domain.
processEvents()
or processNextEvent()
, instead of impl_is_ready()
, on the _CORBA.Orbix
object.
_bind()
method.
processEvents()
and processNextEvent()
can be used to accept incoming OrbixWeb requests in a similar manner to impl_is_ready()
, but these methods do not require the initialisation of an OrbixWeb server name.
processEvents()
to handle client invocations on that IOR. The client simply retrieves the IOR using the Naming Service and invokes operations on the server object.The example is based on the following IDL interface representing a two dimensional grid.
// IDL // In file grid.idl. interface Grid { readonly attribute short height; readonly attribute short width; void set(in short n, in short m, in long value); long get(in short n, in short m); };
-m
switch as follows:
idl -m IIOPOnly grid.idlHowever, this is the default setting, so it is not necessary to specify the
-m
switch in order to use IIOP.Alternative values for the
-m
switch are orbixOnly
, which generates support for the Orbix protocol, and interOp
, which allows both protocols to be used. IDL definitions which are not compiled with the setting orbixOnly
or the setting interOp
cannot be accessed using the native Orbix protocol.
GridImplementation
implements interface Grid
.
// Java // Server main() method. // In file GridServer.java. import CosNaming._NamingContextRef; import CosNaming.Name; import IE.Iona.Orbix2._CORBA; import IE.Iona.Orbix2.CORBA.SystemException; import IE.Iona.Orbix2.CORBA._ObjectRef; class GridServer { public static void main(String args[]) { // Assume TIE approach. _GridRef gridImpl; // Declare Naming service types. _ObjectRef initRef; _NamingContextRef initContext; _NamingContextRef objectsContext; _NamingContextRef mathContext; Name name; try { // Create implementation object. gridImpl = new _tie_Grid (new GridImplementation (100,100)); } catch (SystemException se) { // Details omitted. } try { // Find initial naming context. initRef = _CORBA.Orbix.resolve_initial_references ("NameService"); initContext = NamingContext._narrow (initRef); // A CosNaming.Name is simply a sequence // of structs. name = new Name (1); name.buffer[0].id = new String ("objects"); name.buffer[0].kind = new String (""); // (In one step) create a new context, // and bind it relative to the // initial context: objectsContext = initContext.bind_new_context (name); name.buffer[0].id = new String ("math"); name.buffer[0].kind = new String (""); // (In one step) create a new context, // and bind it relative to the // objects context: mathContext = objectsContext.bind_new_context (name); name.buffer[0].id = new String ("grid"); name.buffer[0].kind = new String (""); // Bind name to object gridImpl in context // objects.math: mathContext.bind (name, gridImpl); } catch (SystemException se) { // Details omitted. } try { // Call processEvents() to process // client invocations. _CORBA.Orbix.processEvents (); } catch (SystemException se) { // Details omitted. } } }This server instantiates a TIE object for interface
Grid
. By default, OrbixWeb automatically identifies this object using an IOR. The server then resolves the initial context in the Naming Service and associates the compound name objects.math.grid
with the IOR, in the manner described in Chapter 7, "Publishing Object References in Servers". Finally, the server enters an OrbixWeb event processing loop by calling processEvents()
.
Programming the Client
This client program resolves the name objects.math.grid
to locate the object reference published by the server using the Naming Service. The interoperable object reference retrieved from the Naming Service must be narrowed to an object reference of the appropriate interface before operations can be invoked on it in the normal way.
// Java // Client application code. // In file Client.java. import CosNaming._NamingContextRef; import CosNaming.Name; import IE.Iona.Orbix2._CORBA; import IE.Iona.Orbix2.CORBA.SystemException; import IE.Iona.Orbix2.CORBA._ObjectRef; public class Client { public static void main (String args[]) { _NamingContextRef initContext; Name name; _ObjectRef initRef, objRef; _GridRef gRef; try { // Find initial naming context. initRef = _CORBA.Orbix.resolve_initial_references ("NameService"); initContext = NamingContext._narrow (initRef); // Set up name and contexts. name = new Name (3); name.buffer[0].id = new String ("objects"); name.buffer[0].kind = new String (""); name.buffer[1].id = new String ("math"); name.buffer[1].kind = new String (""); name.buffer[2].id = new String ("grid"); name.buffer[2].kind = new String (""); // Resolve the name. objRef = initContext.resolve (name); gRef = Grid._narrow (objRef); } catch (SystemException se) { // Details omitted. } try { w = gRef.width(); h = gRef.height(); } catch (SystemException se) { // Details omitted. } System.out.println("height is " + h); System.out.println("width is " + w); try { gRef.set((short)2,(short)4,123); v = gRef.get((short)2,(short)4); } catch (SystemException se) { // Details omitted. } System.out.println( "value at grid position (2,4) is " + v); } }
The mechanism required to register a server in the Implementation Repository is independent of the server protocol. However, an additional registration option is available to servers which use IIOP, as described in "Configuring an IIOP Port Number for an OrbixWeb Server".
In order to use
_bind()
to resolve IORs in an OrbixWeb client, the server must be registered in the Implementation Repository (unless the OrbixWeb daemon is run with the -u
switch) and the server must call impl_is_ready()
to initialise its server name. In addition, the client must be configured to use IIOP in OrbixWeb communications (which is the default case).Configure
allows a programmer to specify, during compilation, several configuration variables including the default protocol to be used when the client binds to a server object. In the context of using IIOP in a _bind()
call, this class allows the following values to be modified:
// Configure Class // In file Configure.java. package IE.Iona.Orbix2; public class Configure { private Configure() {} static { // Set bind communications protocol. _CORBA.IT_BIND_USING_IIOP = true; // Port number for communicating with // OrbixWeb daemon using IIOP. _CORBA.IT_ORBIXD_IIOP_PORT = 1571; // Other details omitted. } }This default assignment for
_CORBA.IT_BIND_USING_IIOP
allows calls to _bind()
which use IIOP. This assignment may be changed to the following:
// Set bind communications protocol. _CORBA.IT_BIND_USING_IIOP = false;In this case, calls to
_bind()
can only use the Orbix protocol. The variable
_CORBA.IT_ORBIXD_IIOP_PORT
specifies the port number on which the OrbixWeb daemon listens for incoming IIOP requests. When calling _bind()
using IIOP, it is important that the client's setting for this variable matches the OrbixWeb daemon IT_IIOP_PORT
value, as set in the OrbixWeb configuration file, Orbix.cfg
.Note that class
Configure
must be recompiled if a configuration value is modified. See Chapter 3, "OrbixWeb Configuration" of the OrbixWeb Reference Guide for further details of configuration issues.
Specifying a Communications Port for the OrbixWeb Daemon
It is important to note that the OrbixWeb daemon process listens for incoming OrbixWeb events on two communications channels: one for Orbix protocol messages, the other for IIOP messages. If a client wishes to invoke _bind()
using IIOP, then it should ensure that it communicates with the OrbixWeb daemon using the daemon IIOP port number and not the Orbix protocol port. For details, see Chapter 3, "OrbixWeb Configuration" of the OrbixWeb Reference Guide.
9.2.3 Configuring an IIOP Port Number for an OrbixWeb Server
Using IIOP, an OrbixWeb server must listen for client connection requests on a fixed TCP/IP port. The port number for each server is assigned by OrbixWeb on start-up._CORBA.IT_IIOP_USE_LOCATOR
to false
in the server, as follows:
// Java import IE.Iona.Orbix2._CORBA; ... _CORBA.IT_IIOP_USE_LOCATOR = false;This setting must be applied before any IORs are created in the server.
During registration of a server in the Implementation Repository, a well-known port for a server can be specified using the
putit
-port
switch, for example:
putit serverName -java -port portNumber ...If
_CORBA.IT_IIOP_USE_LOCATOR
is set to true
and a port number has been specified for the server in this manner, then the OrbixWeb daemon will attempt to assign the required IIOP port to the server. If that port is not available, then an attempt to create an IOR in the server will raise a system exception.If
_CORBA.IT_IIOP_USE_LOCATOR
is set to false
, and a port number has not been specified in a putit
command, then the OrbixWeb daemon will assign a default well-known port to the server.A server which does not depend on the availability of an OrbixWeb daemon process should set
_CORBA.IT_IIOP_USE_LOCATOR
to false. In this case, an alternative mechanism is required to allow the server to establish a well-known IIOP port number. This can be achieved by altering class Configure
before compilation of the server.Class
Configure
includes the following variable setting:
// Configure Class // in file Configure.java package IE.Iona.Orbix2; public class Configure { private Configure() {} static { // Server listen port for IIOP protocol. _CORBA.IT_IIOP_LISTEN_PORT = 0; // Other details omitted. ... } }A server programmer may edit the setting for the
_CORBA.IT_IIOP_LISTEN_PORT
variable and then recompile this class. The value of _CORBA.IT_IIOP_LISTEN_PORT
can also be reassigned in an OrbixWeb server by simply adding the lines:
// Java // Variable "port" indicates some int value. IE.Iona.Orbix2._CORBA.IT_IIOP_LISTEN_PORT = port;This approach is only effective if the new value is assigned before the creation of any IORs in the server. The value of
_CORBA.IT_IIOP_LISTEN_PORT
has no significance if _CORBA.IT_IIOP_USE_LOCATOR
is set to true
.If
_CORBA.IT_IIOP_LISTEN_PORT
is set to zero, then the server will not be associated with a well-known port numberthat is, an IIOP port will be dynamically assigned to the server on start-up.
any
to Java type Any
(defined in package IE.Iona.Orbix2.CORBA
). In an OrbixWeb application, it is necessary to specify the protocol which will be used to marshal an any
value during creation of the any
. For this reason, the Java type Any
includes constructors which allow the desired protocol to be configured.
These constructors are defined as follows:
// Java // in package IE.Iona.Orbix2.CORBA, // in class Any public Any (int kind); public Any (Any a, int kind);where the variable
kind
is an integer with one of the following values:
|
|
The constant value
_CORBA.IT_ORBIX_OR_KIND
(defined in package IE.Iona.Orbix2
) indicates that the any
will be marshalled using the Orbix protocol; the value _CORBA.IT_INTEROPERABLE_OR_KIND
indicates that the any
will be marshalled using the IIOP protocol. When OrbixWeb is installed, the default protocol for marshalling of
any
values is IIOP. In the next subsection, we will describe how this default value may be configured during client compilation.
Configure
allows a programmer to specify, during compilation, the default communications protocol to be used when marshalling any
s. In this context, the relevant section of this class is:
// Configure Class // In file Configure.java. package IE.Iona.Orbix2; public class Configure { private Configure() {} static { // Default protocol for marshalling // of any. _CORBA.IT_BIND_USING_ANY = true; // Other details omitted. } }In order to specify which protocol should act as the default for type
any
marshalling, the programmer should do the following:
Configure
, and set the IT_BIND_USING_IIOP
variable value to false
(to use the Orbix protocol) or true
(to use IIOP).
Configure.class
file (in package subdirectory IE/Iona/Orbix2
).
Tel: 508-820 4300