首页 >web前端 >js教程 >使用 JavaScript 和 Bun 的 WebSocket

使用 JavaScript 和 Bun 的 WebSocket

Susan Sarandon
Susan Sarandon原创
2024-12-03 06:00:16818浏览

确保客户端和服务器之间高效、无缝的通信是构建现代实时 Web 应用程序的关键。传统的 HTTP 请求(如轮询中使用的请求)是无状态且单向的。客户端向服务器发出请求(例如,使用 fetch 或 axios),服务器在连接关闭之前做出响应。如果客户端需要新鲜数据,则必须定期重复发送新请求,从而造成不必要的延迟并增加客户端和服务器的负载。

例如,如果您正在构建实时聊天应用程序或股票价格跟踪器,则轮询将要求客户端每秒左右请求更新一次,即使没有新数据可供获取。这就是 WebSockets 的闪光点。


WebSocket 方法

WebSockets 在客户端和服务器之间提供持久的双向通信通道。连接建立后,服务器可以立即将更新推送到客户端,而无需等待新的请求。这使得 WebSockets 非常适合需要实时更新的场景,例如:

  • 在实时聊天应用程序中发送聊天消息。
  • 同时向多个用户广播通知或更新。
  • 流式传输实时数据,例如股票价格、体育比分或游戏状态。

在客户端使用 Vanilla JavaScript,在服务器端使用 Bun 运行时,使得 WebSocket 的实现变得简单而高效。例如:

  • 客户端可以向服务器发送消息,服务器可以立即将该消息广播给其他连接的客户端。
  • 与轮询不同,持久连接确保不会产生重新建立连接的重复开销。

在这种情况下,WebSocket 比传统的轮询方法提供更低的延迟、减少的服务器负载以及更流畅的用户体验。


构建 WebSocket 项目

第 1 步:建立 Bun 项目

首先,确保 Bun 已安装。然后新建一个Bun项目,新建一个空目录,进入新目录,通过bun init命令初始化项目:

mkdir websocket-demo
cd websocket-demo
bun init

bun init 命令将创建 package.json 文件、“hello world”index.ts 文件、.gitignore 文件、用于打字稿配置的 tsconfig.json 文件和 README.md 文件。

现在,您可以开始创建 JavaScript 代码。我将向您展示整个脚本;然后我们将探索所有相关部分。您可以编辑index.ts文件:

console.log("? Hello via Bun! ?");
const server = Bun.serve({
  port: 8080, // defaults to $BUN_PORT, $PORT, $NODE_PORT otherwise 3000
  fetch(req, server) {
    const url = new URL(req.url);
    if (url.pathname === "/") return new Response(Bun.file("./index.html"));
    if (url.pathname === "/surprise") return new Response("?");

    if (url.pathname === "/chat") {
      if (server.upgrade(req)) {
        return; // do not return a Response
      }
      return new Response("Upgrade failed", { status: 400 });
    }

    return new Response("404!");
  },
  websocket: {
    message(ws, message) {
      console.log("✉️ A new Websocket Message is received: " + message);
      ws.send("✉️ I received a message from you:  " + message);
    }, // a message is received
    open(ws) {
      console.log("? A new Websocket Connection");
      ws.send("? Welcome baby");
    }, // a socket is opened
    close(ws, code, message) {
      console.log("⏹️ A Websocket Connection is CLOSED");
    }, // a socket is closed
    drain(ws) {
      console.log("DRAIN EVENT");
    }, // the socket is ready to receive more data
  },
});
console.log(`? Server (HTTP and WebSocket) is launched ${server.url.origin}`);

使用 Bun 记录基本 WebSocket 服务器的代码

下面是所提供代码的细分,解释了每个部分及其功能。


服务器初始化

mkdir websocket-demo
cd websocket-demo
bun init

Bun.serve 方法初始化一个能够处理 HTTPWebSocket 请求的服务器。

  • port: 8080:指定服务器监听的端口。默认为公共环境变量,如果未指定则默认为 3000。在这个例子中,端口被硬编码为8080。如果你想提供更灵活的方式,你应该删除端口线并允许Bun来管理端口。所以你可以通过export BUN_PORT=4321运行脚本;包子跑指数.ts

