实时在线状态

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

相关推荐
智驱力人工智能32 分钟前
基于视觉分析的人脸联动使用手机检测系统 智能安全管理新突破 人脸与手机行为联动检测 多模态融合人脸与手机行为分析模型
算法·安全·目标检测·计算机视觉·智能手机·视觉检测·边缘计算
悟能不能悟1 小时前
java的java.sql.Date和java.util.Date的区别,应该怎么使用
java·开发语言
Mr_Xuhhh1 小时前
GUI自动化测试--自动化测试的意义和应用场景
python·集成测试
2301_764441331 小时前
水星热演化核幔耦合数值模拟
python·算法·数学建模
循环过三天1 小时前
3.4、Python-集合
开发语言·笔记·python·学习·算法
Q_Q5110082851 小时前
python+django/flask的眼科患者随访管理系统 AI智能模型
spring boot·python·django·flask·node.js·php
高山上有一只小老虎2 小时前
java 正则表达式大全
java·正则表达式
_院长大人_3 小时前
设计模式-工厂模式
java·开发语言·设计模式
凌波粒3 小时前
MyBatis完整教程IDEA版(2)--ResultMap/注解/一对多/多对一/lombok/log4j
java·intellij-idea·mybatis
SunnyDays10113 小时前
如何使用Python高效转换Excel到HTML
python·excel转html