User Tools

Site Tools


tanszek:oktatas:iss_t:group_chat

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

tanszek:oktatas:iss_t:group_chat [2024/04/07 14:54] – created superusertanszek: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.
  
 +<mermaid>
 +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: Starts Application
 +    UI->>CC: Creates ChatClient
 +    CC->>IS: Tries to connect
 +    IS->>CS: Login request
 +    CS->>IC: Checks if client can connect
 +    IC->>CC: Connection successful
 +    CC->>UI: Update UI (Connected)
 +    UI->>U: Show connected status
 +    
 +    U->>UI: Enter message
 +    UI->>CC: Send message
 +    CC->>IS: Publish message
 +    IS->>CS: Publish message to all clients
 +    CS->>IC: Iterate over clients
 +    IC->>CC: Display message
 +    CC->>UI: Update UI with new message
 +    UI->>U: Show new message
 +
 +    U->>UI: Disconnect
 +    UI->>CC: Disconnect from server
 +    CC->>IS: Logout request
 +    IS->>CS: Remove client from list
 +    CS-->>IC: Update client list
 +    IC->>CC: Acknowledge disconnect
 +    CC->>UI: Update UI (Disconnected)
 +    UI->>U: Show disconnected status
 +</mermaid>
 +
 +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's component connectivity and communication structure, including the interactions between client and server.
 +
 +<mermaid>
 +graph TD
 +    A[ChatUI] --> B[ChatClient]
 +    B --> C{Java RMI Registry}
 +    B -->|lookup| D[IChatServer]
 +    D --> E[ChatServer]
 +    E --> F[IChatClient]
 +    F --> B
 +    D -.-> G[Client List]
 +    E --> G
 +
 +    A -.-> H[User Interface]
 +    H --> A
 +
 +    C -.->|registers| E
 +
 +    style A fill:#f9f,stroke:#333,stroke-width:4px
 +    style B fill:#bbf,stroke:#f66,stroke-width:2px,stroke-dasharray: 5, 5
 +    style C fill:#fea,stroke:#333,stroke-width:2px
 +    style D fill:#bbf,stroke:#f66,stroke-width:2px,stroke-dasharray: 5, 5
 +    style E fill:#f99,stroke:#333,stroke-width:4px
 +    style F fill:#bbf,stroke:#f66,stroke-width:2px,stroke-dasharray: 5, 5
 +    style G fill:#dff,stroke:#333,stroke-width:2px
 +    style H fill:#fff,stroke:#333,stroke-width:2px
 +</mermaid>
 +
 +==== 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;
 +  }
 +</sxh>
 +
 +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<IChatClient> getConnected() throws RemoteException;
 +  }
 +</sxh>
 +
 +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<IChatClient> v = new ArrayList<IChatClient>();
 +  
 +      public ChatServer() throws RemoteException {
 +      }
 +  
 +      public boolean login(IChatClient client) throws RemoteException {
 +          System.out.println(client.getName() + " got connected....");
 +          client.tell("You're connected");
 +          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<IChatClient> getConnected() throws RemoteException {
 +          return v;
 +      }
 +  }
 +</sxh>
 +
 +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("rmi://localhost:1099/chatserver", server);
 +              System.out.println("Server ready.");
 +          } catch (Exception e) {
 +              e.printStackTrace();
 +          }
 +      }
 +  }
 +</sxh>
 +
 +===== 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;
 +      }
 +  }
 +</sxh>
 +
 +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("Connect")) {
 +              if (name.getText().length() < 2) {
 +                  JOptionPane.showMessageDialog(frame, "You need to type a name.");
 +                  return;
 +              }
 +              if (ip.getText().length() < 2) {
 +                  JOptionPane.showMessageDialog(frame, "You need to type an IP.");
 +                  return;
 +              }
 +              try {
 +                  client = new ChatClient(name.getText());
 +                  client.setGUI(this);
 +                  server = (IChatServer) Naming.lookup("rmi://"+ ip.getText() +"/chatserver");
 +                  server.login(client);
 +                  updateUsers(server.getConnected());
 +                  connect.setText("Disconnect");
 +              } catch (Exception e) {
 +                  e.printStackTrace();
 +                  JOptionPane.showMessageDialog(frame, "ERROR, we couldn't connect....");
 +              }
 +          } else {
 +              updateUsers(null);
 +              connect.setText("Connect");
 +          }
 +      }
 +  
 +      public void sendText() {
 +          if (connect.getText().equals("Connect")) {
 +              JOptionPane.showMessageDialog(frame, "You need to connect first.");
 +              return;
 +          }
 +          String st = tf.getText();
 +          st = "[" + name.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() + "\n" + st);
 +      }
 +  
 +      public void updateUsers(ArrayList<IChatClient> users) {
 +          DefaultListModel<String> listModel = new DefaultListModel<String>();
 +          if (users != null)
 +              for (int i = 0; i < users.size(); i++) {
 +                  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("Hello World !");
 +          ChatUI c = new ChatUI();
 +      }
 +  
 +      // User Interface code.
 +      public ChatUI() {
 +          frame = new JFrame("Group Chat");
 +          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("Connect");
 +          JButton bt = new JButton("Send");
 +          list = new JList();
 +          main.setLayout(new BorderLayout(5, 5));
 +          top.setLayout(new GridLayout(1, 0, 5, 5));
 +          cn.setLayout(new BorderLayout(5, 5));
 +          bottom.setLayout(new BorderLayout(5, 5));
 +          top.add(new JLabel("Your name: "));
 +          top.add(name);
 +          top.add(new JLabel("Server Address: "));
 +          top.add(ip);
 +          top.add(connect);
 +          cn.add(new JScrollPane(tx), BorderLayout.CENTER);
 +          cn.add(list, BorderLayout.EAST);
 +          bottom.add(tf, BorderLayout.CENTER);
 +          bottom.add(bt, BorderLayout.EAST);
 +          main.add(top, BorderLayout.NORTH);
 +          main.add(cn, BorderLayout.CENTER);
 +          main.add(bottom, BorderLayout.SOUTH);
 +          main.setBorder(new EmptyBorder(10, 10, 10, 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, 600);
 +          frame.setVisible(true);
 +      }
 +  
 +      JTextArea tx;
 +      JTextField tf, ip, name;
 +      JButton connect;
 +      JList list;
 +      JFrame frame;
 +  }
 +</sxh>
 +
 +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