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
