Is it ok to use multiple objects for RMI communication
Scenario:
- Client C connects to Server S via RMI
- C asks S to create a handler H, S returns H to C
- C then talks to H
Now I could do this in two ways:
- Make the handler a
Remote
and let S return the stub to it, so C can directly talk to that (h.say(String msg);
) - Give the handler an ID and return that to C. C will talk to H via S (
s.sayToH开发者_JAVA技巧andler(int id, String msg);
)
The first is nicer OO, but what about the performance? Will an extra TCP connection be opened, or is the existing connection between S and H used?
I don't know about the implementation. I don't think a new connection is made. But what I know is the more objects you share remotely the more objects that depends on remote dereference to get garbage collected (so there will be more objects living longer, not good).
Alternative approach
I'll recommend a mixed approach. Use the nice approach for the client but implement it the not-so-nice-way internally:
interface Server {
public Handler getHandler(...);
}
interface Handler extends Serializable {
// it gets copied!
public X doThis(...);
public Y doThat(...);
}
class HandlerImpl implements Handler {
public X doThis(...) {
backDoor.doThis(this, ...);
}
public Y doThat(...) {
backDoor.doThat(this, ...);
}
private BackDoor backDoor;
}
interface BackDoor {
public X doThis(Handler h, ...);
public Y doThat(Handler h, ...);
}
class ServerImpl imlpements Server, BackDoor {
public Handler getHandler(...) {
return /*a handler with a self reference as backdoor, only ONE remote obj shared via TWO interfaces */
}
...
// it does everything
// it receives the handler
}
BackDoor and Handler are sync'ed interfaces. The first has the methods with Handler as argument, the later has the pure methods. I don't think it's a big deal. And the two different interfaces let you work cleanly without the client know nothing and allowing the thin serializable Handler's do the dirty work.
Hope you like it!
The RMI specification does not really say whether there should be a new connection or the existing one reused. The wire protocol allows both, using either multiplexing or one TCP connection per call (which might be reused for following calls to the same sever object, I'm not sure). If you need tunneling through HTTP, than only one message per connection is allowed.
I did not find anything on how to configure which type of protocol to use (other than disabling HTTP tunneling).
If you want to make sure that only one TCP connection is used, use custom client and server socket factories doing the tunneling of multiple connections though one themselves. This will probably be less efficient than what the RMI runtime system would be doing there.
精彩评论