RPC System [Version 3]

🚫
Exiled
Joined
Mar 22, 2009
Messages
247
Reaction score
80
I'm just releasing this in hopes of somebody taking the time to replace the RMI in OdinMS with an RPC System.

New: Version 3



Version 2:



Updates (v3):
- Added fireResponse(..) to both RPCClientContext and RPCClient
- Fixed a few bugs in the Event Listener handling code
- Fixed the DefaultRPCMessageDecoder so it doesn't screw up when there is data to decode.

Updates (v2):
- Event based mechanism
- Register event listeners rather than modifying the RPC code
- Much more abstract, RPCResponse and RPCRequest were both replaced with RPCMessage
- If you want to implement your own RPC encoder/decoder just subclass RPCMessageEncoder/RPCMessageDecoder and pass those to the constructor of RPCServer/RPCClient.
- The server can now send Requests, and the client can now send Responses.

How to use:

if you're registering a function listener:

Code:
object.registerRequestHandler(new MyRequestHandler());

if you're registering a response listener:

Code:
object.callRequest(myRequest, new MyResponseHandler());

be notified that response handlers will be removed after the response is received. Request handlers can only be added/removed via

Code:
object.registerRequestHandler

or

Code:
object.deregisterRequestHandler


Compiled JAR:



Source (RAR):



There are also two test files

net.idgames.server.rpc.test.TestRPCServer
net.idgames.server.rpc.test.TestRPCClient

to prove that the system works.

The system runs off MINA version 2.0, so please have that available.

The default way of calling an RPC Request would be like so:

client:

Code:
			DefaultRPCRequest request = new DefaultRPCRequest();
			request.setFunctionID(1);
			client.callRequest(request, new RPCResponseHandler() {
				@Override
				public void onResponse(IoSession session, RPCResponse response, SeekableLittleEndianAccessor slea) {
					System.out.println("onResponse [" + response.getFunctionID() + "/" + response.getRequestID() + "]");
				}
			});

Server:

Code:
			public void handleRequest(RPCClientContext client, RPCResponse request, SeekableLittleEndianAccessor slea) {
				System.out.println("handleRequest [" + request.getFunctionID() + "/" + request.getRequestID() + "]");
				DefaultRPCRequest response = new DefaultRPCRequest();
				response.setFunctionID(2);
				response.setRequestID(request.getRequestID());
				server.fireResponse(client, response);
			}

Credits:

Apache for supplying MINA

Frz for the SeekableLittleEndianWriter

Me for writing the RPC system

Oh, and you may have to change some things around for it to work, ie the imports.

And I know someone will ask this, so yes, this system is Asynchronous, ie, it uses "Future" objects instead of blocking on a thread waiting for a reply.

Well, i'm out.
 
Last edited:
Re: RPC System [Version 1]

Compiled JAR:


Source (RAR):
 
Re: RPC System [Version 2]

RMI = Sync

IDGRPC = Async

thats the difference, Sync has to block on a thread and wait for a reply, while Async just creates a listener and the listener is notified later.

---------- Post added at 01:39 PM ---------- Previous post was at 01:18 PM ----------

Version 3 is released.

Example of how my server uses the code:

Code:
	public void handle(RenoriaService service, RPCMessage message, SeekableLittleEndianAccessor slea) {
		if (service.isRegistered()) {
			service.terminate();
			System.out.println("Trying to register an already registered service.");
			return;
		}

		service.setServiceName(slea.readRenoriaAsciiString());
		service.setRegistered(true);
		Core.getCenter().writeLine("Service [" + service.getServiceID() + "] [" + service.getServiceName() + "] was successfully registered.");
		Core.getCenter().updateServices();
		DefaultRPCMessage response = new DefaultRPCMessage(message.getRequestID());
		response.setFunctionID(RPCResponseOps.TELL_SERVICE_ID);
		PacketWriter pw = new PacketWriter();
		pw.writeInt(service.getServiceID());
		response.setBytes(pw.getBytes());
		service.getClient().fireResponse(message);
	}
 
In my server it took 2 minutes ;)

basically just add:

Code:
RPCServer server = new RPCServer(...);
initiallizeRequestHandlers(); // Initiallize request handlers

Code:
RPCClient client = new RPCClient(...);
... Make a request here
client.callRequest(request, new RPCResponseHandler() {
.............
});

at least i've saved you the hassle of writing your own RPC implementation now, it took me 2 days of no sleep to write this (not really)
 
Last edited:
Back