You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot RSocket如何检测连接断开?断开时如何获取用户信息

RSocket检测用户断开并获取用户信息解决方案

RSocket完全可以检测到用户断开连接,你当前的代码已经通过reqer.rsocket().onClose()监听了连接关闭事件,但缺少用户信息与RSocket连接的绑定逻辑,只需调整存储结构并补充关联逻辑即可实现需求。

1. 调整存储结构,绑定用户信息与连接实例

你当前仅用List<RSocketRequester>存储连接实例,无法关联用户身份信息。建议自定义实体类或使用Map,将用户信息与对应的RSocket连接绑定:

方式一:自定义连接实体类

// 自定义实体,封装用户信息和RSocket连接
@Data
public class ClientConnection {
    private String userId; // 用户唯一标识
    private String username; // 用户名
    private RSocketRequester requester; // 对应的RSocket连接实例
}

// 替换原有列表,使用线程安全集合避免并发问题
private final List<ClientConnection> CLIENT_CONNECTIONS = new CopyOnWriteArrayList<>();

方式二:使用Map直接映射

// 以用户ID为Key,RSocket连接为Value,线程安全的ConcurrentHashMap
private final ConcurrentHashMap<String, RSocketRequester> CLIENT_MAP = new ConcurrentHashMap<>();

2. 连接时绑定用户信息,并在断开时获取

用户连接时,通常会通过元数据(Metadata)或Payload携带身份信息,你可以在@ConnectMapping方法中解析这些信息,绑定到连接实例上,再在onClose()的回调中获取用户信息:

@ConnectMapping
public void onConnect(RSocketRequester requester, @Metadata String userId, @Payload String username) {
    log.info("RSocket连接建立:requester hashCode = {}", requester.hashCode());

    // 创建连接实体并绑定信息
    ClientConnection connection = new ClientConnection();
    connection.setUserId(userId);
    connection.setUsername(username);
    connection.setRequester(requester);

    requester.rsocket()
        .onClose()
        .doFirst(() -> CLIENT_CONNECTIONS.add(connection))
        .doOnError(error -> log.info("RSocket连接异常:{}", error.getMessage()))
        .doFinally(signalType -> {
            // 断开时直接获取用户信息
            log.info("用户 {}(ID:{})已断开连接", connection.getUsername(), connection.getUserId());
            CLIENT_CONNECTIONS.remove(connection);
        })
        .subscribe();

    log.info("当前在线客户端数量:{}", CLIENT_CONNECTIONS.size());
}

说明:如果使用自定义元数据格式(如CompositeMetadata),需要配合对应的解码器解析指定MIME类型的元数据内容。

3. 覆盖所有断开场景

onClose()会触发所有连接终止场景:

  • 用户主动关闭连接
  • 网络波动导致连接中断
  • 服务器主动断开连接
  • 连接超时

在doFinally回调中,无论连接是正常关闭还是异常终止,都能安全获取用户信息并完成清理操作(如移除连接记录、更新在线状态等)。

4. 线程安全注意事项

原代码使用的ArrayList是非线程安全集合,多用户并发连接/断开时可能出现ConcurrentModificationException,建议替换为:

  • CopyOnWriteArrayList(适合读多写少的场景)
  • ConcurrentHashMap(适合按用户ID快速查找的场景)

内容的提问来源于stack exchange,提问作者superpil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 00:05:35