实时在线状态

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

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 部分修改:

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 类需要扩展的字段:

public class User {
    private Long id;
    private String username;
    private Date loginTime; // 登录时间

    // Getters/Setters...
}

主要功能说明

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

使用示例

// 用户登录成功
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秒检测一次连接活性)来维护在线状态的准确性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值