本文提供使用 Java Spring Boot 框架实现 WebSocket 单聊和群聊的基本思路和代码示例。

一、单聊实现思路

  1. 客户端连接 WebSocket,并发送用户信息(用户名、用户 ID 等)到后台。
  2. 后台将用户信息保存到一个 Map 中,以用户 ID 作为键,WebSocketSession 对象作为值。
  3. 当有用户发送消息时,后台根据接收者的用户 ID 从 Map 中获取 WebSocketSession 对象,并通过该对象发送消息。
  4. 后台可以保存每个用户的未读消息数量,在用户连接 WebSocket 时将未读消息数量返回给客户端,在客户端打开聊天窗口时将未读消息数量清零。

二、群聊实现思路

  1. 客户端连接 WebSocket,并发送用户信息(用户名、用户 ID、加入的群聊 ID 等)到后台。
  2. 后台将用户信息保存到两个 Map 中:一个以用户 ID 作为键,WebSocketSession 对象作为值;另一个以群聊 ID 作为键,保存所有加入该群聊的用户 ID。
  3. 当有用户发送消息时,后台根据群聊 ID 从 Map 中获取所有加入该群聊的用户 ID,然后根据每个用户 ID 从第一个 Map 中获取 WebSocketSession 对象,并通过该对象发送消息。
  4. 后台可以保存每个用户在每个群聊中的未读消息数量,在用户连接 WebSocket 时将未读消息数量返回给客户端,在客户端打开聊天窗口时将未读消息数量清零。

三、离线信息处理

  1. 当用户连接 WebSocket 时,后台可以检查该用户是否有未读消息。如果有,将未读消息发送给客户端。
  2. 当用户断开 WebSocket 连接时,后台可以将该用户的未读消息保存到数据库或缓存中,等用户下次连接 WebSocket 时再将未读消息发送给客户端。

四、未读信息统计

  1. 对于单聊,后台可以保存每个用户的未读消息数量,并在用户连接 WebSocket 时将未读消息数量返回给客户端,在客户端打开聊天窗口时将未读消息数量清零。
  2. 对于群聊,后台可以保存每个用户在每个群聊中的未读消息数量,并在用户连接 WebSocket 时将未读消息数量返回给客户端,在客户端打开聊天窗口时将未读消息数量清零。

代码示例

1. 单聊

@Controller
public class WebSocketController {
    // 保存用户 ID 和 WebSocketSession 对象的 Map
    private static Map<String, WebSocketSession> users = new ConcurrentHashMap<>();
    // 保存每个用户的未读消息数量的 Map
    private static Map<String, Integer> unreadMsgCounts = new ConcurrentHashMap<>();

    @OnOpen
    public void onOpen(WebSocketSession session) throws IOException {
        // 获取用户信息
        String userId = getUserIdFromSession(session);
        // 将用户信息保存到 Map 中
        users.put(userId, session);
        // 返回该用户的未读消息数量
        int unreadMsgCount = unreadMsgCounts.getOrDefault(userId, 0);
        session.sendMessage(new TextMessage(String.valueOf(unreadMsgCount)));
        // 将未读消息数量清零
        unreadMsgCounts.put(userId, 0);
    }

    @OnMessage
    public void onMessage(WebSocketSession session, String message) throws IOException {
        // 获取发送者和接收者的用户 ID
        String[] parts = message.split(',');
        String senderId = getUserIdFromSession(session);
        String receiverId = parts[0];
        // 获取接收者的 WebSocketSession 对象
        WebSocketSession receiverSession = users.get(receiverId);
        if (receiverSession != null) {
            // 如果接收者在线,直接发送消息
            TextMessage msg = new TextMessage(senderId + ',' + parts[1]);
            receiverSession.sendMessage(msg);
        } else {
            // 如果接收者离线,将消息保存到数据库或缓存中
            saveOfflineMsg(senderId, receiverId, parts[1]);
            // 增加接收者的未读消息数量
            int count = unreadMsgCounts.getOrDefault(receiverId, 0);
            unreadMsgCounts.put(receiverId, count + 1);
        }
    }

    @OnClose
    public void onClose(WebSocketSession session) {
        // 移除用户信息
        String userId = getUserIdFromSession(session);
        users.remove(userId);
    }

