实时在线状态

以下是一个完整的 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秒检测一次连接活性)来维护在线状态的准确性。

相关推荐
冷雨夜中漫步7 小时前
Python快速入门(6)——for/if/while语句
开发语言·经验分享·笔记·python
郝学胜-神的一滴7 小时前
深入解析Python字典的继承关系:从abc模块看设计之美
网络·数据结构·python·程序人生
百锦再7 小时前
Reactive编程入门:Project Reactor 深度指南
前端·javascript·python·react.js·django·前端框架·reactjs
JH30738 小时前
SpringBoot 优雅处理金额格式化:拦截器+自定义注解方案
java·spring boot·spring
颜酱9 小时前
图结构完全解析:从基础概念到遍历实现
javascript·后端·算法
m0_736919109 小时前
C++代码风格检查工具
开发语言·c++·算法
yugi9878389 小时前
基于MATLAB强化学习的单智能体与多智能体路径规划算法
算法·matlab
喵手9 小时前
Python爬虫实战:旅游数据采集实战 - 携程&去哪儿酒店机票价格监控完整方案(附CSV导出 + SQLite持久化存储)!
爬虫·python·爬虫实战·零基础python爬虫教学·采集结果csv导出·旅游数据采集·携程/去哪儿酒店机票价格监控
Coder_Boy_9 小时前
技术让开发更轻松的底层矛盾
java·大数据·数据库·人工智能·深度学习
2501_944934739 小时前
高职大数据技术专业,CDA和Python认证优先考哪个?
大数据·开发语言·python