《OnlineChat996》基于微信群聊的在线实时通信工具


项目源码:你和我的畅聊时光


一、主要功能

  1. 注册,成为我们的注册会员用户,你将拥有全网唯一的ID。
  2. 登录,进入拥有千万好友的畅聊空间。
  3. 私聊,你可以选择和任意在线用户进行一次亲密对话。
  4. 群聊,只要你想,没有不可以。你们的团体就是一个小群组。

二、具体实现

1.服务器与客户端的连接

服务器加载所有的配置信息,包括数据库的密码等。服务器根据Socket与客户端连接,服务器根据收到的不同类型信息而进行不同的操作。如1代表用户注册操作。
1.注册:将用户信息存储到服务器。登录后将新上线的用户信息发回给当前已在线的所有用户。
2.私聊:服务器会检测到所有的私聊信息以及发送方和接收方。
3.注册群:群名和群成员信息存储在Map集合中。
4.群聊:服务器会接收到所有的群聊消息,并发送给群聊内的每一个用户。

public class MultiThreadServer {
    private static final String IP;
    private static final int PORT;
    // 缓存当前服务器所有在线的客户端信息
    private static Map<String, Socket> clients = new ConcurrentHashMap<>();
    // 缓存当前服务器注册的所有群名称以及群好友
    private static Map<String,Set<String>> groups = new ConcurrentHashMap<>();
    static {
        Properties pros = CommUtils.loadProperties("socket.properties");
        IP = pros.getProperty("address");
        PORT = Integer.parseInt(pros.getProperty("port"));
    }

    private static class ExecuteClient implements Runnable {
        private Socket client;
        private Scanner in;
        private PrintStream out;

