Spring Websocket - 确定用户是否已连接

问题描述 投票:0回答:1

我正在使用 Spring Boot 来构建 REST API。网站的一部分使用 WebSocket 进行客户端-服务器通信,以便为两个用户创建“房间”。需要通过 API 订购特定时间和持续时间的房间,例如2016年12月21日11:00 1小时。在网络应用程序中,我从现在开始设置超时,以指定使用“加入房间”按钮显示弹出窗口的时间。当用户单击此按钮时,就会创建房间。但我需要在第二个用户离线时禁用按钮。

如何在 Spring WebSockets 中确定用户是否在线?

我的解决方案是监听 SessionConnectEvent 和 SessionDisconnectEvent,并将用户状态(在数据库中)更新为在线或离线。仅当用户只有一个 Websocket 连接时它才有效。因为如果他有例如在同一页面上打开 2 个选项卡,然后建立 2 个连接(状态 = 在线)。当用户关闭一个选项卡时,会触发断开连接事件并将状态更改为离线,而他在线(仍然打开 1 个选项卡)。 会话断开事件。

此解决方案的修复方法是将 SessionConnectEvent 上的 session_id 和 user_id 保存在数据库对中,并在 SessionDisconnectEvent 上将其删除。

有没有更好的方法来判断用户是否在线?

java spring websocket client-server
1个回答
0
投票

让我告诉你我的方法, 我启用了 Spring Security,以便将主体(及其 .getName())与会话关联。然后使用简单的代理,添加您提到的侦听器(SessionConnectedEvent 和 SessionDisconnectEvent)和以下简单的类。

@Component
public class SessionManagement {
    private final Map<String, Boolean> sessions = new ConcurrentHashMap<>();

    public boolean isConnected(@NonNull String userId) {
        return this.sessions.getOrDefault(userId, false);
    }

    public void connect(@NonNull String userId) {
        this.sessions.put(userId, true);
    }

    public void disconnect(@NonNull String userId) {
        this.sessions.remove(userId);
    }
}

听众会是这样的:

@Component
public class WebSocketConnectedListener implements ApplicationListener<SessionConnectedEvent> {
    private final SessionManagement sessionManagement;

    @Autowired
    public WebSocketConnectedListener(SessionManagement sessionManagement) {
        this.sessionManagement = sessionManagement;
    }

    @Override
    public void onApplicationEvent(SessionConnectedEvent event) {
        this.sessionManagement.connect(Objects.requireNonNull(event.getUser()).getName());
    }
}

我希望这有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.