Using the RPC/XDR server system layer
RPC/XDR server is supported by two primary classes implemented at the system layer:
• AbtRPCConnectionSpec
• AbtRPCProcedures
• AbtRPCServer
In addition, if an error occurs, then an instance of the following class will be returned:
• AbtRPCError
The following sections discuss how to establish a RPC server.
Defining a RPC server
Defining a RPC server is a seven-step process. PortMapper must be running for the server to work correctly.
1. Create an instance of the AbtRPCConnectionSpec class
How
The AbtRPCConnectionSpec object represents the server that clients are going to communicate with. To create an instance of this class you need to provide the name or address of the server, the program and version numbers.
For Example:
nspec := AbtRPCConnectionSpec new
programNumber: 16r30099999;
programVersion: 1;
serverName: '9.67.167.75';
yourself.
2. Define the server program number, version and TCP address
3. Define the input and output records for each server procedure
How
inputRecord1 :=(AbtCompoundType new name: 'myinrcd1';
addField: (AbtCUIntField new name: #Field1; yourself);
addField: (AbtCUIntField new name: #Field2; yourself);
yourself) newRecord.
outputRecord1 :=(AbtCompoundType new name: 'myoutrcd1';
addField: (AbtCUIntField new name: #Result; yourself);
yourself) newRecord.
inputRecord2 := (AbtCompoundType new name: 'myinrcd2';
addField: (AbtCCharArrayField new
name: #Field1;count: 200; yourself);
yourself) newRecord.
outputRecord2 := (AbtCompoundType new name: 'myoutrcd2';
addField: (AbtCCharArrayField new
name: #Result;count: 400; yourself);
yourself) newRecord.
4. Create definitions of procedures that the server will respond to
You need to have created the procedures that will be initiated by the RPC server. Each instance method that represents a procedure should take both an input and output record as its input.
For example:
addNumbers: anInputRecord with: anOutputRecord
"this method will add two numbers in the input record and store the
results in the output record. This method is an instance method of
MyClass"
anOutputRecord
at: #Result
put: ((anInputRecord at: #Field1) +
(anInputRecord at: #Field2)).
changeString: anInputRecord with: anOutputRecord
"this method will concatenate the string in the input record with its
self and store the results in the output record. This method is an
instance method of MyClass"
anOutputRecord
at: #Result
put: ((anInputRecord at: #Field1) ,
(anInputRecord at: #Field1)).
5. Create an instance of the class whose procedures are invoked by the server
How
Use the receiver: method to associate the instance with the server.
(server := AbtRPCServer new)
connectionSpec: connspec;
receiver: MyClass new.
You need to create an instance of the AbtRPCProcedures class for each procedure the server is able to invoke. An AbtRPCProcedures instance contains the method name to be invoked and the input and ouput records it expects. AbtRPCServer expects an ordered collection of the procedure instances. The makeRows: method will create a collection of procedure instances and associate the collection with the server. If you use the makeRows: method, create a collection one larger than your needs. You must set the method name, input and output record values for all members of the ordered collection except the first one which gets set by default to the null proc.
result := server makeRows: 3.
(server procedures at: 2)
methodInvoked: #addNumbers:with:;
inputRecord: inputRecord1;
outputRecord: outputRecord1.
(server procedures at: 3)
methodInvoked: #changeString:with:;
inputRecord: inputRecord2;
outputRecord: outputRecord2.
6. Create a server handle
Next you need to create a server handle and register with PortMapper.
result := server createServerHandle.
7. Start the server
Next start your server that will loop forever waiting for client transaction requests.
When a request is received the server will invoke the procedure specified with both an input and output record. The output record will then be transmitted back to the waiting client.
server serverRun.
Unregister from PortMapper and destroy the server handle
To end the server and clean up the resources, execute the following.
result := server serverFree.
Handling Errors
In all the above cases it is possible for errors to occur because of failures in the network of logic in either the client or server application. Because of this, it is a good practice to test for errors after each call. Checking for errors is handled as follows:
result isCommunicationsError
ifTrue: [result display ].
Last modified date: 01/29/2015