The Artima Developer Community
Sponsored Link

Make Room for JavaSpaces, Part III
Coordinate your Jini Apps with JavaSpaces
by Susan Hupfer
First Published in JavaWorld, March 2000

<<  Page 5 of 10  >>


The Game Service

All the Jini responsibilities of a game service, including finding Jini lookup services and publishing the proxy used to connect to a game, are handled by the GameService class. Without some of the nitty-gritty Jini lookup and discovery code (which you can peruse in, here's what the game service code looks like:

public class GameService implements Runnable {
    protected JavaSpace space;
    protected Game game;


    // method that adds maxPlayers tickets to the named game to the space
    private void createTickets(String name, int maxPlayers) {
        // instantiate a game with the specified name
        try {
            game = new GameImpl(name);
        } catch (RemoteException e) {
        // write maxPlayers game tickets to the space
        for (int i = 0; i < maxPlayers; i++) {
            Ticket ticket = new Ticket(name, game);
            try {
                space.write(ticket, null, Lease.FOREVER);
            } catch (Exception e) {
    // method that creates a proxy object that implements the GameServiceInterface
    protected GameServiceInterface createProxy() {
        GameServiceInterface gameServiceProxy = new GameServiceProxy();
        return gameServiceProxy;
    public GameService(String gameName, int numTickets) throws IOException {
        space = SpaceAccessor.getSpace();
        item = new ServiceItem(null, createProxy(), null);

        // ...
        // set a security manager, & set up a listener for discovery events
        // ...

        // create the specified number of tickets to the named game
        createTickets(gameName, numTickets);      
    public static void main(String args[]) {
        if (args.length < 2) {
            System.out.println("Usage: GameService gameName numTickets");
        try {
            String gameName = args[0];
            int numPlayers = Integer.parseInt(args[1]);
            GameService gameService = new GameService(gameName, numPlayers);
            new Thread(gameService).start();
        } catch (Exception e) {
            System.out.println("Could not create game service: " + e.getMessage());

Let's look at the pieces, starting with the main method. You'll see that it instantiates a new GameService object -- passing it command-line arguments that specify the name of this particular game and the maximum number of players the game should admit. Then, just as you saw in the player code, main starts up a thread (which simply loops indefinitely) to keep this object from terminating. When you construct a GameService object, several interesting things happen. First, you obtain a reference to a JavaSpace (how SpaceAccessor accomplishes this will be detailed in a future article) and assign it to the space member variable. This is the space that the game service and players use to coordinate their access to the game.

Next you create an instance of ServiceItem, the object that the game service registers with any lookup services it finds. You'll notice the call to createProxy, which instantiates a GameServiceProxy, stashes a reference to the space within the proxy, and returns the proxy. This proxy gets embedded in the service item and becomes the means that players use to join and leave the game (as you saw in the player).

Then the constructor takes care of some Jini details. It's important to understand that whenever the game service hears about Jini discovery events, it registers your service item (with the proxy to the game service) with any new lookup services; in other words, it "publishes" the game proxy whenever it gets a chance. Finally, the constructor calls the createTickets method, which sets the stage for how you'll coordinate access to the game.

The basic idea behind mediating access to the game is that the game service admits only those players holding a ticket (just as in the real world). Before looking in detail at createTickets, you should know what a Ticket entry looks like:

import net.jini.core.entry.Entry;

public class Ticket implements Entry {
    public String gameName;
    public Game game;

    public Ticket() {
    public Ticket(String gameName) {
        this.gameName = gameName;
    public Ticket(String gameName, Game game) {
        this.gameName = gameName; = game;

When you have a ticket for an event in hand, it should include information about and directions to the event. So here are the two pieces of information on every ticket: the name of the game and a reference to a remote Game object that a player can use to access that game. Ticket also has a no-arg constructor (which JavaSpaces entries require) and two other constructors provided for convenience.

Now returning to createTickets, you'll notice that it first instantiates a remote game object and assigns the remote reference to the game. With a reference to the remote game in hand, createTickets enters a loop to create tickets. Given that maxPlayers specifies the maximum number of players the game should permit at a time, createTickets instantiates exactly that many Ticket objects for this game. It passes each Ticket the name of the game and the reference to the remote game, and writes the Tickets into the space.

Those are the basics of the game service. Essentially, it publishes a game service proxy that players use to join and leave the game, and it initializes the JavaSpace you're using with an appropriate number of tickets to mediate access to the game.

<<  Page 5 of 10  >>

Sponsored Links

Copyright © 1996-2018 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use