Presentation is loading. Please wait.

Presentation is loading. Please wait.

CSCE 515: Computer Network Programming Chin-Tser Huang University of South Carolina.

Similar presentations


Presentation on theme: "CSCE 515: Computer Network Programming Chin-Tser Huang University of South Carolina."— Presentation transcript:

1 CSCE 515: Computer Network Programming Chin-Tser Huang huangct@cse.sc.edu University of South Carolina

2 4/13/20042 An RMI Chat with Callback Example An RMI-based client/server chat system with callback mechanism Define remote interfaces RMICallbackServer and RMICallbackClient Server class RMICallbackServerImpl accepts client registration through interface RMICallbackServer Client class RMICallbackClientImpl sends messages to server and server broadcasts messages to each registered client through interface RMICallbackClient

3 4/13/20043 Interface RMICallbackServer /* Java Network Programming, Second Edition * Merlin Hughes, Michael Shoffner, Derek Hamner * Manning Publications Company; ISBN 188477749X * * http://nitric.com/jnp/ * * Copyright (c) 1997-1999 Merlin Hughes, Michael Shoffner, Derek Hamner; * all rights reserved; see license.txt for details. */ import java.rmi.*; public interface RMICallbackServer extends Remote { public static final String REGISTRY_NAME = "Callback Server"; public abstract void register (RMICallbackClient client) throws RemoteException; public abstract void deregister (RMICallbackClient client) throws RemoteException; public abstract void say (String message) throws RemoteException; }

4 4/13/20044 Interface RMICallbackClient /* Java Network Programming, Second Edition * Merlin Hughes, Michael Shoffner, Derek Hamner * Manning Publications Company; ISBN 188477749X * * http://nitric.com/jnp/ * * Copyright (c) 1997-1999 Merlin Hughes, Michael Shoffner, Derek Hamner; * all rights reserved; see license.txt for details. */ import java.rmi.*; public interface RMICallbackClient extends Remote { public abstract void said (String message) throws RemoteException; }

