实时在线状态

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

相关推荐
钢铁男儿5 分钟前
Python变量作用域陷阱:为什么函数内赋值会引发_局部变量未定义
开发语言·python
尤物程序猿6 分钟前
Java怎么实现一个敏感词过滤?有哪些方法?怎么优化?
java·开发语言·c#
magic 24512 分钟前
Spring 基于 XML 的自动装配:原理与实战详解
xml·java·spring
佩奇的技术笔记31 分钟前
Java学习手册:Spring Boot 自动配置与快速开发
java·spring boot
love530love38 分钟前
将 virtualenv 环境迁移到 Conda 环境
运维·windows·python·conda·virtualenv
ayiya_Oese38 分钟前
[预备知识]5. 优化理论(一)
python·神经网络·目标检测·机器学习·计算机视觉
heart000_141 分钟前
如何在IDEA中去除警告波浪线
java·ide·intellij-idea
vibag43 分钟前
启发式算法-遗传算法
java·算法·启发式算法·智能算法
magic 2451 小时前
SpringMVC——第五章:视图View
java·后端·springmvc
爱编程的鱼1 小时前
C# 运算符重载深度解析:从基础到高阶实践
前端·算法·c#