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

使用Angular与WebSocket时如何在用户未登出关闭浏览器/标签时标记离线

Angular + WebSocket 用户离线状态判定方案

核心实现逻辑

1. 前端侧处理逻辑

  • 监听beforeunload事件:用户关闭浏览器、标签页、刷新页面时都会触发该事件,在回调中主动给WebSocket服务端发送用户离线通知,请求更新数据库状态。Angular中可以在全局WebSocket服务的初始化逻辑里绑定该事件,组件销毁时及时解绑避免内存泄漏。
  • 监听浏览器原生online/offline事件:网络断开时触发offline事件,可直接标记本地用户为离线状态;网络恢复触发online事件时,可自动执行WebSocket重连、状态同步逻辑。
  • 新增心跳检测机制:前端固定间隔(建议30s)给服务端发送ping消息,连续3次未收到服务端返回的pong响应时,判定连接失效,主动执行本地离线清理逻辑。

重点提示:不要完全依赖前端事件做离线判定,极端场景下(浏览器崩溃、设备强制断电)前端事件不会触发,必须配合后端逻辑保证状态准确性

2. 后端侧处理逻辑

  • 监听WebSocketonClose事件:无论前端是主动发送离线通知,还是异常断连,服务端的连接关闭事件都会触发,直接在该回调中更新对应用户的数据库在线状态即可,无需依赖前端的主动上报。
  • 心跳超时判定:服务端如果超过设定阈值(建议90s,即3次前端心跳间隔)未收到某个客户端的任何消息,直接主动断开该连接,同时更新用户状态为离线,避免僵尸连接导致的状态异常。
  • 多连接冲突处理:同一个用户ID发起新的WebSocket连接时,先主动断开该用户对应的旧连接,再更新状态为在线,避免多端登录导致的状态混乱。

3. 兜底优化逻辑

  • 服务端定期校验:可设置定时任务(比如每5分钟执行一次),比对当前活跃WebSocket连接列表和数据库中的在线用户列表,将不存在于活跃连接中的用户状态统一更新为离线,覆盖极端异常场景。
  • 业务接口同步校验:用户在线时的所有业务请求都会携带身份凭证,如果收到标记为离线用户的合法业务请求,可实时将用户状态更新为在线,同时引导前端重建WebSocket连接。

代码示例(Angular WebSocket服务)

import { Injectable, OnDestroy } from '@angular/core';

@Injectable({ providedIn: 'root' })
export class CustomWebsocketService implements OnDestroy {
  private ws: WebSocket;
  private heartbeatTimer: number;
  private readonly HEARTBEAT_INTERVAL = 30000; // 30s心跳间隔
  private currentUserId: string;

  constructor() {
    this.currentUserId = localStorage.getItem('currentUserId') || '';
    this.initWebSocket();
    // 绑定页面关闭事件
    window.addEventListener('beforeunload', this.handlePageClose.bind(this));
  }

  private initWebSocket() {
    this.ws = new WebSocket('ws://你的服务端地址/ws');
    this.ws.onopen = () => {
      // 连接建立后启动心跳
      this.startHeartbeat();
    };
    this.ws.onmessage = (event) => {
      const msg = JSON.parse(event.data);
      if (msg.type === 'PONG') {
        // 收到心跳响应,重置计数逻辑
      }
    };
  }

  private startHeartbeat() {
    this.heartbeatTimer = window.setInterval(() => {
      if (this.ws.readyState === WebSocket.OPEN) {
        this.ws.send(JSON.stringify({ type: 'PING' }));
      }
    }, this.HEARTBEAT_INTERVAL);
  }

  private handlePageClose() {
    if (this.ws.readyState === WebSocket.OPEN) {
      // 页面关闭时主动上报离线
      this.ws.send(JSON.stringify({
        type: 'USER_OFFLINE',
        userId: this.currentUserId
      }));
    }
  }

  ngOnDestroy() {
    window.removeEventListener('beforeunload', this.handlePageClose);
    clearInterval(this.heartbeatTimer);
    this.ws.close();
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 23:24:05