在现代 Web 应用程序中,用户使用实时数据的需求越来越普遍。实时数据通常包含用户数、在线活跃度、服务器负载等信息。平滑地显示实时用户数的方法是使用 Server-sent Events 服务,并在客户端使用 JavaScript 进行处理。本文将介绍如何使用 Server-sent Events 服务实现实时在线用户数统计。
Server-sent Events
Server-sent Events 是一项用于 Web 应用程序中的基于 HTTP 的服务器推送技术。它提供了一种不同于 WebSocket 的轻量级技术,用于以相对较低的延迟向浏览器发送推送数据。
使用 Server-sent Events,服务器可以发送包含文本数据的消息。这些消息由浏览器自动接收和处理,该技术通常用于实现实时通知、实时计数器等功能。
创建 SSE 服务
在服务器端实现 Server-sent Events 服务,需要遵循以下步骤:
- 创建 HTTP 请求,并设置正确的响应头。
----- ---- - ---------------- ----- ---- - ----- ----- ------ - ----------------------- ---- -- - ----------------------------- --------------------- ------------------------------ ------------ --------------------------- -------------- -------------------------------------------- ----- ------------------- ---
- 向客户端发送 SSE 消息。
----- ---- - ------ ---------------- ----------------
在 SSE 消息中,必须包含前缀 data:
和两个连续的换行符 \n\n
。这个两个字符用于标识消息的结束。
完整的 Server-sent Events 服务实现如下:
----- ---- - ---------------- ----- ---- - ----- ----- ------ - ----------------------- ---- -- - ----------------------------- --------------------- ------------------------------ ------------ --------------------------- -------------- -------------------------------------------- ----- ------------------- --- ----- - -- -------------- -- - -------- ----- ------- - --------- ----- -------- ----- ---- - ------ ---------------- ---------------- -- ------ --- ------------------- -- -- - ------------------- -- --------- -- --------------------------- ---
这个例子使用 setInterval 函数每秒向客户端发送一条 SSE 消息并增加在线用户数。
客户端订阅 SSE 服务
在客户端,可以使用 EventSource
对象订阅 SSE 服务。
----- ------ - --- ------------------------------------- ---------------- - ----- -- - ----- ------- - ----------- --------------------- --
在 open
事件和 error
事件中,可以监听 SSE 服务的连接状态和错误信息。
------------- - -- -- - ----------------------- -------------- -- -------------- - ----- -- - ------------------ ----------- ------- --
使用 EventSource
对象订阅 SSE 服务是非常简单的。在订阅成功后,所有发送到 SSE 服务的消息都会被自动接收。
实现实时在线用户数统计
现在,我们可以将 SSE 服务应用于实时在线用户数统计。
从技术上讲,只需维护每个用户的连接并跟踪它们的状态。当用户成功连接到服务器时,增加在线用户数量;当用户断开连接时,减少在线用户数量。服务器将计数器的当前值发送到所有连接的客户端。
代码示例:
服务器端
----- ---- - ---------------- ----- ---- - ----- ----- ------ - ----------------------- ---- -- - ----------------------------- --------------------- ------------------------------ ------------ --------------------------- -------------- -------------------------------------------- ----- ------------------- --- ----- - -- ----- ------- - --- ------ -------- ----------- - ----- ------- - --------- ----- -------- ----- ---- - ------ ---------------- --- ------ ----- --- -- -------- - ---------------- - - -------------- -- - ------------ -- ------ ------------------ -- -- - --- ------ -------- --- -- -------- - ------------- - --- ------------------ ----- -- - --------------------- --- --------------- -- -- - ----- ------ - ----------------- -- -------- - -------- -------------------- - --- -------- ----- -- - ----------- ---------------- ---- ----------------- ------------ ------------ ---------------- ------------ --- ------------------- -- -- - ------------------- -- --------- -- --------------------------- ---
这个代码维护了一个计数器和一个客户端 Map 映射,该映射持有每个连接的客户端对象和一个连接 ID。服务器更新客户端 Map 映射并统计在线用户数量。当新客户端连接时,服务器将其 ID 发送到客户端。
客户端
----- ------ - --- ------------------------------------- ----- ------------------ - ------------------------------------------------ ----- ----- - --- ------ ---------------- - ----- -- - ----- ------- - ----------- -- ------ ----- ----------------------- - ---------------------------- - -------- - ---- - ----- ------- --- ----- - ---------------------------- -- --------------------------- -- - ---- ------ ------- - ---- ---------- ------------- ------ ------ ---- ------------- ----------------- ------ -------- --------------------- ------ ----------- ------ - - --
这个代码使用监听 onmessage
事件对服务器发送的消息进行处理。如果接收到的消息是在线用户数量,它将更新用户计数器的值。如果消息是连接事件或断开事件,它将更新用户 Map 映射并更新用户数量。
结论
使用 Server-sent Events 可以轻松地实现实时在线用户数统计。构建 SSE 服务的过程非常简单且高效,不需要特殊的软件或库。借助 SSE,Web 应用程序可以更好地处理用户实时数据,从而为用户提供更好的使用体验。
完整的示例代码可以在 GitHub 项目 上进行查看。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/6715c6d5ad1e889fe218dd5e