tanszek:oktatas:iss_t:group_chat
Differences
This shows you the differences between two versions of the page.
tanszek:oktatas:iss_t:group_chat [2024/04/07 14:54] – created superuser | tanszek:oktatas:iss_t:group_chat [2024/04/07 15:03] (current) – superuser | ||
---|---|---|---|
Line 5: | Line 5: | ||
Create two projects in a Java IDE for the client and server respectively. The following interaction diagram illustrates the conceptual operation. | Create two projects in a Java IDE for the client and server respectively. The following interaction diagram illustrates the conceptual operation. | ||
+ | < | ||
+ | sequenceDiagram | ||
+ | participant U as User | ||
+ | participant UI as ChatUI | ||
+ | participant CC as ChatClient | ||
+ | participant CS as ChatServer | ||
+ | participant IC as IChatClient | ||
+ | participant IS as IChatServer | ||
+ | U->> | ||
+ | UI->> | ||
+ | CC->> | ||
+ | IS->> | ||
+ | CS->> | ||
+ | IC->> | ||
+ | CC->> | ||
+ | UI->> | ||
+ | | ||
+ | U->> | ||
+ | UI->> | ||
+ | CC->> | ||
+ | IS->> | ||
+ | CS->> | ||
+ | IC->> | ||
+ | CC->> | ||
+ | UI->> | ||
+ | |||
+ | U->> | ||
+ | UI->> | ||
+ | CC->> | ||
+ | IS->> | ||
+ | CS-->> | ||
+ | IC->> | ||
+ | CC->> | ||
+ | UI->> | ||
+ | </ | ||
+ | |||
+ | We can create another diagram to demonstrate the operation: | ||
+ | |||
+ | * **ChatUI** is the user interface, which directly communicates with ChatClient. | ||
+ | * **ChatClient** is the client-side logic, implementing the IChatClient interface. | ||
+ | * **Java RMI Registry** serves for resolving service names, used by ChatClient to access the IChatServer interface. | ||
+ | * **IChatServer** is the interface through which ChatClient communicates with ChatServer. | ||
+ | * **ChatServer** is the server-side logic, implementing the IChatServer interface. | ||
+ | * **Client List** is the list of connected clients on the server. | ||
+ | * **User Interface** represents the user interface components interacting with the user. | ||
+ | |||
+ | This diagram shows the system' | ||
+ | |||
+ | < | ||
+ | graph TD | ||
+ | A[ChatUI] --> B[ChatClient] | ||
+ | B --> C{Java RMI Registry} | ||
+ | B --> | ||
+ | D --> E[ChatServer] | ||
+ | E --> F[IChatClient] | ||
+ | F --> B | ||
+ | D -.-> G[Client List] | ||
+ | E --> G | ||
+ | |||
+ | A -.-> H[User Interface] | ||
+ | H --> A | ||
+ | |||
+ | C -.-> | ||
+ | |||
+ | style A fill:# | ||
+ | style B fill:# | ||
+ | style C fill:# | ||
+ | style D fill:# | ||
+ | style E fill:# | ||
+ | style F fill:# | ||
+ | style G fill:# | ||
+ | style H fill:# | ||
+ | </ | ||
+ | |||
+ | ==== Project 1: ChatServer ==== | ||
+ | |||
+ | 1.) IChatClient | ||
+ | |||
+ | <sxh java> | ||
+ | import java.rmi.Remote; | ||
+ | import java.rmi.RemoteException; | ||
+ | | ||
+ | public interface IChatClient extends Remote { | ||
+ | public void tell(String name) throws RemoteException; | ||
+ | public String getName() throws RemoteException; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | 2.) IChatServer | ||
+ | |||
+ | <sxh java> | ||
+ | import java.rmi.Remote; | ||
+ | import java.rmi.RemoteException; | ||
+ | import java.util.ArrayList; | ||
+ | | ||
+ | public interface IChatServer extends Remote { | ||
+ | public boolean login(IChatClient client) throws RemoteException; | ||
+ | | ||
+ | public void publish(String s) throws RemoteException; | ||
+ | | ||
+ | public ArrayList< | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | 3.) ChatServer | ||
+ | |||
+ | <sxh java> | ||
+ | import java.rmi.RemoteException; | ||
+ | import java.rmi.server.UnicastRemoteObject; | ||
+ | import java.util.ArrayList; | ||
+ | | ||
+ | public class ChatServer extends UnicastRemoteObject implements IChatServer { | ||
+ | private static final long serialVersionUID = 4705993250126188735L; | ||
+ | private ArrayList< | ||
+ | | ||
+ | public ChatServer() throws RemoteException { | ||
+ | } | ||
+ | | ||
+ | public boolean login(IChatClient client) throws RemoteException { | ||
+ | System.out.println(client.getName() + " got connected...." | ||
+ | client.tell(" | ||
+ | publish(client.getName() + " connected." | ||
+ | v.add(client); | ||
+ | return true; | ||
+ | } | ||
+ | | ||
+ | public void publish(String s) throws RemoteException { | ||
+ | System.out.println(s); | ||
+ | for (int i = 0; i < v.size(); i++) { | ||
+ | try { | ||
+ | IChatClient tmp = (IChatClient) v.get(i); | ||
+ | tmp.tell(s); | ||
+ | } catch (Exception e) { | ||
+ | e.printStackTrace(); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | | ||
+ | public ArrayList< | ||
+ | return v; | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | 4.) StartServer | ||
+ | |||
+ | <sxh java> | ||
+ | import java.rmi.Naming; | ||
+ | | ||
+ | public class StartServer { | ||
+ | public static void main(String[] args) { | ||
+ | try { | ||
+ | // System.setSecurityManager(new RMISecurityManager()); | ||
+ | java.rmi.registry.LocateRegistry.createRegistry(1099); | ||
+ | IChatServer server = new ChatServer(); | ||
+ | Naming.rebind(" | ||
+ | System.out.println(" | ||
+ | } catch (Exception e) { | ||
+ | e.printStackTrace(); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ===== Client Side ===== | ||
+ | |||
+ | ==== Project 2: ChatClient ==== | ||
+ | |||
+ | 1.) ChatClient | ||
+ | |||
+ | <sxh java> | ||
+ | import java.rmi.RemoteException; | ||
+ | import java.rmi.server.UnicastRemoteObject; | ||
+ | | ||
+ | public class ChatClient extends UnicastRemoteObject implements IChatClient { | ||
+ | private String name; | ||
+ | private ChatUI ui; | ||
+ | | ||
+ | public ChatClient(String n) throws RemoteException { | ||
+ | name = n; | ||
+ | } | ||
+ | | ||
+ | public void tell(String st) throws RemoteException { | ||
+ | System.out.println(st); | ||
+ | ui.writeMsg(st); | ||
+ | } | ||
+ | | ||
+ | public String getName() throws RemoteException { | ||
+ | return name; | ||
+ | } | ||
+ | | ||
+ | public void setGUI(ChatUI t) { | ||
+ | ui = t; | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | 2.) ChatUI | ||
+ | |||
+ | <sxh java> | ||
+ | import java.awt.BorderLayout; | ||
+ | import java.awt.GridLayout; | ||
+ | import java.awt.event.ActionEvent; | ||
+ | import java.awt.event.ActionListener; | ||
+ | import java.rmi.Naming; | ||
+ | import java.util.ArrayList; | ||
+ | | ||
+ | import javax.swing.DefaultListModel; | ||
+ | import javax.swing.JButton; | ||
+ | import javax.swing.JFrame; | ||
+ | import javax.swing.JLabel; | ||
+ | import javax.swing.JList; | ||
+ | import javax.swing.JOptionPane; | ||
+ | import javax.swing.JPanel; | ||
+ | import javax.swing.JScrollPane; | ||
+ | import javax.swing.JTextArea; | ||
+ | import javax.swing.JTextField; | ||
+ | import javax.swing.border.EmptyBorder; | ||
+ | | ||
+ | public class ChatUI { | ||
+ | private ChatClient client; | ||
+ | private IChatServer server; | ||
+ | | ||
+ | public void doConnect() { | ||
+ | if (connect.getText().equals(" | ||
+ | if (name.getText().length() < 2) { | ||
+ | JOptionPane.showMessageDialog(frame, | ||
+ | return; | ||
+ | } | ||
+ | if (ip.getText().length() < 2) { | ||
+ | JOptionPane.showMessageDialog(frame, | ||
+ | return; | ||
+ | } | ||
+ | try { | ||
+ | client = new ChatClient(name.getText()); | ||
+ | client.setGUI(this); | ||
+ | server = (IChatServer) Naming.lookup(" | ||
+ | server.login(client); | ||
+ | updateUsers(server.getConnected()); | ||
+ | connect.setText(" | ||
+ | } catch (Exception e) { | ||
+ | e.printStackTrace(); | ||
+ | JOptionPane.showMessageDialog(frame, | ||
+ | } | ||
+ | } else { | ||
+ | updateUsers(null); | ||
+ | connect.setText(" | ||
+ | } | ||
+ | } | ||
+ | | ||
+ | public void sendText() { | ||
+ | if (connect.getText().equals(" | ||
+ | JOptionPane.showMessageDialog(frame, | ||
+ | return; | ||
+ | } | ||
+ | String st = tf.getText(); | ||
+ | st = " | ||
+ | tf.setText("" | ||
+ | // Remove if you are going to implement for remote invocation | ||
+ | try { | ||
+ | server.publish(st); | ||
+ | } catch (Exception e) { | ||
+ | e.printStackTrace(); | ||
+ | } | ||
+ | } | ||
+ | | ||
+ | public void writeMsg(String st) { | ||
+ | tx.setText(tx.getText() + " | ||
+ | } | ||
+ | | ||
+ | public void updateUsers(ArrayList< | ||
+ | DefaultListModel< | ||
+ | if (users != null) | ||
+ | for (int i = 0; i < users.size(); | ||
+ | try { | ||
+ | String tmp = ((IChatClient) users.get(i)).getName(); | ||
+ | listModel.addElement(tmp); | ||
+ | } catch (Exception e) { | ||
+ | e.printStackTrace(); | ||
+ | } | ||
+ | } | ||
+ | list.setModel(listModel); | ||
+ | } | ||
+ | | ||
+ | public static void main(String[] args) { | ||
+ | System.out.println(" | ||
+ | ChatUI c = new ChatUI(); | ||
+ | } | ||
+ | | ||
+ | // User Interface code. | ||
+ | public ChatUI() { | ||
+ | frame = new JFrame(" | ||
+ | JPanel main = new JPanel(); | ||
+ | JPanel top = new JPanel(); | ||
+ | JPanel cn = new JPanel(); | ||
+ | JPanel bottom = new JPanel(); | ||
+ | ip = new JTextField(); | ||
+ | tf = new JTextField(); | ||
+ | name = new JTextField(); | ||
+ | tx = new JTextArea(); | ||
+ | connect = new JButton(" | ||
+ | JButton bt = new JButton(" | ||
+ | list = new JList(); | ||
+ | main.setLayout(new BorderLayout(5, | ||
+ | top.setLayout(new GridLayout(1, | ||
+ | cn.setLayout(new BorderLayout(5, | ||
+ | bottom.setLayout(new BorderLayout(5, | ||
+ | top.add(new JLabel(" | ||
+ | top.add(name); | ||
+ | top.add(new JLabel(" | ||
+ | top.add(ip); | ||
+ | top.add(connect); | ||
+ | cn.add(new JScrollPane(tx), | ||
+ | cn.add(list, | ||
+ | bottom.add(tf, | ||
+ | bottom.add(bt, | ||
+ | main.add(top, | ||
+ | main.add(cn, | ||
+ | main.add(bottom, | ||
+ | main.setBorder(new EmptyBorder(10, | ||
+ | // Events | ||
+ | connect.addActionListener(new ActionListener() { | ||
+ | public void actionPerformed(ActionEvent e) { | ||
+ | doConnect(); | ||
+ | } | ||
+ | }); | ||
+ | bt.addActionListener(new ActionListener() { | ||
+ | public void actionPerformed(ActionEvent e) { | ||
+ | sendText(); | ||
+ | } | ||
+ | }); | ||
+ | tf.addActionListener(new ActionListener() { | ||
+ | public void actionPerformed(ActionEvent e) { | ||
+ | sendText(); | ||
+ | } | ||
+ | }); | ||
+ | frame.setContentPane(main); | ||
+ | frame.setSize(600, | ||
+ | frame.setVisible(true); | ||
+ | } | ||
+ | | ||
+ | JTextArea tx; | ||
+ | JTextField tf, ip, name; | ||
+ | JButton connect; | ||
+ | JList list; | ||
+ | JFrame frame; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Task 1: Implement functionality so that when new clients join, the existing ones receive the complete user list. |
tanszek/oktatas/iss_t/group_chat.1712501640.txt.gz · Last modified: 2024/04/07 14:54 by superuser