        public ExecuteClient(Socket client) {
            this.client = client;
            try {
                this.in = new Scanner(client.getInputStream());
                this.out = new PrintStream(client.getOutputStream(),
                        true,"UTF-8");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        @Override
        public void run() {
            while (true) {
                if (in.hasNextLine()) {
                    String jsonStrFromClient = in.nextLine();
                    MessageVO msgFromClient =
                            (MessageVO) CommUtils.json2Object(jsonStrFromClient,
                                    MessageVO.class);
                    // 新用户注册到服务端
                    if (msgFromClient.getType().equals("1")) {
                        String userName = msgFromClient.getContent();
                        // 将当前在线的所有用户名发回客户端
                        MessageVO msg2Client = new MessageVO();
                        msg2Client.setType("1");
                        msg2Client.setContent(CommUtils.object2Json(
                                clients.keySet()
                        ));
                        out.println(CommUtils.object2Json(msg2Client));
                        // 将新上线的用户信息发回给当前已在线的所有用户
                        sendUserLogin("newLogin:"+userName);
                        // 将当前新用户注册到服务端缓存
                        clients.put(userName,client);
                        System.out.println(userName+"上线了!");
                        System.out.println("当前聊天室共有"+
                                clients.size()+"人");
                    }
                    else if (msgFromClient.getType().equals("2")) {
                        // 用户私聊
                        // type:2
                        //  Content:myName-msg
                        //  to:friendName
                        String friendName = msgFromClient.getTo();
                        Socket clientSocket = clients.get(friendName);
                        try {
                            PrintStream out = new PrintStream(clientSocket.getOutputStream(),
                                    true,"UTF-8");
                            MessageVO msg2Client = new MessageVO();
                            msg2Client.setType("2");
                            msg2Client.setContent(msgFromClient.getContent());
                            System.out.println("收到私聊信息,内容为"+msgFromClient.getContent());
                            out.println(CommUtils.object2Json(msg2Client));
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }else if (msgFromClient.getType().equals("3")) {
                        // 注册群
                        String groupName = msgFromClient.getContent();
                        // 该群的所有群成员
                        Set<String> friends = (Set<String>) CommUtils.json2Object(
                                msgFromClient.getTo(),Set.class);
                        groups.put(groupName,friends);
                        System.out.println("有新的群注册成功,群名称为"+
                                groupName+",一共有"+groups.size() + "个群");
                    }else if (msgFromClient.getType().equals("4")) {
                        // 群聊信息
                        System.out.println("服务器收到的群聊信息为:"+msgFromClient);
                        String groupName = msgFromClient.getTo();
                        Set<String> names = groups.get(groupName);
                        Iterator<String> iterator = names.iterator();
                        while (iterator.hasNext()) {
                            String socketName = iterator.next();
                            Socket client = clients.get(socketName);
                            try {
                                PrintStream out = new PrintStream(client.getOutputStream(),
                                        true,"UTF-8");
                                MessageVO messageVO = new MessageVO();
                                messageVO.setType("4");
                                messageVO.setContent(msgFromClient.getContent());
                                // 群名-[]
                                messageVO.setTo(groupName+"-"+CommUtils.object2Json(names));
                                out.println(CommUtils.object2Json(messageVO));
                                System.out.println("服务端发送的群聊信息为:"+messageVO);
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
            }
        }

        /**
         * 向所有在线用户发送新用户上线信息
         * @param msg
         */
        private void sendUserLogin(String msg) {
            for (Map.Entry<String,Socket> entry: clients.entrySet()) {
                Socket socket = entry.getValue();
                try {
                    PrintStream out = new PrintStream(socket.getOutputStream(),
                            true,"UTF-8");
                    out.println(msg);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(PORT);
        ExecutorService executors = Executors.
                newFixedThreadPool(50);
        for (int i = 0; i < 50; i++) {
            System.out.println("等待客户端连接...");
            Socket client = serverSocket.accept();
            System.out.println("有新的连接,端口号为"+client.getPort());
            executors.submit(new ExecuteClient(client));
        }
    }
}

2.注册功能的实现

获取到用户在注册页面输入的所有内容,封装到User类中,存储到数据库中。如果提示注册成功,则返回到登录页面;否则,停留在当前页面。

public UserReg() {
        JFrame frame = new JFrame("用户注册");
        frame.setContentPane(userRegPanel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.pack();
        frame.setVisible(true);
        // 点击注册按钮,将信息持久化到db中,成功弹出提示框
        regBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                // 获取用户输入的注册信息
                String userName = userNameText.getText();
                String password = String.valueOf
                        (passwordText.getPassword());
                String brief = brifeText.getText();
                // 将输入信息包装为User类,保存到数据库中
                User user = new User();
                user.setUserName(userName);
                user.setPassword(password);
                user.setBrief(brief);
                // 调用dao对象
                if (accountDao.userReg(user)) {//将user信息存到数据库中
                    // 返回登录页面
                    JOptionPane.showMessageDialog(frame,"注册成功!",
                            "提示信息",JOptionPane.INFORMATION_MESSAGE);
                    frame.setVisible(false);
                }else {
                    // 保留当前注册页面
                    JOptionPane.showMessageDialog(frame,"注册失败!",
                            "错误信息",JOptionPane.ERROR_MESSAGE);
                }
            }
        });

    }
3.登录的实现

构建登录界面,给每个按钮设置点击事件。
1.注册按钮,则弹出注册页面
2.登录按钮,则获取用户输入的用户名、密码。
2.1校验用户信息,在数据中查找是否存在此用户。不存在,提示登录失败,留在登录界面。用户可以选择注册,所有的注册信息存储在服务器的数据库中。
2.2存在,提示登录成功!然后与服务器建立连接,将当前用户的用户名发送到服务器。
2.3读取服务端发回的所有在线用户信息,通知每个在线用户有某用户上线了。

public UserLogin() {
        frame = new JFrame("用户登录");
        frame.setContentPane(UserLoginPanel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.pack();
        frame.setVisible(true);
        // 注册按钮
        regButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                // 弹出注册页面
                new UserReg();
            }
        });
        // 登录按钮
        loginButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                // 校验用户信息
                String userName = userNameText.getText();
                String password = String.valueOf(
                        passwordText.getPassword());
                User user = accountDao.userLogin(userName,password);//在数据库中查看是否有对应的用户名和密码
                if (user != null) {
                    // 成功,加载用户列表
                    JOptionPane.showMessageDialog(frame,
                             "登录成功!","提示信息",JOptionPane.INFORMATION_MESSAGE);
                    frame.setVisible(false);
                    // 与服务器建立连接,将当前用户的用户名发送到服务端
                    Connect2Server connect2Server = new Connect2Server();
                    MessageVO msg2Server = new MessageVO();
                    msg2Server.setType("1");
                    msg2Server.setContent(userName);
                    String json2Server = CommUtils.object2Json(msg2Server);
                    try {
                        PrintStream out = new PrintStream(connect2Server.getOut(),
                                true,"UTF-8");
                        out.println(json2Server);
                        // 读取服务端发回的所有在线用户信息
                        Scanner in = new Scanner(connect2Server.getIn());
                        if (in.hasNextLine()) {
                            String msgFromServerStr = in.nextLine();
                            MessageVO msgFromServer =
                                    (MessageVO) CommUtils.json2Object(msgFromServerStr,
                                            MessageVO.class);
                            Set<String> users =
                                    (Set<String>) CommUtils.json2Object(msgFromServer.getContent(),
                                            Set.class);
                            System.out.println("所有在线用户为:"+users);
                            // 加载用户列表界面
                            // 将当前用户名、所有在线好友、与服务器建立连接传递到好友列表界面
                            new FriendsList(userName,users,connect2Server);
                        }
                    } catch (UnsupportedEncodingException ex) {
                        ex.printStackTrace();
                    }
                }else {
                    // 失败,停留在当前登录页面,提示用户信息错误
                    JOptionPane.showMessageDialog(frame,
                            "登录失败!","错误信息",
                            JOptionPane.ERROR_MESSAGE);
                }
            }
        });
    }
4.私聊

1.当用户A在在线好友列表界面双击用户B,即进入私聊界面。
2.用户输入信息,按回车,即将信息发送给服务器。发送到服务器之前,工具类会封装发送方A的用户名、消息内容、聊天类型、接收方B的用户名,将其转为json字符串。
3.服务器对json字符串进行解析,决定进行私聊操作,服务器将信息发送给B。发送到B之前会将json字符串转为Object对象,用户B最终才接收到A发送的消息。

public PrivateChatGUI(String friendName,
                          String myName,
                          Connect2Server connect2Server) {
        this.friendName = friendName;
        this.myName = myName;
        this.connect2Server = connect2Server;
        try {
            this.out = new PrintStream(connect2Server.getOut(),true,
                    "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        frame = new JFrame("与"+friendName+"私聊中...");
        frame.setContentPane(privateChatPanel);
        // 设置窗口关闭的操作,将其设置为隐藏
        frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
        frame.setSize(400,400);
        frame.setVisible(true);
        // 捕捉输入框的键盘输入
        send2Server.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                StringBuilder sb = new StringBuilder();
                sb.append(send2Server.getText());
                // 1.当捕捉到按下Enter
                if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                    // 2.将当前信息发送到服务端
                    String msg = sb.toString();
                    MessageVO messageVO = new MessageVO();
                    messageVO.setType("2");
                    messageVO.setContent(myName+"-"+msg);
                    messageVO.setTo(friendName);
                    PrivateChatGUI.this.out.println(CommUtils.object2Json(messageVO));
                    // 3.将自己发送的信息展示到当前私聊界面
                    readFromServer(myName+"说:"+msg);
                    send2Server.setText("");
                }
            }
        });
    }

5.群聊
(1)创建群:

1.点击创建群,进入创建群界面。所有的在线好友以列表形式展现。
2.选择你想选择的用户,勾选进行多选,已选择的用户会存储在集合中。
3.将自己加入到群聊集合中,存储群名。
4.用工具类将群名、群成员信息、当前类的操作类型3,封装成json字符串,发送给服务器。
5.隐藏创建群界面,然后刷新群列表界面。

public CreateGroupGUI(String myName,
                          Set<String> friends,
                          Connect2Server connect2Server,
                          FriendsList friendsList) {
        this.myName = myName;
        this.friends = friends;
        this.connect2Server = connect2Server;
        this.friendsList = friendsList;
        JFrame frame = new JFrame("创建群组");
        frame.setContentPane(createGroupPanel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400,300);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
        // 将在线好友以checkBox展示到界面中
        friendLabelPanel.setLayout(new BoxLayout(friendLabelPanel,BoxLayout.Y_AXIS));
        Iterator<String> iterator = friends.iterator();
        while (iterator.hasNext()) {
            String labelName = iterator.next();
            JCheckBox checkBox = new JCheckBox(labelName);
            friendLabelPanel.add(checkBox);
        }
        // 点击提交按钮提交信息到服务端
        conformBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                // 1.判断哪些好友选中加入群聊
                Set<String> selectedFriends = new HashSet<>();
                Component[] comps = friendLabelPanel.getComponents();
                for (Component comp : comps) {
                    JCheckBox checkBox = (JCheckBox) comp;
                    if (checkBox.isSelected()) {
                        String labelName = checkBox.getText();
                        selectedFriends.add(labelName);
                    }
                }
                selectedFriends.add(myName);
                // 2.获取群名输入框输入的群名称
                String groupName = groupNameText.getText();
                // 3.将群名+选中好友信息发送到服务端
                // type:3
                // content:groupName
                // to:[user1,user2,user3...]
                MessageVO messageVO = new MessageVO();
                messageVO.setType("3");
                messageVO.setContent(groupName);
                messageVO.setTo(CommUtils.object2Json(selectedFriends));
                try {
                    PrintStream out = new PrintStream(connect2Server.getOut(),
                            true,"UTF-8");
                    out.println(CommUtils.object2Json(messageVO));
                } catch (UnsupportedEncodingException ex) {
                    ex.printStackTrace();
                }
                // 4.将当前创建群界面隐藏,刷新好友列表界面的群列表
                frame.setVisible(false);
                // addGroupInfo
                // loadGroup
                friendsList.addGroup(groupName,selectedFriends);
                friendsList.loadGroupList();
            }
        });
    }