5 4/13/20045 Class RMICallbackServerImpl /* Java Network Programming, Second Edition * Merlin Hughes, Michael Shoffner, Derek Hamner * Manning Publications Company; ISBN 188477749X * * http://nitric.com/jnp/ * * Copyright (c) 1997-1999 Merlin Hughes, Michael Shoffner, Derek Hamner; * all rights reserved; see license.txt for details. */ import java.rmi.*; import java.util.*; import java.rmi.server.*; import java.rmi.registry.*; public class RMICallbackServerImpl extends UnicastRemoteObject implements RMICallbackServer { // public RMICallbackServerImpl () throws RemoteException … // public void register (RMICallbackClient client) … // public void deregister (RMICallbackClient client) … // public void say (String message) … // public static void main (String[] args) throws RemoteException … }

6 4/13/20046 Methods of RMICallbackServerImpl protected Vector clients; public RMIChatServerImpl () throws RemoteException { clients = new Vector (); } public void register (RMICallbackClient client) { try { say (getClientHost () + " has joined."); } catch (ServerNotActiveException ignored) { } clients.addElement (client); } public void deregister (RMICallbackClient client) { clients.removeElement (client); try { say (getClientHost () + " has left."); } catch (ServerNotActiveException ignored) { }

7 4/13/20047 Method say public void say (String message) { Vector clients = (Vector) this.clients.clone (); for (int i = 0; i < clients.size (); ++ i) { RMICallbackClient client = (RMICallbackClient) clients.elementAt (i); try { client.said (message); } catch (RemoteException ex) { this.clients.removeElement (client); }

8 4/13/20048 Method main public static void main (String[] args) throws RemoteException { RMICallbackServerImpl callbackServer = new RMICallbackServerImpl (); Registry registry = LocateRegistry.getRegistry (); registry.rebind (REGISTRY_NAME, callbackServer); }

9 4/13/20049 Class RMICallbackClientImpl /* Java Network Programming, Second Edition * Merlin Hughes, Michael Shoffner, Derek Hamner * Manning Publications Company; ISBN 188477749X * * http://nitric.com/jnp/ * * Copyright (c) 1997-1999 Merlin Hughes, Michael Shoffner, Derek Hamner; * all rights reserved; see license.txt for details. */ import java.awt.*; import java.rmi.*; import java.awt.event.*; import java.rmi.server.*; import java.rmi.registry.*; public class RMICallbackClientImpl extends UnicastRemoteObject implements RMICallbackClient, ActionListener{ // public RMICallbackClientImpl (String host) throws RemoteException … // public synchronized void start () throws RemoteException, NotBoundException … // public synchronized void stop () throws RemoteException … // public void said (String message) … // public void actionPerformed (ActionEvent ev) … // public static void main (String[] args) throws RemoteException, NotBoundException … }

10 4/13/200410 Constructor RMICallbackClientImpl protected String host; protected Frame frame; protected TextField input; protected TextArea output; public RMICallbackClientImpl (String host) throws RemoteException { this.host = host; frame = new Frame ("RMICallbackClientImpl [" + host + "]"); frame.add (output = new TextArea (), "Center"); output.setEditable (false); frame.add (input = new TextField (), "South"); input.addActionListener (this); frame.addWindowListener (new WindowAdapter () { public void windowOpened (WindowEvent ev) { input.requestFocus (); } public void windowClosing (WindowEvent ev) { try { stop (); } catch (RemoteException ex) { ex.printStackTrace (); } }); frame.pack (); }

11 4/13/200411 Methods start, stop, and said protected RMICallbackServer server; public synchronized void start () throws RemoteException, NotBoundException { if (server == null) { Registry registry = LocateRegistry.getRegistry (host); server = (RMICallbackServer) registry.lookup (RMICallbackServer.REGISTRY_NAME); server.register (this); frame.setVisible (true); } public synchronized void stop () throws RemoteException { frame.setVisible (false); RMICallbackServer server = this.server; this.server = null; if (server != null) server.deregister (this); } public void said (String message) { output.append (message + "\n"); }

12 4/13/200412 Method actionPerformed public void actionPerformed (ActionEvent ev) { try { RMICallbackServer server = this.server; if (server != null) { server.say (ev.getActionCommand ()); input.setText (""); } } catch (RemoteException ex) { input.setVisible (false); frame.validate (); ex.printStackTrace (); }

13 4/13/200413 Method main public static void main (String[] args) throws RemoteException, NotBoundException { if (args.length != 1) throw new IllegalArgumentException ("Syntax: RMICallbackClientImpl "); RMICallbackClientImpl callbackClient = new RMICallbackClientImpl (args[0]); callbackClient.start (); }

14 4/13/200414 Disadvantages of Example For every client, need to maintain two network connections, one incoming and one outgoing Connections will timeout and need to be periodically reestablished

15 4/13/200415 An RMI Distributed List Example Client and server maintain list state in local IDList object When an update is attempted to a client list, makes a remote method call on server If server approves the change, it makes remote method calls on all registered clients to indicate the change

16 4/13/200416 Interface DistributedList /* Java Network Programming, Second Edition * Merlin Hughes, Michael Shoffner, Derek Hamner * Manning Publications Company; ISBN 188477749X * * http://nitric.com/jnp/ * * Copyright (c) 1997-1999 Merlin Hughes, Michael Shoffner, Derek Hamner; * all rights reserved; see license.txt for details. */ import java.util.*; public interface DistributedList { public abstract void addElement (Object element); public abstract void updateElement (Object oldElement, Object newElement); public abstract void replaceElement (Object oldElement, Object newElement); public abstract void removeElement (Object element); public abstract Enumeration getElements (); public abstract void addChangeListener (ChangeListener listener); public abstract void removeChangeListener (ChangeListener listener); }

17 4/13/200417 Interface ChangeListener /* Java Network Programming, Second Edition * Merlin Hughes, Michael Shoffner, Derek Hamner * Manning Publications Company; ISBN 188477749X * * http://nitric.com/jnp/ * * Copyright (c) 1997-1999 Merlin Hughes, Michael Shoffner, Derek Hamner; * all rights reserved; see license.txt for details. */ import java.util.*; public interface ChangeListener extends EventListener { public abstract void changeOccurred (ChangeEvent changeEvent); }

18 4/13/200418 Class ChangeEvent /* Java Network Programming, Second Edition * Merlin Hughes, Michael Shoffner, Derek Hamner * Manning Publications Company; ISBN 188477749X * * http://nitric.com/jnp/ * * Copyright (c) 1997-1999 Merlin Hughes, Michael Shoffner, Derek Hamner; * all rights reserved; see license.txt for details. */ import java.util.*; public class ChangeEvent extends EventObject { public ChangeEvent (Object source) { super (source); }

19 4/13/200419 Class ID /* Java Network Programming, Second Edition * Merlin Hughes, Michael Shoffner, Derek Hamner * Manning Publications Company; ISBN 188477749X * * http://nitric.com/jnp/ * * Copyright (c) 1997-1999 Merlin Hughes, Michael Shoffner, Derek Hamner; * all rights reserved; see license.txt for details. */ import java.io.*; public class ID implements Serializable { protected int id; public ID (int id) { this.id = id; } public boolean equals (Object other) { return (other != null) && (other instanceof ID) && (((ID) other).id == id); } public int hashCode () { return id; }

20 4/13/200420 Class IDList /* Java Network Programming, Second Edition * Merlin Hughes, Michael Shoffner, Derek Hamner * Manning Publications Company; ISBN 188477749X * * http://nitric.com/jnp/ * * Copyright (c) 1997-1999 Merlin Hughes, Michael Shoffner, Derek Hamner; * all rights reserved; see license.txt for details. */ import java.io.*; import java.util.*; public class IDList implements Serializable { // public IDList () … // public synchronized ID allocateID () … // public synchronized boolean addElement (ID id, Object element) … // public synchronized boolean updateElement (ID oldID, ID id, Object element) … // public synchronized boolean replaceElement (ID oldID, ID id, Object element) … // public synchronized boolean removeElement (ID id) … // public synchronized ID getID (Object element) … // public Enumeration getElements () … // public synchronized Object clone () … }

21 4/13/200421 Constructor IDList protected Vector ids, elements; public IDList () { ids = new Vector (); elements = new Vector (); }

22 4/13/200422 Methods of IDList protected int id; public synchronized ID allocateID () { return new ID (id ++); } protected int updateCount; public int getUpdateCount () { return updateCount; } public synchronized boolean addElement (ID id, Object element) { if (ids.contains (id)) return false; ids.addElement (id); elements.addElement (element); ++ updateCount; return true; }

23 4/13/200423 Methods of IDList public synchronized boolean updateElement (ID oldID, ID id, Object element) { int index = ids.indexOf (oldID); if (index < 0) return false; ids.setElementAt (id, index); elements.setElementAt (element, index); ++ updateCount; return true; } public synchronized boolean replaceElement (ID oldID, ID id, Object element) { int index = ids.indexOf (oldID); if (index < 0) return false; ids.removeElementAt (index); elements.removeElementAt (index); ids.addElement (id); elements.addElement (element); ++ updateCount; return true; }

24 4/13/200424 Methods of IDList public synchronized boolean removeElement (ID id) { int index = ids.indexOf (id); if (index < 0) return false; ids.removeElementAt (index); elements.removeElementAt (index); ++ updateCount; return true; } public synchronized ID getID (Object element) { int index = elements.indexOf (element); if (index < 0) return null; else return (ID) ids.elementAt (index); } public Enumeration getElements () { return ((Vector) elements.clone ()).elements (); }

25 4/13/200425 Methods of IDList public synchronized Object clone () { try { IDList idList = (IDList) super.clone (); idList.ids = (Vector) ids.clone (); idList.elements = (Vector) elements.clone (); return idList; } catch (CloneNotSupportedException ignored) { return null; }

26 4/13/200426 Interface RMIListServer /* Java Network Programming, Second Edition * Merlin Hughes, Michael Shoffner, Derek Hamner * Manning Publications Company; ISBN 188477749X * * http://nitric.com/jnp/ * * Copyright (c) 1997-1999 Merlin Hughes, Michael Shoffner, Derek Hamner; * all rights reserved; see license.txt for details. */ import java.rmi.*; public interface RMIListServer extends Remote { public abstract IDList register (RMIListClient client) throws RemoteException; public abstract void deregister (RMIListClient client) throws RemoteException; public abstract void addElement (Object element) throws RemoteException; public abstract void updateElement (ID id, Object newElement) throws RemoteException; public abstract void replaceElement (ID id, Object newElement) throws RemoteException; public abstract void removeElement (ID id) throws RemoteException; }

27 4/13/200427 Interface RMIListClient /* Java Network Programming, Second Edition * Merlin Hughes, Michael Shoffner, Derek Hamner * Manning Publications Company; ISBN 188477749X * * http://nitric.com/jnp/ * * Copyright (c) 1997-1999 Merlin Hughes, Michael Shoffner, Derek Hamner; * all rights reserved; see license.txt for details. */ import java.rmi.*; public interface RMIListClient extends Remote { public abstract void elementAdded (ID id, Object element) throws RemoteException; public abstract void elementUpdated (ID oldID, ID id, Object element) throws RemoteException; public abstract void elementReplaced (ID oldID, ID id, Object element) throws RemoteException; public abstract void elementRemoved (ID id) throws RemoteException; }

28 4/13/200428 Class RMIListServerImpl /* Java Network Programming, Second Edition * Merlin Hughes, Michael Shoffner, Derek Hamner * Manning Publications Company; ISBN 188477749X * * http://nitric.com/jnp/ * * Copyright (c) 1997-1999 Merlin Hughes, Michael Shoffner, Derek Hamner; * all rights reserved; see license.txt for details. */ import java.rmi.*; import java.util.*; import java.rmi.server.*; import java.rmi.registry.*; public class RMIListServerImpl extends UnicastRemoteObject implements RMIListServer { // public RMIListServerImpl () throws RemoteException … // public synchronized IDList register (RMIListClient client) … // public synchronized void deregister (RMIListClient client) … // public synchronized void addElement (Object element) … // public synchronized void updateElement (ID id, Object element) … // public synchronized void replaceElement (ID id, Object element) … // public synchronized void removeElement (ID id) … // public static void main (String[] args) throws RemoteException, AlreadyBoundException … }

29 4/13/200429 Constructor RMIListServerImpl protected IDList idList; protected Vector clients; public RMIListServerImpl () throws RemoteException { idList = new IDList (); clients = new Vector (); }

30 4/13/200430 Methods of RMIListServerImpl public synchronized IDList register (RMIListClient client) { clients.addElement (client); return idList; } public synchronized void deregister (RMIListClient client) { clients.removeElement (client); }

31 4/13/200431 Methods of RMIListServerImpl public synchronized void addElement (Object element) { ID id = idList.allocateID (); if (idList.addElement (id, element)) { for (int i = 0; i < clients.size (); ++ i) { try { ((RMIListClient) clients.elementAt (i)).elementAdded (id, element); } catch (RemoteException ex) { clients.removeElementAt (i --); } public synchronized void updateElement (ID id, Object element) { ID newID = idList.allocateID (); if (idList.updateElement (id, newID, element)) { for (int i = 0; i < clients.size (); ++ i) { try { ((RMIListClient) clients.elementAt (i)).elementUpdated (id, newID, element); } catch (RemoteException ex) { clients.removeElementAt (i --); }

32 4/13/200432 Methods of RMIListServerImpl public synchronized void replaceElement (ID id, Object element) { ID newID = idList.allocateID (); if (idList.replaceElement (id, newID, element)) { for (int i = 0; i < clients.size (); ++ i) { try { ((RMIListClient) clients.elementAt (i)).elementReplaced (id, newID, element); } catch (RemoteException ex) { clients.removeElementAt (i --); } public synchronized void removeElement (ID id) { if (idList.removeElement (id)) { for (int i = 0; i < clients.size (); ++ i) { try { ((RMIListClient) clients.elementAt (i)).elementRemoved (id); } catch (RemoteException ex) { clients.removeElementAt (i --); }

33 4/13/200433 Method main public static void main (String[] args) throws RemoteException, AlreadyBoundException { if (args.length != 2) throw new IllegalArgumentException ("Syntax: RMIListServerImpl "); RMIListServerImpl listServer = new RMIListServerImpl (); Registry registry = LocateRegistry.createRegistry (Integer.parseInt (args[0])); registry.bind (args[1], listServer); }

34 4/13/200434 Class RMIListClientImpl /* Java Network Programming, Second Edition * Merlin Hughes, Michael Shoffner, Derek Hamner * Manning Publications Company; ISBN 188477749X * * http://nitric.com/jnp/ * * Copyright (c) 1997-1999 Merlin Hughes, Michael Shoffner, Derek Hamner; * all rights reserved; see license.txt for details. */ import java.rmi.*; import java.util.*; import java.rmi.server.*; import java.rmi.registry.*; public class RMIListClientImpl implements DistributedList { // public RMIListClientImpl (String host, int port, String service) … // public synchronized void start () throws RemoteException, NotBoundException … // public synchronized void stop () throws RemoteException … // public synchronized void addElement (Object element) … // public synchronized void updateElement (Object oldElement, Object newElement) … // public synchronized void replaceElement (Object oldElement, Object newElement) … // public synchronized void removeElement (Object element) … // public Enumeration getElements () … // public void addChangeListener (ChangeListener listener) … // public void removeChangeListener (ChangeListener listener) … // protected void fireChangeEvent (ChangeEvent changeEvent) … // class Callback implements RMIListClient … }

35 4/13/200435 Constructor RMIListClientImpl protected String host, service; protected int port; public RMIListClientImpl (String host, int port, String service) { this.host = host; this.port = port; this.service = service; }

36 4/13/200436 Methods of RMIListClientImpl protected IDList idList; protected RMIListClient myself; protected RMIListServer listServer; public synchronized void start () throws RemoteException, NotBoundException { if (listServer == null) { myself = (RMIListClient) UnicastRemoteObject.exportObject (new Callback ()); Registry registry = LocateRegistry.getRegistry (host, port); listServer = (RMIListServer) registry.lookup (service); try { idList = listServer.register (myself); } catch (RemoteException ex) { listServer = null; throw ex; } fireChangeEvent (new ChangeEvent (this)); } public synchronized void stop () throws RemoteException { try { if (listServer != null) listServer.deregister (myself); } finally { listServer = null; UnicastRemoteObject.unexportObject (myself, true); }

37 4/13/200437 Methods of RMIListClientImpl public synchronized void addElement (Object element) { if (listServer != null) { try { listServer.addElement (element); } catch (RemoteException ex) { listServer = null; } public synchronized void updateElement (Object oldElement, Object newElement) { if (listServer != null) { ID id = idList.getID (oldElement); if (id != null) { try { listServer.updateElement (id, newElement); } catch (RemoteException ex) { listServer = null; }

38 4/13/200438 Methods of RMIListClientImpl public synchronized void replaceElement (Object oldElement, Object newElement) { if (listServer != null) { ID id = idList.getID (oldElement); if (id != null) { try { listServer.replaceElement (id, newElement); } catch (RemoteException ex) { listServer = null; } public synchronized void removeElement (Object element) { if (listServer != null) { ID id = idList.getID (element); if (id != null) { try { listServer.removeElement (id); } catch (RemoteException ex) { listServer = null; } public Enumeration getElements () { return idList.getElements (); }

39 4/13/200439 Methods of RMIListClientImpl protected Vector listeners = new Vector (); public void addChangeListener (ChangeListener listener) { listeners.addElement (listener); } public void removeChangeListener (ChangeListener listener) { listeners.removeElement (listener); } protected void fireChangeEvent (ChangeEvent changeEvent) { synchronized (listeners) { for (int i = 0; i < listeners.size (); ++ i) ((ChangeListener) listeners.elementAt (i)).changeOccurred (changeEvent); }

40 4/13/200440 Inner Class Callback class Callback implements RMIListClient { public void elementAdded (ID id, Object element) { idList.addElement (id, element); fireChangeEvent (new ChangeEvent (RMIListClientImpl.this)); } public void elementUpdated (ID oldID, ID id, Object element) { idList.updateElement (oldID, id, element); fireChangeEvent (new ChangeEvent (RMIListClientImpl.this)); } public void elementReplaced (ID oldID, ID id, Object element) { idList.replaceElement (oldID, id, element); fireChangeEvent (new ChangeEvent (RMIListClientImpl.this)); } public void elementRemoved (ID id) { idList.removeElement (id); fireChangeEvent (new ChangeEvent (RMIListClientImpl.this)); }

41 4/13/200441 Summary of RMI RMI framework hides low-level networking details in the guise of remote method calls Different style than using streams and sockets Each style has its own uses Sockets are useful when interacting with other socket-based applications and when full control of communication channel is needed RMI is good in designing cleaner high-level protocols, in request-based applications, and in peer-to-peer applications

42 4/13/200442 Next Class Telnet and rlogin File transfer protocol (FTP) Read TI Ch. 26, 27


Download ppt "CSCE 515: Computer Network Programming Chin-Tser Huang University of South Carolina."

Similar presentations


Ads by Google