HTTP 请求处理

console.log("? Hello via Bun! ?");
const server = Bun.serve({
  port: 8080, // defaults to $BUN_PORT, $PORT, $NODE_PORT otherwise 3000
  fetch(req, server) {
    const url = new URL(req.url);
    if (url.pathname === "/") return new Response(Bun.file("./index.html"));
    if (url.pathname === "/surprise") return new Response("?");

    if (url.pathname === "/chat") {
      if (server.upgrade(req)) {
        return; // do not return a Response
      }
      return new Response("Upgrade failed", { status: 400 });
    }

    return new Response("404!");
  },
  websocket: {
    message(ws, message) {
      console.log("✉️ A new Websocket Message is received: " + message);
      ws.send("✉️ I received a message from you:  " + message);
    }, // a message is received
    open(ws) {
      console.log("? A new Websocket Connection");
      ws.send("? Welcome baby");
    }, // a socket is opened
    close(ws, code, message) {
      console.log("⏹️ A Websocket Connection is CLOSED");
    }, // a socket is closed
    drain(ws) {
      console.log("DRAIN EVENT");
    }, // the socket is ready to receive more data
  },
});
console.log(`? Server (HTTP and WebSocket) is launched ${server.url.origin}`);

  • fetch(req, server):处理传入的 HTTP 请求。
  • 根路径/:提供index.html文件。
  • /surprise 路径:返回一个有趣的惊喜表情符号响应?.
  • /chat 路径:尝试将连接“升级”为 WebSocket 连接。如果升级失败,则会返回错误 400 响应。

WebSocket 处理程序

websocket 键定义事件处理程序来管理 WebSocket 连接。

?连接打开(打开)

const server = Bun.serve({
  port: 8080, // defaults to $BUN_PORT, $PORT, $NODE_PORT otherwise 3000
  ...
});

客户端建立 WebSocket 连接时触发。

  • ws.send(...): 向请求连接的客户端发送欢迎消息..

✉️接收消息(消息)

fetch(req, server) {
  const url = new URL(req.url);

  if (url.pathname === "/") 
    return new Response(Bun.file("./index.html"));

  if (url.pathname === "/surprise") 
    return new Response("?");

  if (url.pathname === "/chat") {
    if (server.upgrade(req)) {
      return; // do not return a Response
    }
    return new Response("Upgrade failed", { status: 400 });
  }

  return new Response("404!");
}

服务器收到客户端消息时触发。

  • ws.send(...):回显收到的消息并进行确认。

⏹️连接关闭(关闭)

open(ws) {
  console.log("? A new Websocket Connection");
  ws.send("? Welcome baby");
}

WebSocket 连接关闭时触发。

参数:

  • code: 关闭连接的原因代码。
  • 消息:有关关闭的更多详细信息。

?排水事件(排水)

message(ws, message) {
  console.log("✉️ A new Websocket Message is received: " + message);
  ws.send("✉️ I received a message from you: " + message);
}

当 WebSocket 在暂时不堪重负后准备好接受更多数据时,会触发排出事件。


记录服务器启动

close(ws, code, message) {
  console.log("⏹️ A Websocket Connection is CLOSED");
}

服务器运行后将其 URL 记录到控制台。


回顾一下它是如何工作的

  1. HTTP 请求:处理标准 HTTP 请求(例如,提供文件或响应状态)。
  2. WebSocket 升级:当客户端连接到 /chat 时,将 HTTP 连接升级为 WebSocket 连接。
  3. 实时通信:使用 WebSocket 事件(打开、消息、关闭、耗尽)处理服务器和客户端之间的持久通信。

运行服务器

一旦你有了index.ts文件,你就可以通过bun run启动服务器:

drain(ws) {
  console.log("DRAIN EVENT");
}

服务器已准备就绪并已启动并正在运行。现在,我们可以实现客户端了。

WebSocket with JavaScript and Bun

后续步骤

现在我们了解了处理 WebSocket 的脚本的结构,接下来的步骤是:

  • 为 WebSocket 客户端实现 HTML;
  • 实现广播逻辑,将消息从一个客户端转发到所有连接的客户端。

以上是使用 JavaScript 和 Bun 的 WebSocket的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn