使用 Koa2 和 WebSocket 构建聊天室应用

阅读时长 17 分钟读完

前言

在现代互联网应用中,聊天室是一个常见的场景。为了满足不同用户群体的需求,聊天室应用往往需要支持不同的功能,如群聊、私聊、消息记录等。为了提供更好的用户体验,聊天室应用也需要支持即时通讯技术。本文将介绍如何使用 Koa2 和 WebSocket 构建聊天室应用。

技术背景

Koa2 是一个轻量级的 Node.js WEB 框架,通过中间件的方式实现路由、参数解析、错误处理等功能。WebSocket 是一种全双工通信协议,能够在客户端与服务器之间建立实时的、双向的数据流通道。使用 WebSocket 可以让聊天室应用实时更新聊天内容,提升用户体验。

实现步骤

1. 安装依赖

使用 Koa2 和 WebSocket 需要安装相应的依赖:

  • koa:Koa2 的核心模块,用于创建 Web 应用;
  • koa-router:Koa2 的路由模块,用于管理 URL;
  • koa-static:Koa2 的静态文件模块,用于提供静态文件服务;
  • koa-bodyparser:Koa2 的请求体解析模块,用于解析请求体中的参数;
  • websocket:WebSocket 实现模块。

2. 初始化 Koa2 应用

在项目根目录下创建一个 server.js 文件,输入以下代码:

-- -------------------- ---- -------
----- --- - ---------------
----- ------ - ----------------------
----- --- - --- ------
----- ------ - --- ---------
----- ---- - ---------------- -- -----

-- ------
--------------------------------------- - ------------

-- --
--------------- ----- ----- -- -
  -------- - -------
  -------- - -------------------------------------------
---

-- ----
------------------------------------------------------
---------------- -- -- -
  ------------------- --------- -- ----- ---- ------
---

这段代码主要完成以下任务:

  • 使用 Koa 静态文件模块提供静态文件服务;
  • 使用 Koa 路由模块创建路由,返回 HTML 页面;
  • 启动 Koa2 应用。

3. 实现 WebSocket 通信

WebSocket 是一种全双工通信协议,需要客户端和服务器之间建立通信通道。在 Koa2 中,我们可以使用 WebSocket 模块实现 WebSocket 通信。在 server.js 文件中加入以下代码:

-- -------------------- ---- -------
----- --------- - ----------------------------

-- -- --------- ---
----- -------- - --- -----------
  ----------- -------
---

-- -- --------- --
---------------------- --------- -- -
  ----- ---------- - -------------------- ----------------
  ------------------------ --------- -- -
    --------------------- -------- ----------------------
    ----------------------- ----- ----------------------
  ---
---

这段代码主要完成以下任务:

  • 使用 WebSocket 模块创建 WebSocket 服务器;
  • 处理 WebSocket 请求,响应客户端的消息。

4. 实现聊天室功能

要实现聊天室功能,需要在服务器端维护一个用户列表和消息记录列表。每当有用户进入聊天室或发送消息时,都需要更新用户列表和消息记录列表,并向所有在线用户广播消息。在 server.js 文件中加入以下代码:

-- -------------------- ---- -------
-- ----
--- ----- - ---
--- -------- - ---

-- -- --------- --
---------------------- --------- -- -
  ----- ---------- - -------------------- ----------------

  -- --------------------------------
  --------------------- -- -- -
    ----- ---- - -
      --- -----------
      -----------
    --
    -----------------
    ----------
      -
        ----- ------------
        ----- ------
      --
      ----
    --
    ----------
      -
        ----- ---------------
        ----- ---------
      --
      ----
    --
  ---

  -- ----------------------------------
  ---------------------- -- -- -
    ----- - ------------------- -- --------------- --- ------------
    ----------
      -
        ----- ------------
        ----- ------
      --
      ----
    --
  ---

  -- -----------------------------------
  ------------------------ --------- -- -
    ----- ---- - ----------------- -- --------------- --- ------------
    ----- ---- - -----------------------------
    ----- ---------- - -
      --- -----------
      -----
      ----- ----------
      ----- --- -------
    --
    --------------------------
    ----------
      -
        ----- --------------
        ----- -----------
      --
      ----
    --
  ---
---

-- ----
-------- --------------- -------- -
  -------------------- -- -
    -- ----- --- -------- -
      ----------------------------------------------
    -
  ---
-

这段代码主要完成以下任务:

  • 定义了一个用户列表和消息记录列表;
  • 处理 WebSocket 请求,当用户进入聊天室时将其加入用户列表,当用户退出聊天室时将其从用户列表中删除,在用户发送消息时添加到消息记录列表中,并向所有在线用户广播消息。

5. HTML 页面编写

最后,我们需要编写一个 HTML 页面来使用聊天室应用。在线上,需要将相关的JS注入HTML。HTML页面内容如下:

<html> <head> <meta /> <title>Koa2 WebSocket Chat</title> <style> * { margin: 0; padding: 0; } <pre class="prettyprint undefined">-- -------------------- ---- ------- ---- - ----------------- -------- ------------ ---------- ------ ---------- ------ ----------- ---------- ----- - ---------- - ------- - ----- ---------- ------ -------- ----- - ------ - ----------- ------- ---------- ----- -------------- ----- ------------ --- --- ----- ------ ----- - ---------- - ------- ------ ----------------- ----- ------- --- ----- ----- -------------- ----- ----------- ------- - ------------------- - -------- ---- -------------- --- ----- ----- - ------------------------------ - -------------- ----- - ------------------------ - ---------- ----- ------ ----- - ------------------------ - ------------ ----- ------ ----- ------------- ---- - ------------------------ - ------ ----- - ----- - -------- ----- -------------- ----- - ------------ - ---------- -- ------------- ---- -------------- ---- ------- ----- -------- ----- -------- ---- ---------- ----- - ------------- - ----------------- ----- -------------- ---- ------- ----- -------- ----- -------- ---- ------ ----- ------- -------- ---------- ----- - ------------------- - ----------------- ----- - ---------- - ----------- ----- -------------- ----- - ---------------- - -------------- ---- -------- ---- -------------- ---- ----------------- ----- -</pre><p> </style> </head> <body>

Koa2 WebSocket Chat

    <form> <input /> <button>Send</button> </form>
    <script> // WebSocket const socket = new WebSocket("ws://localhost:3000"); socket.addEventListener("open", (event) => { console.log("WebSocket connected"); }); socket.addEventListener("message", (event) => { const data = JSON.parse(event.data); switch (data.type) { case "user_list": renderUserList(data.data); break; case "message_list": renderMessageList(data.data); break; case "new_message": renderNewMessage(data.data); break; } }); function sendMessage(text) { const data = { text, }; socket.send(JSON.stringify(data)); } // 渲染用户列表 function renderUserList(users) { const $userList = document.querySelector(".user-list"); $userList.innerHTML = ""; users.forEach((user) => { const $user = document.createElement("li"); $user.classList.add("user-list__user"); $user.textContent = `User ${user.id}`; $userList.appendChild($user); }); } // 渲染消息记录 function renderMessageList(messages) { const $chatRoom = document.querySelector(".chat-room"); $chatRoom.innerHTML = ""; messages.forEach((message) => { const $message = document.createElement("div"); $message.classList.add("chat-room__message"); const $messageUser = document.createElement("span"); $messageUser.classList.add("chat-room__message-user"); $messageUser.textContent = `User ${message.user.id}`; const $messageText = document.createElement("span"); $messageText.classList.add("chat-room__message-text"); $messageText.textContent = message.text; const $messageTime = document.createElement("span"); $messageTime.classList.add("chat-room__message-time"); $messageTime.textContent = formatTime(message.time); $message.appendChild($messageUser); $message.appendChild($messageText); $message.appendChild($messageTime); $chatRoom.appendChild($message); }); } // 渲染新消息 function renderNewMessage(message) { const $chatRoom = document.querySelector(".chat-room"); const $message = document.createElement("div"); $message.classList.add("chat-room__message"); const $messageUser = document.createElement("span"); $messageUser.classList.add("chat-room__message-user"); $messageUser.textContent = `User ${message.user.id}`; const $messageText = document.createElement("span"); $messageText.classList.add("chat-room__message-text"); $messageText.textContent = message.text; const $messageTime = document.createElement("span"); $messageTime.classList.add("chat-room__message-time"); $messageTime.textContent = formatTime(message.time); $message.appendChild($messageUser); $message.appendChild($messageText); $message.appendChild($messageTime); $chatRoom.appendChild($message); $chatRoom.scrollTop = $chatRoom.scrollHeight; } // 格式化时间 function formatTime(time) { const date = new Date(time); const hour = date.getHours(); const minute = date.getMinutes().toString().padStart(2, "0"); const second = date.getSeconds().toString().padStart(2, "0"); return `${hour}:${minute}:${second}`; } // 发送消息 const $form = document.querySelector(".form"); const $input = document.querySelector(".form__input"); $form.addEventListener("submit", (event) => { event.preventDefault(); const text = $input.value.trim(); if (text) { sendMessage(text); $input.value = ""; } }); </script> </body> </html>

    总结

    本文介绍了如何使用 Koa2 和 WebSocket 构建聊天室应用。通过本文的学习,我们了解了 Koa2 和 WebSocket 的使用方法,并学会了实现聊天室功能的相关技术。希望本文能对您在开发聊天室应用时有所帮助。

    来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64697d81968c7c53b09643b0

    纠错
    反馈