    private String getUserIdFromSession(WebSocketSession session) {
        // 从 WebSocketSession 对象中获取用户 ID
        // ...
    }

    private void saveOfflineMsg(String senderId, String receiverId, String content) {
        // 将离线消息保存到数据库或缓存中
        // ...
    }
}

2. 群聊

@Controller
public class WebSocketController {
    // 保存用户 ID 和 WebSocketSession 对象的 Map
    private static Map<String, WebSocketSession> users = new ConcurrentHashMap<>();
    // 保存群聊 ID 和所有加入该群聊的用户 ID 的 Map
    private static Map<String, Set<String>> groups = new ConcurrentHashMap<>();
    // 保存每个用户在每个群聊中的未读消息数量的 Map
    private static Map<String, Map<String, Integer>> unreadMsgCounts = new ConcurrentHashMap<>();

    @OnOpen
    public void onOpen(WebSocketSession session) throws IOException {
        // 获取用户信息
        String userId = getUserIdFromSession(session);
        String groupId = getGroupIdFromSession(session);
        // 将用户信息保存到 Map 中
        users.put(userId, session);
        Set<String> groupUsers = groups.getOrDefault(groupId, new HashSet<>());
        groupUsers.add(userId);
        groups.put(groupId, groupUsers);
        // 返回该用户在该群聊中的未读消息数量
        int unreadMsgCount = unreadMsgCounts.getOrDefault(userId, new HashMap<>()).getOrDefault(groupId, 0);
        session.sendMessage(new TextMessage(String.valueOf(unreadMsgCount)));
        // 将未读消息数量清零
        Map<String, Integer> groupUnreadMsgCounts = unreadMsgCounts.getOrDefault(userId, new HashMap<>());
        groupUnreadMsgCounts.put(groupId, 0);
        unreadMsgCounts.put(userId, groupUnreadMsgCounts);
    }

    @OnMessage
    public void onMessage(WebSocketSession session, String message) throws IOException {
        // 获取发送者和群聊 ID
        String[] parts = message.split(',');
        String senderId = getUserIdFromSession(session);
        String groupId = parts[0];
        Set<String> groupUsers = groups.getOrDefault(groupId, new HashSet<>());
        // 遍历群聊中所有用户,将消息发送给在线用户,将离线消息保存到数据库或缓存中
        for (String userId : groupUsers) {
            WebSocketSession receiverSession = users.get(userId);
            if (receiverSession != null) {
                // 如果接收者在线,直接发送消息
                TextMessage msg = new TextMessage(senderId + ',' + parts[1]);
                receiverSession.sendMessage(msg);
            } else {
                // 如果接收者离线,将消息保存到数据库或缓存中
                saveOfflineMsg(senderId, userId, groupId, parts[1]);
                // 增加接收者在该群聊中的未读消息数量
                Map<String, Integer> groupUnreadMsgCounts = unreadMsgCounts.getOrDefault(userId, new HashMap<>());
                int count = groupUnreadMsgCounts.getOrDefault(groupId, 0);
                groupUnreadMsgCounts.put(groupId, count + 1);
                unreadMsgCounts.put(userId, groupUnreadMsgCounts);
            }
        }
    }

    @OnClose
    public void onClose(WebSocketSession session) {
        // 移除用户信息
        String userId = getUserIdFromSession(session);
        String groupId = getGroupIdFromSession(session);
        users.remove(userId);
        Set<String> groupUsers = groups.getOrDefault(groupId, new HashSet<>());
        groupUsers.remove(userId);
        groups.put(groupId, groupUsers);
    }

    private String getUserIdFromSession(WebSocketSession session) {
        // 从 WebSocketSession 对象中获取用户 ID
        // ...
    }

    private String getGroupIdFromSession(WebSocketSession session) {
        // 从 WebSocketSession 对象中获取群聊 ID
        // ...
    }

    private void saveOfflineMsg(String senderId, String receiverId, String groupId, String content) {
        // 将离线消息保存到数据库或缓存中
        // ...
    }
}

注意: 以上代码示例仅供参考,实际应用中需要根据具体需求进行修改和完善。

SpringBoot WebSocket 实现单聊、群聊及离线信息处理

原文地址: http://www.cveoy.top/t/topic/nJac 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录