li tak sing comps311f. rmi callbacks in previous example, only the client can initiate a...
TRANSCRIPT
![Page 1: Li Tak Sing COMPS311F. RMI callbacks In previous example, only the client can initiate a communication with the server. The server can only response to](https://reader031.vdocuments.us/reader031/viewer/2022032308/56649f475503460f94c69060/html5/thumbnails/1.jpg)
Li Tak Sing
COMPS311F
![Page 2: Li Tak Sing COMPS311F. RMI callbacks In previous example, only the client can initiate a communication with the server. The server can only response to](https://reader031.vdocuments.us/reader031/viewer/2022032308/56649f475503460f94c69060/html5/thumbnails/2.jpg)
RMI callbacksIn previous example, only the client can initiate a
communication with the server. The server can only response to a server's request.
For example, if we want to use RMI to write a chat server, when a client send in a message, we need to send it to all connecting clients. In this case, we need the server to be able to initiate the communication with the clients.
In order for the server to initiate a request, the client should also be a Remote object. The server should have a copy of the stub. This can be done by invoking a remote method by the client which passes itself as a parameter to the server.
![Page 3: Li Tak Sing COMPS311F. RMI callbacks In previous example, only the client can initiate a communication with the server. The server can only response to](https://reader031.vdocuments.us/reader031/viewer/2022032308/56649f475503460f94c69060/html5/thumbnails/3.jpg)
Passing the client to the serverThe first step is to create a client interface:
public interface Client extends Remote { public void callBack(...) throws RemoteException; }
The server should have a method which allows the client to pass itself as the parameter:public interface Server extends Remote { public void connect(Client client) throws
RemoteException;.......
}
![Page 4: Li Tak Sing COMPS311F. RMI callbacks In previous example, only the client can initiate a communication with the server. The server can only response to](https://reader031.vdocuments.us/reader031/viewer/2022032308/56649f475503460f94c69060/html5/thumbnails/4.jpg)
Implementation of the clientThe implementation of the client should
consists of a statement that invoke the connect method of the server that passes itself to the server:....server.connect(this); // A statement in the client....
![Page 5: Li Tak Sing COMPS311F. RMI callbacks In previous example, only the client can initiate a communication with the server. The server can only response to](https://reader031.vdocuments.us/reader031/viewer/2022032308/56649f475503460f94c69060/html5/thumbnails/5.jpg)
Implementation of the serverThe server should use an attribute to store the
connected client:public class ServerImp implements Server, Serializable {
private client;public void connect(Client c) throws RemoteException {
client=c;}
....//whenever there is a need to contact the client, we can:client.callBack(..);
....}
![Page 6: Li Tak Sing COMPS311F. RMI callbacks In previous example, only the client can initiate a communication with the server. The server can only response to](https://reader031.vdocuments.us/reader031/viewer/2022032308/56649f475503460f94c69060/html5/thumbnails/6.jpg)
A Chat server using RMIYou can download the program at
http://plbpc001.ouhk.edu.hk/~mt311f/examples/mt3112010/src/r.zip
The server is stored in the package RMIChatIn the above file, there is another server in the
package RMIChat2 which we will talk about later.The program has four files:
ChatServer: interface for the chat serverChatServerImp: implementation of the chat
serverChatClient: interface for the chat clientChatClientImp: implementation of the chat client
![Page 7: Li Tak Sing COMPS311F. RMI callbacks In previous example, only the client can initiate a communication with the server. The server can only response to](https://reader031.vdocuments.us/reader031/viewer/2022032308/56649f475503460f94c69060/html5/thumbnails/7.jpg)
ChatServerpublic interface ChatServer extends java.rmi.Remote { public void send(String st) throws
java.rmi.RemoteException; //the client uses it to send a
//message to the server public void connect(ChatClient c) throws
java.rmi.RemoteException; //the client sends itself to the //server
public void disconnect(ChatClient c) throws java.rmi.RemoteException; //the client disconnect from the //server
}
![Page 8: Li Tak Sing COMPS311F. RMI callbacks In previous example, only the client can initiate a communication with the server. The server can only response to](https://reader031.vdocuments.us/reader031/viewer/2022032308/56649f475503460f94c69060/html5/thumbnails/8.jpg)
ChatServerImpIt contains a
JFrame and a JTextArea for the displaying all messages from the clients.
The bottom line displays all connected clients.
![Page 9: Li Tak Sing COMPS311F. RMI callbacks In previous example, only the client can initiate a communication with the server. The server can only response to](https://reader031.vdocuments.us/reader031/viewer/2022032308/56649f475503460f94c69060/html5/thumbnails/9.jpg)
Declaration of ChatServerImppublic class ChatServerImp extends
UnicastRemoteObject implements ChatServer{
.....}
![Page 10: Li Tak Sing COMPS311F. RMI callbacks In previous example, only the client can initiate a communication with the server. The server can only response to](https://reader031.vdocuments.us/reader031/viewer/2022032308/56649f475503460f94c69060/html5/thumbnails/10.jpg)
Some Attributes of ChatServerImpVector<ChatClient> clients; //this stores all
connected clients
![Page 11: Li Tak Sing COMPS311F. RMI callbacks In previous example, only the client can initiate a communication with the server. The server can only response to](https://reader031.vdocuments.us/reader031/viewer/2022032308/56649f475503460f94c69060/html5/thumbnails/11.jpg)
Some Methods of ChatServerImppublic void send(String st) throws RemoteException { Vector<ChatClient> problem = new
Vector<ChatClient>(); textarea.append(st+"\n"); synchronized (clients) { for (ChatClient c : clients) { try { c.toClient(st); } catch (Exception e) { problem.add(c); }
![Page 12: Li Tak Sing COMPS311F. RMI callbacks In previous example, only the client can initiate a communication with the server. The server can only response to](https://reader031.vdocuments.us/reader031/viewer/2022032308/56649f475503460f94c69060/html5/thumbnails/12.jpg)
Some Methods of ChatServerImp } for (ChatClient c : problem) { clients.remove(c); } displayClients(); } }
![Page 13: Li Tak Sing COMPS311F. RMI callbacks In previous example, only the client can initiate a communication with the server. The server can only response to](https://reader031.vdocuments.us/reader031/viewer/2022032308/56649f475503460f94c69060/html5/thumbnails/13.jpg)
Some Methods of ChatServerImppublic void connect(ChatClient c) throws
RemoteException { clients.add(c); displayClients(); }
![Page 14: Li Tak Sing COMPS311F. RMI callbacks In previous example, only the client can initiate a communication with the server. The server can only response to](https://reader031.vdocuments.us/reader031/viewer/2022032308/56649f475503460f94c69060/html5/thumbnails/14.jpg)
Some Methods of ChatServerImp public void disconnect(ChatClient c) throws
RemoteException { clients.remove(c); displayClients(); }
![Page 15: Li Tak Sing COMPS311F. RMI callbacks In previous example, only the client can initiate a communication with the server. The server can only response to](https://reader031.vdocuments.us/reader031/viewer/2022032308/56649f475503460f94c69060/html5/thumbnails/15.jpg)
The main method of ChatServerImp public static void main(String st[]) throws
RemoteException { ChatServer s = new ChatServerImp(); java.rmi.registry.Registry r =
java.rmi.registry.LocateRegistry.getRegistry();
r.rebind("chat", s); }
![Page 16: Li Tak Sing COMPS311F. RMI callbacks In previous example, only the client can initiate a communication with the server. The server can only response to](https://reader031.vdocuments.us/reader031/viewer/2022032308/56649f475503460f94c69060/html5/thumbnails/16.jpg)
ChatClientpublic interface ChatClient extends
java.rmi.Remote { public void toClient(String st) throws
java.rmi.RemoteException; //this is the callback for the //server to send a string to the client
public String name() throws java.rmi.RemoteException; //this is another callback for the server to get the name of //the client.
}
![Page 17: Li Tak Sing COMPS311F. RMI callbacks In previous example, only the client can initiate a communication with the server. The server can only response to](https://reader031.vdocuments.us/reader031/viewer/2022032308/56649f475503460f94c69060/html5/thumbnails/17.jpg)
ChatClientImpThe bottom
textfield is for the user to type in the name.
The connect bottom is used to connect to the chat server.
Once the connection is made, the button becomes the disconnection button.
![Page 18: Li Tak Sing COMPS311F. RMI callbacks In previous example, only the client can initiate a communication with the server. The server can only response to](https://reader031.vdocuments.us/reader031/viewer/2022032308/56649f475503460f94c69060/html5/thumbnails/18.jpg)
ChatClientImpThere is a textfield at the top to allow the
user to type a message.When the user presses the send button, the
message would be sent to the server.The message broadcasted from the server
would be displayed on the middle textarea.
![Page 19: Li Tak Sing COMPS311F. RMI callbacks In previous example, only the client can initiate a communication with the server. The server can only response to](https://reader031.vdocuments.us/reader031/viewer/2022032308/56649f475503460f94c69060/html5/thumbnails/19.jpg)
Declaration of ChatClientImppublic class ChatClientImp extends
UnicastRemoteObject implements ChatClient {
...
![Page 20: Li Tak Sing COMPS311F. RMI callbacks In previous example, only the client can initiate a communication with the server. The server can only response to](https://reader031.vdocuments.us/reader031/viewer/2022032308/56649f475503460f94c69060/html5/thumbnails/20.jpg)
Some Attributes of ChatClientImpJTextField name; //the textfield at the
bottom of the //window that allows the user to type in the name
JTextArea textarea; //the textarea for the display of //messages broadcasted from the server.
ChatServer server; //the chat server
![Page 21: Li Tak Sing COMPS311F. RMI callbacks In previous example, only the client can initiate a communication with the server. The server can only response to](https://reader031.vdocuments.us/reader031/viewer/2022032308/56649f475503460f94c69060/html5/thumbnails/21.jpg)
The action listener of the send button public void actionPerformed(ActionEvent e)
{ try { server.send(name.getText() +
":" + textfield.getText()); textfield.setText(""); } catch (RemoteException ex) { } }
![Page 22: Li Tak Sing COMPS311F. RMI callbacks In previous example, only the client can initiate a communication with the server. The server can only response to](https://reader031.vdocuments.us/reader031/viewer/2022032308/56649f475503460f94c69060/html5/thumbnails/22.jpg)
The action listener of the connect button public void actionPerformed(ActionEvent e) { try { if
(connect.getText().equals("connect")) { Registry registry =
java.rmi.registry.LocateRegistry.getRegistry("localhost");
server = (ChatServer) registry.lookup("chat");
server.connect(ChatClientImp.this);...
![Page 23: Li Tak Sing COMPS311F. RMI callbacks In previous example, only the client can initiate a communication with the server. The server can only response to](https://reader031.vdocuments.us/reader031/viewer/2022032308/56649f475503460f94c69060/html5/thumbnails/23.jpg)
The action listener of the connect button } else { connect.setText("connect");server.disconnect(ChatClientImp.this); }
} catch (NotBoundException ex) { }
![Page 24: Li Tak Sing COMPS311F. RMI callbacks In previous example, only the client can initiate a communication with the server. The server can only response to](https://reader031.vdocuments.us/reader031/viewer/2022032308/56649f475503460f94c69060/html5/thumbnails/24.jpg)
Some methods of ChatClientImp public String name() throws
RemoteException { return name.getText(); }
public void toClient(String st) throws java.rmi.RemoteException {
textarea.append(st + "\n"); }
![Page 25: Li Tak Sing COMPS311F. RMI callbacks In previous example, only the client can initiate a communication with the server. The server can only response to](https://reader031.vdocuments.us/reader031/viewer/2022032308/56649f475503460f94c69060/html5/thumbnails/25.jpg)
The main method of ChatClientImp public static void main(String st[]) throws
RemoteException { new ChatClientImp(); }
Note that we do not need to register the client with any RMI registries. The client would be sent to the server via a method call. So the server would not need to get the client from an RMI registry.
![Page 26: Li Tak Sing COMPS311F. RMI callbacks In previous example, only the client can initiate a communication with the server. The server can only response to](https://reader031.vdocuments.us/reader031/viewer/2022032308/56649f475503460f94c69060/html5/thumbnails/26.jpg)
Some features of this RMI serverThere is no need to handle multithreading
in the RMI version of the server. Multithreading is handled by the internal mechanism of RMI.
Although we do not create threads, we still need to make the server thread safe as RMI is multithreaded. Therefore, we use the synchronized keyword whenever needed.
![Page 27: Li Tak Sing COMPS311F. RMI callbacks In previous example, only the client can initiate a communication with the server. The server can only response to](https://reader031.vdocuments.us/reader031/viewer/2022032308/56649f475503460f94c69060/html5/thumbnails/27.jpg)
Problems of the RMI ChatServerAlthough we have a button for the user to
disconnect from the server, it has problem for the server to keep track of clients that have quit execution without informing the server.
In the socket version of the ChatServer, when a client quit execution, a network exception would be thrown at the server side so that the server would know that the client has quit. This is not the case for RMI. The server would not know that a client has quit execution.
![Page 28: Li Tak Sing COMPS311F. RMI callbacks In previous example, only the client can initiate a communication with the server. The server can only response to](https://reader031.vdocuments.us/reader031/viewer/2022032308/56649f475503460f94c69060/html5/thumbnails/28.jpg)
The java.rmi.server.Unreferenced interfaceThis interface has one method:
public void unreferenced() throws RemoteException
After a remote object has implemented this interface, then the unreferenced method will be invoked when it is not referenced anywhere.
![Page 29: Li Tak Sing COMPS311F. RMI callbacks In previous example, only the client can initiate a communication with the server. The server can only response to](https://reader031.vdocuments.us/reader031/viewer/2022032308/56649f475503460f94c69060/html5/thumbnails/29.jpg)
The java.rmi.server.Unreferenced interfaceThere are sever ways that an external
reference to a remote object disappear:The client quits execution.The reference to the object is set to null. For
example:ChatServer server=registry.lookup("chat");
.....server=null; //the remote object is not referenced by server
The variable that references the object is garbage collected.
![Page 30: Li Tak Sing COMPS311F. RMI callbacks In previous example, only the client can initiate a communication with the server. The server can only response to](https://reader031.vdocuments.us/reader031/viewer/2022032308/56649f475503460f94c69060/html5/thumbnails/30.jpg)
How to know that a client has quit?For every client that is connected to the
server, we pass to it a newly created object that has implemented the Unreferenced interface. Then, when the client has quit, the object is not reference anywhere as we only pass the object to one client. In this way, the corresponding unreferenced method would be invoked.
![Page 31: Li Tak Sing COMPS311F. RMI callbacks In previous example, only the client can initiate a communication with the server. The server can only response to](https://reader031.vdocuments.us/reader031/viewer/2022032308/56649f475503460f94c69060/html5/thumbnails/31.jpg)
But there is a delay before unreferenced is calledNote that the unreferenced method would
only be invoked for a delay of 10 minutes after all referencing clients have quit.
![Page 32: Li Tak Sing COMPS311F. RMI callbacks In previous example, only the client can initiate a communication with the server. The server can only response to](https://reader031.vdocuments.us/reader031/viewer/2022032308/56649f475503460f94c69060/html5/thumbnails/32.jpg)
Modified Chat server You can find the server in the same file for
the original server. But this time, the server is in the RMIChat2 package.
A new Contact interface is needed for this purpose:public interface Contact extends
java.rmi.Remote {
}The interface has no method. It only use is to
have the object implementing this also implements the Unreferenced interface.
![Page 33: Li Tak Sing COMPS311F. RMI callbacks In previous example, only the client can initiate a communication with the server. The server can only response to](https://reader031.vdocuments.us/reader031/viewer/2022032308/56649f475503460f94c69060/html5/thumbnails/33.jpg)
Implementation of Contact public class ContactImp extends
UnicastRemoteObject implements Contact, Unreferenced {
private ChatClient client; public ContactImp(ChatClient c) throws
RemoteException { client = c; } public void unreferenced() { clients.remove(client); displayClients(); } }
![Page 34: Li Tak Sing COMPS311F. RMI callbacks In previous example, only the client can initiate a communication with the server. The server can only response to](https://reader031.vdocuments.us/reader031/viewer/2022032308/56649f475503460f94c69060/html5/thumbnails/34.jpg)
Changes to ChatServerImpThe connect method is changed as following: public Contact connect(ChatClient c) throws
RemoteException { clients.add(c); displayClients(); return new ContactImp(c); }
![Page 35: Li Tak Sing COMPS311F. RMI callbacks In previous example, only the client can initiate a communication with the server. The server can only response to](https://reader031.vdocuments.us/reader031/viewer/2022032308/56649f475503460f94c69060/html5/thumbnails/35.jpg)
Changes to ChatClientThe following attribute is added:
private Contact contact;
The code to connect to the server is changed as following: Registry registry =
java.rmi.registry.LocateRegistry.getRegistry("localhost");
server = (ChatServer) registry.lookup("chat2");
contact=server.connect(ChatClientImp.this);
.......