开发者

Java Socket RPC protocol

I've been asking some questions about adapting the command protocol for use in my client server environment. However, after some experimentation, I have come to the conclusion that it will not work for me. It is not designed for this scenario. I'm thus at a loose end.

I have implemented a sort of RPC mechanism before whereby I had a class entitled "Operation". I also had an enum entitled "Action" that contained names for actions that could be invoked on the server.

Now, in my old project, every time that the client wanted to invoke an action on the server, it would create an instance of 'Operation' and set the action variable with a value from the "Action" enum. For example

Operation serverOpToInvoke = new Operation();

serverOpToInvoke.setAction(Action.CREATE_TIME_TABLE);

serverOpToInvoke.setParameters(Map params);

ServerReply reply = NetworkManager.sendOperation(serverOpToInvoke);

...

On the server side, I had to perform the horrible task of determining which method to invoke by examining the 'Action' enum value with a load of 'if/else' statements. When a match was found, I would call the appropriate method.

The problem with this was that it was messy, hard to maintain and was ultimately bad design.

My question is thus - Is there some sort of pattern that I can follow to implement a nice, clean and maintainable rpc mechanism over a TCP socket in java? RMI is a no go for me here as the client开发者_如何学运维 (android) doesn't support RMI. I've exhausted all avenues at this stage. The only other option would maybe be a REST service. Any advice would be very helpful.

Thank you very much Regards


Probably the easiest solution is to loosely follow the path of RMI.

You start out with an interface and an implementation:

interface FooService  {
  Bar doThis( String param );
  String doThat( Bar param );
}

class FooServiceImpl implements FooService {
  ...
}

You deploy the interface to both sides and the implementation to the server side only.

Then to get a client object, you create a dynamic proxy. Its invocation handler will do nothing else but serialize the service classname, the method name and the parameters and send it to the server (initially you can use an ObjectOutputStream but you can use alternative serialization techniques, like XStream for example).

The server listener takes this request and executes it using reflection, then sends the response back.

The implementation is fairly easy and it is transparent from both sides, the only major caveat being that your services will effectively be singletons.

I can include some more implementation detail if you need, but this is the general idea I would follow if I had to implement something like that.

Having said that, I'd probably search a bit more for an already existing solution, like webservices or something similar.

Update: This is what an ordinary (local) invocation handler would do.

class MyHandler implements InvocationHandler {

    private Object serviceObject;

    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        return method.invoke(serviceObject, args);
    }
}

Where serviceObject is your service implementation object wrapped into the handler.

This is what you have to cut in half, and instead of calling the method, you need to send the following to the server:

  1. The full name of the interface (or some other value that uniquely identifies the service interface)
  2. The name of the method.
  3. The names of the parameter types the method expects.
  4. The args array.

The server side will have to:

  1. Find the implementation for that interface (the easiest way is to have some sort of map where the keys are the interface names and the values the implementation singleton instance)
  2. Find the method, using Class.getMethod( name, paramTypes );
  3. Execute the method by calling method.invoke(serviceObject, args); and send the return value back.


You should look into protocol buffers from google: http://code.google.com/p/protobuf/

This library defines an IDL for generating struct like classes that can be written and read from a stream/byte array/etc. They also define an RPC mechanism using the defined messages.

I've used this library for a similar problem and it worked very well.


RMI is the way to go.

Java RMI is a Java application programming interface that performs the object-oriented equivalent of remote procedure calls (RPC).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