WebSocket 是一种用于在浏览器和服务器之间建立实时、双向通信的协议。在 Deno 中,我们可以使用标准库提供的 WebSocket 模块来创建 WebSocket 服务器和客户端。
本文将介绍如何在 Deno 中使用 WebSocket 实现一个实时聊天室,包括基本的聊天功能和用户在线状态管理。同时,我们将探讨一些技巧和最佳实践,以帮助开发人员更好地使用 WebSocket。
基本聊天功能
首先,我们需要创建一个 WebSocket 服务器。在 Deno 中,可以使用 serve()
方法创建一个 HTTP 服务器,并将其传递给 WebSocket()
构造函数来创建 WebSocket 服务器。
-- -------------------- ---- ------- ------ - ----- - ---- --------------------------------------- ------ - ---------------- --------- - ---- ---------------------------------- ----- ---- - ----- ----- ------ - ------- ---- --- ---------------------- ------ ------- -- --------------------------- --- ----- ------ --- -- ------- - -- -------- --- ------ - ----- - ----- -- ---------- -- ---------- ------- - - ---- ----------------- ----- ---------- ---------- -------- ------------------------- - - ----- -------- ------------------- ---------- - ---------------------- ------------ --- ----- ------ ----- -- --- - ---------------------- -------- ------- ------ ------------ - ---- ------- -------------------------- ------- ------ ---- -------- ------------------------ ------- ------ - - - -------- -------------------------- ---------- ------ ---- - ---------------------- ---------- ------- ------------------------ ----- ---------- ----- ----------- ---- - -------- ------------------------ ---------- ------ ---- - ---------------------- --------- -------------- -
在上面的代码中,我们将 /ws
作为 WebSocket 连接的端点。当客户端连接到该端点时,acceptWebSocket()
将返回一个 WebSocket 实例,并创建一个事件循环来处理来自 WebSocket 的消息。
当我们收到来自客户端的文本消息时,我们需要将消息广播到所有连接的 WebSocket 客户端。为此,我们可以在 handleWebSocketMessage()
方法中使用 ws.send()
方法将消息发送回所有客户端。
接下来,我们需要创建客户端 HTML 页面。该页面将包含一个文本框和一个按钮,以便用户可以向聊天室发送消息。
-- -------------------- ---- ------- --------- ----- ------ ------ ----- --------------- -- ---------------- ---- ------------ ------- ------ ------ ------ ----------- ------------ -- ------- ------------- ------------------------------------- ------- --- ------------------- -------- ----- ------ - --- ------------------------------------ ----- ----------------- - ------------------------------------ ---------------------------------- -------- ------- - ----- ------- - ----------------------- ------ -------------- - ---- ---------- ---------------------------- ------ - --- -------- ------------- - ----- ------------ - ----------------------------------- ----- ------- - -------------------------- -- --------- - --------------------- ------------------ - --- - - -------- ---------------------- - ----- -- - ----------------------------- -------------- - -------- ---------------------------------- - --------- ------- -------
在这个 HTML 页面中,我们通过 new WebSocket("ws://localhost:3000/ws")
创建了一个 WebSocket 客户端,并在收到服务器发送的消息时更新 messages
元素。
现在,我们已经实现了一个基本的实时聊天室。但是,这个聊天室存在一些问题,因为我们并没有考虑多个用户同时连接的情况。接下来,我们将讨论如何管理用户在线状态。
用户在线状态管理
为了管理用户在线状态,我们需要维护一个列表,包含当前所有连接的 WebSocket 客户端的信息。我们可以使用一个对象来存储这些信息,其键为客户端的 ID,值为客户端的 WebSocket 实例和其他信息。
interface ClientInfo { id: string; ws: WebSocket; name?: string; } const clients = new Map<string, ClientInfo>();
接下来,我们需要处理新连接的 WebSocket 客户端,并将其添加到客户端列表中。为此,我们可以添加一个 handleWebSocketOpen()
方法,并将其注册为 acceptWebSocket()
的回调函数。
-- -------------------- ---- ------- ----- -------- ------------------- ---------- - ----- -- - ------------------------------------- ----- ------ - - --- --- -- --------------- -------- ---------------------- ------ ----- ------------ --- ----- ------ ----- -- --- - ---------------------- ------ ----- -------- ------- ------ ------------ - ---- ------- ------------------------------ ------- ------ ---- -------- ---------------------------- ------- ------ - - -
在上面的代码中,我们生成一个新的随机 ID,将 WebSocket 客户端信息添加到 clients
对象中,并在控制台输出客户端连接消息。
当客户端断开连接时,我们需要从客户端列表中删除它。为此,我们可以添加一个 handleWebSocketClose()
方法,并将其注册为 WebSocket 的 close
事件的回调函数。
-- -------------------- ---- ------- -------- ---------------------------- ----------- ------ ---- - -------------------------- ---------------------- ------ ------------ ------- ------------------ ----------- ----- -------- ----- - --- ---------- ----- ------------ -- --- -
在上面的代码中,我们从客户端列表中删除客户端信息,并使用 broadcast()
方法将离开消息发送给所有客户端。
现在,我们需要处理来自客户端的聊天消息,并使用 broadcast()
方法将其广播到所有连接的 WebSocket 客户端。在发送消息之前,我们需要检查发送者是否已设置其昵称。如果没有,我们将在发送之前要求他们输入一个昵称。
-- -------------------- ---- ------- -------- ------------------------------ ----------- ------ ---- - ---------------------- ------ ------------ ---------- ------------ ----- ---- - ----------------------- ------ ----------- - ---- ------- ------------------------- ------ ------ ---- ---------- ---------------------------- ------ ------ - - -------- ------------------------- ----------- ----- ---- - ----------- - ---------- ----------- ----- ------- ----- - --- ---------- ----- ------------ -- --- - -------- ---------------------------- ----------- ----- ---- - -- -------------- - ------------------------------- ----- -------- ----- ------- --- ---- -------- ------- ---- ------- - ----------- ----- ---------- ----- - --- ---------- ----- ------------ -------- ------------- -- --- -
在上面的代码中,我们添加了 join
类型的消息,用于在客户端连接后设置其昵称。如果客户端尝试发送一个消息而没有设置昵称,则返回一个 "Please set your nickname first"
的错误消息。
最后,我们需要添加一个 broadcast()
方法,以便将消息广播到所有选定的 WebSocket 客户端。
function broadcast(data: any) { const message = JSON.stringify(data); clients.forEach((client) => client.ws.send(message)); }
现在,我们已经实现了一个功能齐全的实时聊天室。让我们看看如何运行它。
运行实时聊天室
我们可以使用以下命令来启动 Deno 服务器:
deno run --allow-net server.ts
然后,我们可以在浏览器中打开以下 URL 来访问客户端 HTML 页面:
http://localhost:3000/
现在,我们可以通过在多个浏览器窗口中打开该 URL,或者使用 curl
或其他 HTTP 工具来模拟多个 WebSocket 客户端,来测试我们的实时聊天室。
结论
WebSocket 是构建实时 web 应用程序的强大工具。在 Deno 中,我们可以使用标准库提供的 WebSocket 模块,轻松地创建 WebSocket 服务器和客户端,以建立实时、双向通信。
本文介绍了在 Deno 中使用 WebSocket 实现实时聊天室的最佳实践。我们讨论了如何管理用户在线状态、发送聊天消息以及广播信息给所有连接的 WebSocket 客户端。
通过本文,我们希望读者可以更好地理解 WebSocket 的工作原理,并能够在 Deno 中使用 WebSocket 构建高效、可伸缩的实时 web 应用程序。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/670c7a0566ef9cf37fb18cba