(2)群聊操作:

1.双击一个群,进入群聊。
2.用户A发送信息,将群聊消息、操作类型、和其他群成员信息封装成json字符串发送到服务器。
3.服务器接收到后,将群聊消息发送给所有的群成员。
这里需要注意的是:
a. 只有群主才能发送第一条消息。
b. 创建群时,只有群主的群列表才会刷新,其他群成员并不知道有这个群的存在。
c. 只有当群主发了第一条信息时,其他成员的群列表才会刷新出这个群。
这一点仿照了微信群聊的特点。

send2Server.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                StringBuilder sb = new StringBuilder();
                sb.append(send2Server.getText());
                // 捕捉回车按键
                if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                    String str2Server = sb.toString();
                    // type:4
                    // content:myName-msg
                    // to:groupName
                    MessageVO messageVO = new MessageVO();
                    messageVO.setType("4");
                    messageVO.setContent(myName+"-"+str2Server);
                    messageVO.setTo(groupName);
                    try {
                        PrintStream out = new PrintStream(connect2Server.getOut(),
                                true,"UTF-8");
                        out.println(CommUtils.object2Json(messageVO));
                        System.out.println("客户端发送的群聊信息为:"+messageVO);
                    } catch (UnsupportedEncodingException ex) {
                        ex.printStackTrace();
                    }
                }
            }
        });
