From: Screamin Lord Byron on
On 07/23/2010 12:42 PM, Screamin Lord Byron wrote:

> Some short example of the registration would be very helpful and
> appreciated.

I guess this is not needed anymore, as it turns out it works like this
by default.


>>> public interface Bar extends Remote {
>>> public void mutate();
>>> }
>>
>> You don't need to create *any* implementations of BarImpl until somebody
>> calls constructBar(), and you never need to bind them to the Registry.

This remains a very helpful piece of information, as I'm now assured
it's safe to remove all of that unneeded Bar rmi registration nonsense I
wrote.

Anyways, thanks to all for clearing this up for me.

Cheers!
From: Michal Kleczek on
Screamin Lord Byron wrote:

>
> What matters is that players can't just play any card they like (they
> must follow suit, etc.). The Player class has the hand field which
> contains 8 cards (that class is what the BarImpl represents in my
> example).n
>
> The dealing part is done on the server. The idea is this. At the
> begining of the game, all clients (one for each player) must send the
> name of the player (and possibly some ID) by invoking some construction
> code (something like constructBar() in my example), and it receives a
> Player remote object from the server (which already contains his cards).

How do you handle client crashes? Do you want to rely on RMI DGC? Or maybe
you want to handle it explicitly.

>
> When player chooses a card to play, the server must check if it's a
> valid move. Client uses a chooseCard(Card c) method of the Player class
> which marks the chosen card and enables the game logic on the server to
> check it and proceed if it's ok (remove it from hand). What I want to do
> is to call player.chooseCard(card) from the client. Of course, this
> means that the client's player object must not be a mere copy of the
> server's player object, but it must be a remote object.
>
> Well, that's the idea, and also the problem. :) Of course, it would be
> easier to do it without RMI with some simple quickly-made-up
> communication protocol, but I'm just curios is it possible to make it
> work as I imagined with RMI.

RMI is a pretty good choice IMO. But Jini is better :)

>
> The issues like how to notify all clients that the card is played and
> such are not important right now. I have some idea on how to handle that.

Is the client going to export some listener object and hand it to the server
so that it can use it for notification?

I think you should look at Jini (Apache River now). It has all the basic
infrastructure to handle distributed applications like this - namely:
leasing and remote events. Even better - your game would be a good candidate
to use a JavaSpace.

--
Michal
From: Screamin Lord Byron on
On 07/23/2010 03:23 PM, Michal Kleczek wrote:

> How do you handle client crashes? Do you want to rely on RMI DGC? Or maybe
> you want to handle it explicitly.

I'm not sure I understand what you mean by client crashes -- didn't get
to that point yet. :) I will rethrow all checked exceptions to the
client, and let client handle them. For example, I have one Game object
for each game (involving 4 clients), and it's a state machine. The state
dictates which methods are allowed to be called (for example, it's
illegal to call throwCard() if the state is "bidding", and so on)

I'm yet to discover what happens when connection breaks. It's a part of
the learning process. :) But it's a simple program and the clients are
dumb (all of the heavy lifting is done on the server), so I shouldn't be
in too much trouble and it should be fairly easy to debug.


>> The issues like how to notify all clients that the card is played and
>> such are not important right now. I have some idea on how to handle that.
>
> Is the client going to export some listener object and hand it to the server
> so that it can use it for notification?

Well, that would require the client to act as server (what I want to
avoid), but if nothing else will work then that's the way it will be. I
was actually thinking of blocking the call of one client/player until
the next makes its move, and then return that next player's move, and so
on. How would that work?

Something like:
while(!g.trickFinished()) {
if (g.isOnTurn())
if(!g.playCard(Card c))
continue; // bad card
else
played = c; // good card
else
played = g.checkPlayedCard(); // blocks until card from
// some other player is played
trick.add(played);
...
}

Server will make sure to report checkPlayedCard() 3 times for each
player not on turn per turn and it will be done in correct turn order
(possibly even return an ordered list or queue of all cards played in
the current trick).

This could also check for exceptions in case of client crashes. I'm just
not sure are remote calls that could block for a long time a problem for
RMI (will some kind of timeout occur?).


> I think you should look at Jini (Apache River now). It has all the basic
> infrastructure to handle distributed applications like this - namely:
> leasing and remote events. Even better - your game would be a good candidate
> to use a JavaSpace.

Thanks for the suggestion. I will certainly take a closer look at Jini
for some real projects, but I believe it could be a slight overkill for
this particular application.
From: Esmond Pitt on
> initialContext.bind("rmi:my_foo", myFoo);

initialContext.bind("rmi://localhost:1099/my_foo", myFoo);

You don't need the 1099 unless it isn't 1099 for some reason, but you do
need the hostname. However as for an RMI bind it must be localhost there
is no point in specifying anything else ;-) e.g. a real hostname.
From: Screamin Lord Byron on
On 07/26/2010 05:30 AM, Esmond Pitt wrote:
>> initialContext.bind("rmi:my_foo", myFoo);
>
> initialContext.bind("rmi://localhost:1099/my_foo", myFoo);
>
> You don't need the 1099 unless it isn't 1099 for some reason, but you do
> need the hostname.

If you don't specify the hostname I suppose it defaults to localhost, as
"rmi:my_foo" works just fine in my case.


> However as for an RMI bind it must be localhost there
> is no point in specifying anything else ;-) e.g. a real hostname.

That's if you're running the rmiregistry service that is part of the
JDK, as that service only allows binding calls from the same host.
However, RMI architecture allows for a more general RMI registry
implementation that supports multiple servers (Cay S. Horstman, Gary
Cornell: Core Java, Volume II - Advanced Features, 8th edition, page 853)