RPC/XDR server is supported by two primary classes implemented at the system layer:
In addition, if an error occurs, then an instance of the following class will be returned:
The following sections discuss how to establish a RPC server.
Defining a RPC server is a seven-step process. PortMapper must be running for the server to work correctly.
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.
Next you need to define your input and output records for each server procedure.
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.
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.
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)).
Create an instance of the class whose instance methods are used as the server procedures. Use the receiver: method to associate the instance with the server.
(server := AbtRPCServer new) connectionSpec: connspec; receiver: MyClass new.
u 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.
Next you need to create a server handle and register with PortMapper.
result := server createServerHandle.
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.
To end the server and clean up the resources, execute the following.
result := server serverFree.
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 ].