6.加载好友列表

1.用户上线,刷新好友界面
2.创建群,刷新群列表界面
3.缓存所有私聊界面和群聊界面

public class FriendsList {
    private String userName;
    // 存储所有在线好友
    private Set<String> users;
    // 存储所有群名称以及群好友
    private Map<String,Set<String>> groupList = new ConcurrentHashMap<>();
    private Connect2Server connect2Server;
    // 缓存所有私聊界面
    private Map<String,PrivateChatGUI> privateChatGUIList = new ConcurrentHashMap<>();
    // 缓存所有群聊界面
    private Map<String,GroupChatGUI> groupChatGUIList = new ConcurrentHashMap<>();
    // 好友列表后台任务,不断监听服务器发来的信息
    // 好友上线信息、用户私聊、群聊
    private class DaemonTask implements Runnable {
        private Scanner in = new Scanner(connect2Server.getIn());
        @Override
        public void run() {
            while (true) {
                // 收到服务器发来的信息
                if (in.hasNextLine()) {
                    String strFromServer = in.nextLine();
                    // 此时服务器发来的是一个json字符串
                    if (strFromServer.startsWith("{")) {
                        MessageVO messageVO = (MessageVO) CommUtils.json2Object(strFromServer,
                                MessageVO.class);
                        if (messageVO.getType().equals("2")) {
                            // 服务器发来的私聊信息
                            String friendName = messageVO.getContent().split("-")[0];
                            String msg = messageVO.getContent().split("-")[1];
                            // 判断此私聊是否是第一次创建
                            if (privateChatGUIList.containsKey(friendName)) {
                                PrivateChatGUI privateChatGUI = privateChatGUIList.get(friendName);
                                privateChatGUI.getFrame().setVisible(true);
                                privateChatGUI.readFromServer(friendName+"说:"+msg);
                            }else {
                                PrivateChatGUI privateChatGUI = new PrivateChatGUI(friendName,
                                        userName,connect2Server);
                                privateChatGUIList.put(friendName,privateChatGUI);
                                privateChatGUI.readFromServer(friendName+"说:"+msg);
                            }
                        }
                        else if (messageVO.getType().equals("4")) {
                            // 收到服务器发来的群聊信息
                            // type:4
                            // content:sender-msg
                            // to:groupName-[1,2,3,...]
                            String groupName = messageVO.getTo().split("-")[0];
                            String senderName = messageVO.getContent().split("-")[0];
                            String groupMsg = messageVO.getContent().split("-")[1];
                            // 若此群名称在群聊列表
                            if (groupList.containsKey(groupName)) {
                                if (groupChatGUIList.containsKey(groupName)) {
                                    // 群聊界面弹出
                                    GroupChatGUI groupChatGUI = groupChatGUIList.get(groupName);
                                    groupChatGUI.getFrame().setVisible(true);
                                    groupChatGUI.readFromServer(senderName+"说:"+groupMsg);
                                }else {
                                    Set<String> names = groupList.get(groupName);
                                    GroupChatGUI groupChatGUI = new GroupChatGUI(groupName,
                                            names,userName,connect2Server);
                                    groupChatGUIList.put(groupName,groupChatGUI);
                                    groupChatGUI.readFromServer(senderName+"说:"+groupMsg);
                                }
                            }else {
                                // 若群成员第一次收到群聊信息
                                // 1.将群名称以及群成员保存到当前客户端群聊列表
                                Set<String> friends = (Set<String>) CommUtils.json2Object(messageVO.getTo().split("-")[1],
                                        Set.class);
                                groupList.put(groupName, friends);
                                loadGroupList();
                                // 2.弹出群聊界面
                                GroupChatGUI groupChatGUI = new GroupChatGUI(groupName,
                                        friends,userName,connect2Server);
                                groupChatGUIList.put(groupName,groupChatGUI);
                                groupChatGUI.readFromServer(senderName+"说:"+groupMsg);
                            }


                        }
                    }else {
                        // newLogin:userName
                        if (strFromServer.startsWith("newLogin:")) {
                            String newFriendName = strFromServer.split(":")[1];
                            users.add(newFriendName);
                            // 弹框提示用户上线
                            JOptionPane.showMessageDialog(frame,
                                    newFriendName+"上线了!",
                                    "上线提醒",JOptionPane.INFORMATION_MESSAGE);
                            // 刷新好友列表
                            loadUsers();
                        }
                    }
                }
            }
        }
    }
    // 私聊点击事件
    private class PrivateLabelAction implements MouseListener {
        private String labelName;

