Sample session pattern (SIMON 1.1.0)

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:

1 package de.root1.mycommonproject;
2 
3 public interface ClientCallbackInterface {
4 
5    public void callback(String text);
6 
7 }

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

1 package de.root1.mycommonproject;
2 
3 public interface ServerInterface {
4 
5    public SessionInterface login(String user, ClientCallbackInterface clientCallback);
6 
7 }

This interface contains all the methods, an authed client is allowed to call ...

1 package de.root1.mycommonproject;
2 
3 public interface SessionInterface {
4 
5     public void doSomething();
6 
7 }

Server code

The main-class that starts the server:

 1 package de.root1.myserverproject;
 2 
 3 import java.io.IOException;
 4 import java.net.UnknownHostException;
 5 
 6 import de.root1.simon.Registry;
 7 import de.root1.simon.Simon;
 8 import de.root1.simon.exceptions.NameBindingException;
 9 
10 public class Server {
11 
12     public static void main(String[] args)
13             throws UnknownHostException, IOException, NameBindingException {
14 
15         // create the serverobject
16         ServerInterfaceImpl serverImpl = new ServerInterfaceImpl();
17 
18         // create the server's registry ...
19         Registry registry = Simon.createRegistry(44444);
20 
21         // ... where we can bind the serverobject to
22         registry.bind("server", serverImpl);
23 
24         System.out.println("Server up and running!");
25 
26         // some mechanism to shutdown the server should be placed here
27         // this should include the following command:
28         // registry.unbind("server");
29         // registry.stop();
30     }
31 }

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

 1 package de.root1.myserverproject;
 2 
 3 import de.root1.simon.Simon;
 4 import de.root1.mycommonproject.ServerInterface;
 5 import de.root1.mycommonproject.ClientCallbackInterface;
 6 import de.root1.mycommonproject.SessionInterface;
 7 import de.root1.simon.annotation.SimonRemote;
 8 import de.root1.simon.SimonUnreferenced;
 9 import java.util.ArrayList;
10 import java.util.List;
11 
12 // mark this class as a remote class and export all methods known in ServerInterface
13 @SimonRemote(value = {ServerInterface.class})
14 public class ServerInterfaceImpl implements ServerInterface {
15 
16     private static final long serialVersionUID = 1L;
17 
18     // this is where all user sessions are stored
19     private List<SessionInterface> userSessions = new ArrayList<SessionInterface>();
20 
21     @Override
22     public SessionInterface login(String user, ClientCallbackInterface clientCallback) {
23         System.out.println("login. user="+user);
24         clientCallback.callback("Login is in progress ...");
25         System.out.flush();
26         Session session = new Session(user, this);
27         userSessions.add(session);
28         clientCallback.callback("Session is created ... Now "+userSessions.size()+" users are online ...");
29         System.out.println("Session created for user "+user+". Now "+userSessions.size()+" users are online ...");
30         return session;
31     }
32 
33     // if a session get's unreferenced, the session is removed from the list
34     void removeUserSession(Session userSession) {
35         userSessions.remove(userSession);
36         System.out.println("Removed user "+userSession.getUsername()+" from sessionlist. "+userSessions.size()+" user are online.");
37     }
38 
39 }

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

 1 package de.root1.myserverproject;
 2 
 3 import de.root1.mycommonproject.SessionInterface;
 4 import de.root1.simon.SimonUnreferenced;
 5 import de.root1.simon.annotation.SimonRemote;
 6 import java.io.Serializable;
 7 
 8 @SimonRemote(value = {SessionInterface.class})
 9 public class Session implements SessionInterface,  SimonUnreferenced, Serializable {
10 
11     private final String user;
12     private final ServerInterfaceImpl server;
13 
14     public Session(String user, ServerInterfaceImpl server) {
15         this.user = user;
16         this.server = server;
17     }
18 
19     @Override
20     public void doSomething() {
21         System.out.println("User "+user+" does something ...");
22     }
23 
24     @Override
25     public void unreferenced() {
26         System.out.println("Unreferenced: "+user+"@"+this);
27         server.removeUserSession(this);
28     }
29 
30     public String getUsername(){
31         return user;
32     }
33 
34 }

Client code

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

 1 package de.root1.myclientproject;
 2 
 3 import de.root1.mycommonproject.ServerInterface;
 4 import de.root1.mycommonproject.SessionInterface;
 5 import de.root1.simon.Lookup;
 6 import de.root1.simon.exceptions.EstablishConnectionFailed;
 7 import java.io.IOException;
 8 
 9 import de.root1.simon.Simon;
10 import de.root1.simon.exceptions.LookupFailedException;
11 
12 public class Client {
13 
14     public static void main(String[] args) throws IOException, LookupFailedException, EstablishConnectionFailed {
15 
16         // create a callback object
17         ClientCallbackImpl clientCallbackImpl = new ClientCallbackImpl();
18 
19         // 'lookup' the server object
20         Lookup nameLookup = Simon.createNameLookup("127.0.0.1", 44444);
21         ServerInterface server = (ServerInterface) nameLookup.lookup("server");
22 
23         // use the serverobject as it would exist on your local machine
24         SessionInterface session = server.login("DonaldDuck", clientCallbackImpl);
25 
26         session.doSomething();
27 
28         // do some more stuff
29         // ...
30 
31         // and finally 'release' the serverobject to release to connection to the server
32         nameLookup.release(server);
33     }
34 }

A very simple implementtaion for the callback functionality:

 1 package de.root1.myclientproject;
 2 
 3 import de.root1.mycommonproject.ClientCallbackInterface;
 4 import de.root1.simon.SimonUnreferenced;
 5 import de.root1.simon.annotation.SimonRemote;
 6 
 7 // mark this class as a remote class and export all methods known in ClientCallbackInterface
 8 @SimonRemote(value = {ClientCallbackInterface.class})
 9 public class ClientCallbackImpl implements ClientCallbackInterface, SimonUnreferenced {
10 
11     private static final long serialVersionUID = 1L;
12 
13     @Override
14     public void callback(String text) {
15 
16         System.out.println("This message was received from the server: " + text);
17 
18     }
19 
20     @Override
21     public void unreferenced() {
22         System.out.println("unreferenced: "+this);
23     }
24 }

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