实时在线状态

以下是一个完整的 OnlineUsers 类实现,包含线程安全的在线用户管理功能:

java 复制代码
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * 在线用户管理器(线程安全)
 * 功能:
 * 1. 用户登录/下线状态管理
 * 2. 重复登录强制下线
 * 3. 在线用户查询
 * 4. 实时消息推送支持
 */
public class OnlineUsers {
    // 存储 <用户ID, 客户端连接处理器>
    private static final ConcurrentHashMap<Long, ClientHandler> onlineUsers = new ConcurrentHashMap<>();

    // 防止实例化
    private OnlineUsers() {}

    /**
     * 添加在线用户(如果已登录会强制下线旧连接)
     * @param userId 用户ID
     * @param handler 客户端处理器
     */
    public static void addUser(Long userId, ClientHandler handler) {
        synchronized (onlineUsers) {
            // 处理重复登录
            ClientHandler existingHandler = onlineUsers.get(userId);
            if (existingHandler != null) {
                forceDisconnect(existingHandler);
            }
            onlineUsers.put(userId, handler);
        }
    }

    /**
     * 移除在线用户
     * @param userId 用户ID
     */
    public static void removeUser(Long userId) {
        onlineUsers.remove(userId);
    }

    /**
     * 检查用户是否在线
     * @param userId 用户ID
     * @return 是否在线
     */
    public static boolean isUserOnline(Long userId) {
        return onlineUsers.containsKey(userId);
    }

    /**
     * 获取在线用户ID列表
     * @return 不可修改的ID集合
     */
    public static Set<Long> getOnlineUserIds() {
        return Collections.unmodifiableSet(onlineUsers.keySet());
    }

    /**
     * 获取在线用户详细信息列表
     * @return 用户信息列表(按登录时间排序)
     */
    public static List<User> getOnlineUsers() {
        return onlineUsers.values().stream()
                .filter(handler -> handler.getUser() != null)
                .map(ClientHandler::getUser)
                .sorted(Comparator.comparing(User::getLoginTime))
                .collect(Collectors.toList());
    }

    /**
     * 获取用户连接处理器
     * @param userId 用户ID
     * @return 处理器实例(可能为null)
     */
    public static ClientHandler getHandler(Long userId) {
        return onlineUsers.get(userId);
    }

    /**
     * 获取当前在线人数
     * @return 在线用户数量
     */
    public static int getOnlineCount() {
        return onlineUsers.size();
    }

    /**
     * 强制下线用户
     * @param userId 用户ID
     */
    public static void forceDisconnect(Long userId) {
        ClientHandler handler = onlineUsers.get(userId);
        if (handler != null) {
            forceDisconnect(handler);
            removeUser(userId);
        }
    }

    // 内部断开连接方法
    private static void forceDisconnect(ClientHandler handler) {
        try {
            handler.forceDisconnect();
            System.out.println("强制断开用户连接: " + handler.getUser().getId());
        } catch (Exception e) {
            System.err.println("强制断开连接失败: " + e.getMessage());
        }
    }

    /**
     * 清除所有在线用户(测试用)
     */
    static void clearAll() {
        onlineUsers.values().forEach(OnlineUsers::forceDisconnect);
        onlineUsers.clear();
    }
}

需要配合的 ClientHandler 部分修改:

java 复制代码
public class ClientHandler implements Runnable {
    private User loggedInUser;

    // 获取关联的用户信息
    public User getUser() {
        return loggedInUser;
    }

    // 强制断开连接
    public void forceDisconnect() {
        try {
            if (!clientsocket.isClosed()) {
                clientsocket.close();
            }
        } catch (IOException e) {
            System.err.println("强制断开连接异常: " + e.getMessage());
        }
    }

    // 在登录成功后调用
    private void handleSuccessfulLogin(User user) {
        this.loggedInUser = user;
        OnlineUsers.addUser(user.getId(), this);
    }
}

User 类需要扩展的字段:

java 复制代码
public class User {
    private Long id;
    private String username;
    private Date loginTime; // 登录时间

    // Getters/Setters...
}

主要功能说明

方法 功能说明
**addUser()** 添加在线用户,自动处理重复登录
**removeUser()** 移除指定在线用户
**isUserOnline()** 检查指定用户是否在线
**getOnlineUserIds()** 获取所有在线用户ID(不可修改集合)
**getOnlineUsers()** 获取详细在线用户列表(按登录时间排序)
**getHandler()** 获取用户连接处理器(用于消息推送)
**getOnlineCount()** 获取当前在线人数
**forceDisconnect()** 强制断开指定用户连接
**clearAll()** 清空所有在线用户(测试用)

使用示例

java 复制代码
// 用户登录成功
User user = new User(123L, "张三");
ClientHandler handler = new ClientHandler(socket);
OnlineUsers.addUser(user.getId(), handler);

// 检查用户状态
boolean isOnline = OnlineUsers.isUserOnline(123L);

// 发送实时消息
ClientHandler targetHandler = OnlineUsers.getHandler(456L);
if (targetHandler != null) {
    targetHandler.sendMessage(new ChatMessage(...));
}

// 获取在线用户统计
System.out.println("当前在线人数: " + OnlineUsers.getOnlineCount());

设计特点

  1. 线程安全:使用 **ConcurrentHashMap** 和同步块保证线程安全
  2. 自动清理:连接断开时自动移除用户(需在 **ClientHandler** 的 finally 块调用 **removeUser()**
  3. 强制下线:处理重复登录时自动断开旧连接
  4. 可扩展性:支持按需获取用户ID列表或详细用户信息
  5. 状态跟踪:记录用户登录时间用于排序和分析

建议配合心跳检测机制(如每30秒检测一次连接活性)来维护在线状态的准确性。

相关推荐
山海上的风6 分钟前
23种设计模式--简单工厂模式理解版
java·开发语言·简单工厂模式
像污秽一样13 分钟前
软件开发新技术复习
java·spring boot·后端·rabbitmq·cloud
浮游本尊18 分钟前
Java学习第7天 - 网络编程与数据库操作
java
武昌库里写JAVA19 分钟前
关于springcloud的坑
java·开发语言·spring boot·学习·课程设计
西猫雷婶28 分钟前
python学智能算法(十四)|机器学习朴素贝叶斯方法进阶-CountVectorizer文本处理简单测试
人工智能·python·机器学习
?abc!33 分钟前
(哈希)128. 最长连续序列
算法·leetcode·哈希算法
yihuiComeOn40 分钟前
【大数据高并发核心场景实战】 - 数据持久化之冷热分离
java·后端
Zephyrtoria44 分钟前
动态规划:01 背包(闫氏DP分析法)
java·算法·动态规划
范纹杉想快点毕业1 小时前
解析Qt文件保存功能实现
java·开发语言·c++·算法·命令模式