        public PrivateLabelAction(String labelName) {
            this.labelName = labelName;
        }

        // 鼠标点击执行事件
        @Override
        public void mouseClicked(MouseEvent e) {
            // 判断好友列表私聊界面缓存是否已经有指定标签
            if (privateChatGUIList.containsKey(labelName)) {
                PrivateChatGUI privateChatGUI = privateChatGUIList.get(labelName);
                privateChatGUI.getFrame().setVisible(true);
            }else {
                // 第一次点击,创建私聊界面
                PrivateChatGUI privateChatGUI = new PrivateChatGUI(
                        labelName,userName,connect2Server
                );
                privateChatGUIList.put(labelName,privateChatGUI);
            } 
    }

    // 群聊点击事件
    private class GroupLabelAction implements MouseListener {
        private String groupName;

        public GroupLabelAction(String groupName) {
            this.groupName = groupName;
        }

        @Override
        public void mouseClicked(MouseEvent e) {
            if (groupChatGUIList.containsKey(groupName)) {
                GroupChatGUI groupChatGUI = groupChatGUIList.get(groupName);
                groupChatGUI.getFrame().setVisible(true);
            }else {
                Set<String> names = groupList.get(groupName);
                GroupChatGUI groupChatGUI = new GroupChatGUI(
                        groupName,names,userName,connect2Server
                );
                groupChatGUIList.put(groupName,groupChatGUI);
            }
        }
    }

