Sample session pattern (SIMON 1.1.x)

This sample will teach you how to handle client logins and how to deal with leaving clients ...

Shared interfaces

A simple callback, that can be used by server to call methods on client side:

package de.root1.mycommonproject;

public interface ClientCallbackInterface {

   public void callback(String text);

}

The main server object. It's the entry point for every client connection.

package de.root1.mycommonproject;

public interface ServerInterface {

   public SessionInterface login(String user, ClientCallbackInterface clientCallback);

}

This interface contains all the methods, an auth'ed client is allowed to call ...

package de.root1.mycommonproject;

public interface SessionInterface {

    public void doSomething();

}

Server code

The main-class that starts the server:

package de.root1.myserverproject;

import java.io.IOException;
import java.net.UnknownHostException;

import de.root1.simon.Registry;
import de.root1.simon.Simon;
import de.root1.simon.exceptions.NameBindingException;

public class Server {

    public static void main(String[] args)
            throws UnknownHostException, IOException, NameBindingException {

        // create the serverobject
        ServerInterfaceImpl serverImpl = new ServerInterfaceImpl();

        // create the server's registry ...
        Registry registry = Simon.createRegistry(44444);

        // ... where we can bind the serverobject to
        registry.bind("server", serverImpl);

        System.out.println("Server up and running!");

        // some mechanism to shutdown the server should be placed here
        // this should include the following command:
        // registry.unbind("server");
        // registry.stop();
    }
}

The implementation of the serverinterface. The client can only lookup this object instance ...

package de.root1.myserverproject;

import de.root1.simon.Simon;
import de.root1.mycommonproject.ServerInterface;
import de.root1.mycommonproject.ClientCallbackInterface;
import de.root1.mycommonproject.SessionInterface;
import de.root1.simon.annotation.SimonRemote;
import de.root1.simon.SimonUnreferenced;
import java.util.ArrayList;
import java.util.List;

// mark this class as a remote class and export all methods known in ServerInterface
@SimonRemote(value = {ServerInterface.class})
public class ServerInterfaceImpl implements ServerInterface {

    private static final long serialVersionUID = 1L;

    // this is where all user sessions are stored
    private List<SessionInterface> userSessions = new ArrayList<SessionInterface>();

    @Override
    public SessionInterface login(String user, ClientCallbackInterface clientCallback) {
        System.out.println("login. user="+user);
        clientCallback.callback("Login is in progress ...");
        System.out.flush();
        Session session = new Session(user, this);
        userSessions.add(session);
        clientCallback.callback("Session is created ... Now "+userSessions.size()+" users are online ...");
        System.out.println("Session created for user "+user+". Now "+userSessions.size()+" users are online ...");
        return session;
    }

    // if a session get's unreferenced, the session is removed from the list
    void removeUserSession(Session userSession) {
        userSessions.remove(userSession);
        System.out.println("Removed user "+userSession.getUsername()+" from sessionlist. "+userSessions.size()+" user are online.");
    }

}

The session interface implementation. With the help of "SimonUnreferenced", it's possible to get informed when a client leaves ("logout" or "connection broken"):

package de.root1.myserverproject;

import de.root1.mycommonproject.SessionInterface;
import de.root1.simon.SimonUnreferenced;
import de.root1.simon.annotation.SimonRemote;
import java.io.Serializable;

@SimonRemote(value = {SessionInterface.class})
public class Session implements SessionInterface,  SimonUnreferenced, Serializable {

    private final String user;
    private final ServerInterfaceImpl server;

    public Session(String user, ServerInterfaceImpl server) {
        this.user = user;
        this.server = server;
    }

    @Override
    public void doSomething() {
        System.out.println("User "+user+" does something ...");
    }

    @Override
    public void unreferenced() {
        System.out.println("Unreferenced: "+user+"@"+this);
        server.removeUserSession(this);
    }

    public String getUsername(){
        return user;
    }

}

Client code

The client's main class that establishes the connection to the server:

package de.root1.myclientproject;

import de.root1.mycommonproject.ServerInterface;
import de.root1.mycommonproject.SessionInterface;
import de.root1.simon.Lookup;
import de.root1.simon.exceptions.EstablishConnectionFailed;
import java.io.IOException;

import de.root1.simon.Simon;
import de.root1.simon.exceptions.LookupFailedException;

public class Client {

    public static void main(String[] args) throws IOException, LookupFailedException, EstablishConnectionFailed {

        // create a callback object
        ClientCallbackImpl clientCallbackImpl = new ClientCallbackImpl();

        // 'lookup' the server object
        Lookup nameLookup = Simon.createNameLookup("127.0.0.1", 44444);
        ServerInterface server = (ServerInterface) nameLookup.lookup("server");

        // use the serverobject as it would exist on your local machine
        SessionInterface session = server.login("DonaldDuck", clientCallbackImpl);

        session.doSomething();

        // do some more stuff
        // ...

        // and finally 'release' the serverobject to release to connection to the server
        nameLookup.release(server);
    }
}

A very simple implementtaion for the callback functionality:

package de.root1.myclientproject;

import de.root1.mycommonproject.ClientCallbackInterface;
import de.root1.simon.SimonUnreferenced;
import de.root1.simon.annotation.SimonRemote;

// mark this class as a remote class and export all methods known in ClientCallbackInterface
@SimonRemote(value = {ClientCallbackInterface.class})
public class ClientCallbackImpl implements ClientCallbackInterface, SimonUnreferenced {

    private static final long serialVersionUID = 1L;

    @Override
    public void callback(String text) {

        System.out.println("This message was received from the server: " + text);

    }

    @Override
    public void unreferenced() {
        System.out.println("unreferenced: "+this);
    }
}

NetbeansProjects-SimonSessionPattern.zip - Complete sample as NB6.9 Maven2 projects (39.8 KB) achristian, 07/15/2010 10:45 AM