    public FriendsList(String userName, Set<String> users,
                       Connect2Server connect2Server) {
        this.userName = userName;
        this.users = users;
        this.connect2Server = connect2Server;
        frame = new JFrame(userName);
        frame.setContentPane(friendsPanel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400,300);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
        loadUsers();
        // 启动后台线程不断监听服务器发来的消息
        Thread daemonThread = new Thread(new DaemonTask());
        daemonThread.setDaemon(true);
        daemonThread.start();
        // 创建群组
        createGroupBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                new CreateGroupGUI(userName,users,connect2Server,
                        FriendsList.this);
            }
        });
    }
    // 加载所有在线的用户信息
    public void loadUsers() {
        JLabel[] userLabels = new JLabel [users.size()];
        JPanel friends = new JPanel();
        friends.setLayout(new BoxLayout(friends,BoxLayout.Y_AXIS));
        // set遍历
        Iterator<String> iterator = users.iterator();
        int i = 0;
        while (iterator.hasNext()) {
            String userName = iterator.next();
            userLabels[i] = new JLabel(userName);
            // 添加标签点击事件
            userLabels[i].addMouseListener(new PrivateLabelAction(userName));
            friends.add(userLabels[i]);
            i++;
        }
        frinedsList.setViewportView(friends);
        // 设置滚动条垂直滚动
        frinedsList.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        friends.revalidate();
        frinedsList.revalidate();
    }

    public void loadGroupList() {
        // 存储所有群名称标签Jpanel
        JPanel groupNamePanel = new JPanel();
        groupNamePanel.setLayout(new BoxLayout(groupNamePanel,
                BoxLayout.Y_AXIS));
        JLabel[] labels = new JLabel[groupList.size()];
        // Map遍历
        Set<Map.Entry<String,Set<String>>> entries = groupList.entrySet();
        Iterator<Map.Entry<String,Set<String>>> iterator =
                entries.iterator();
        int i = 0;
        while (iterator.hasNext()) {
            Map.Entry<String,Set<String>> entry = iterator.next();
            labels[i] = new JLabel(entry.getKey());
            labels[i].addMouseListener(new GroupLabelAction(entry.getKey()));
            groupNamePanel.add(labels[i]);
            i++;
        }
        groupListPanel.setViewportView(groupNamePanel);
        groupListPanel.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        groupListPanel.revalidate();
    }

    public void addGroup(String groupName,Set<String> friends) {
        groupList.put(groupName,friends);
    }
}

三、整体流程

服务器:

负责缓存所有在线好友、群组以及私聊群聊的聊天记录。根据客户端进行不同的操作而缓存不同的数据到服务器上。

客户端:

1.点击注册按钮,触发注册事件。在注册页面,获取用户输入的用户名、密码、简介,将信息封装到User类中,将user的信息保存到数据库中,即进行数据插入操作。注册成功,返回登录界面。

2.输入已注册的用户名、密码,点击登录,触发登录事件。获取用户输入的用户名和密码,在数据库中查找是否有此用户。

3.有,则成功登录。然后与服务器建立连接,将当前用户的用户名发送到服务器,服务器缓存此用户名。服务器给每一个在线好友发送新用户上线了,并刷新好友列表。

刷新好友列表:加载所有在线的用户信息,并给每一个用户标签添加标签点击事件。

4.客户端读取服务器返回的所有在线用户信息,加载主界面。即加载用户列表界面,将当前用户名、所有在线好友、与服务器建立连接传递到好友列表界面。

5.好友列表界面:加载所有在线的用户信息,并给每一个用户标签添加标签点击事件,触发私聊功能。如果是第一次点击,则创建私聊界面;如果之前已经有过聊天的记录,则根据缓存中的指定标签将私聊界面显示出来。

6.创建私聊:根据传递的参数(发送方,接收方,Socket连接),一旦用户按下回车,则将当前的发送方、接收方、消息封装到协议类中,发给服务器,并将自己发送的信息展示到当前私聊界面。最后将当前私聊界面缓存起来。

7.创建群。点击创建群,进入创建群界面。所有的在线好友以列表形式展现。将已选择的用户存储在集合中。将自己加入到群聊集合中,存储群名。服务器缓存群名和群成员信息,将群名称标签存储在缓存中,给每个群名称标签添加鼠标点击事件,最后刷新群列表界面。

8.群聊:群聊界面首次创建会存在缓存中,协议类将群聊的发言人和群名称封装起来,发给服务器。服务器经过解析,将消息发送给在群组中的每一个人。

8.启动后台线程不断监听服务器发来的消息:
(1)服务器发来的是json字符串,我们需要进行解析。
a. 服务器发来的是私聊信息。判断是不是第一次和此用户进行的私聊。第一次私聊,则创建私聊界面,缓存此私聊界面。不是第一次私聊,将缓存中的私聊界面弹出来。
b. 服务器发来的是群聊信息。若群聊名称在群聊列表,弹出群聊界面。如果自己刚刚创建了群聊,则将群聊信息缓存起来。若群成员第一次收到群聊信息,将群名称以及群成员保存到当前客户端群聊列表,然后弹出群聊界面,将群聊界面缓存。
(2)服务器发来字符串:newLogin:userName。则提醒新用户上线,刷新好友列表。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章