前端全栈之路Deno篇(五):如何快速创建 WebSocket 服务端应用 + 客户端应用 - 可能是2025最佳的Websocket全栈实时应用框架

本文涉及的产品
Serverless 应用引擎免费试用套餐包,4320000 CU,有效期3个月
函数计算FC,每月15万CU 3个月
简介: 本文介绍了如何使用Deno 2.0快速构建WebSocket全栈应用,包括服务端和客户端的创建。通过一个简单的代码示例,展示了Deno在WebSocket实现中的便捷与强大,无需额外依赖,即可轻松搭建具备基本功能的WebSocket应用。Deno 2.0被认为是最佳的WebSocket全栈应用JS运行时,适合全栈开发者学习和使用。

在前一篇文章 Deno2.0如何快速创建Restfulapi/静态文件托管应用及oak框架介绍 介绍了利用Deno2.0创建http服务端应用的方法,本文主要介绍如果利用它来构建Websocket全栈应用。而且,我可以大言不惭的称之为最佳的Websocket全栈应用js运行时

在全栈开发中,WebSocket 是一种非常常见的实时通信方式,而 Deno 作为一个新兴的 JavaScript/TypeScript 运行时,为创建 WebSocket 提供了更加简便的方式。在本文中,我们将讨论如何利用 Deno 2.0 快速创建 WebSocket 服务端和客户端应用。让我们通过一个简单的代码示例,来探索 Deno 在 WebSocket 实现中的便捷与强大。

Deno Deploy 代码和在线测试环境

准备工作

在本篇内容中,我们将会实现以下功能:

  1. 创建一个 Deno 服务端,用于处理 WebSocket 请求。
  2. 创建客户端页面,用于连接并与 WebSocket 服务器交互。(因为编码简化,按钮使用英文Connect=连接)
  3. 在服务端代码中同时连接自身进行内部测试。

代码示例如下所示:

// 下面这个方法是前后端共用了 - 便于展示前后端接口一致性复用的好处
const createSocket = (url: string, startPing = false, isWeb = false) => {
   
  const ws = new WebSocket(url);

  ws.onopen = () => {
   
    console.log(`ws open isWeb: ${
     isWeb}`);
    if (startPing) ws.send('ping');
  };

  ws.onmessage = (ev) => {
   
    console.log(`message:`, ev.data);
    if (isWeb) document.querySelector('#msg').innerText = ev.data;
  };

  ws.onerror = (err) => {
   
    console.log(`ws err isWeb: ${
     isWeb}`);
    console.error(err);
  };
};

Deno.serve((req) => {
   
  if (req.headers.get("upgrade") !== "websocket") {
   
    return new Response(`
        <div id=msg> messages </div>
        <script>
        // 这里就把共用的代码用最简单的方式传回给web前端,
        const createSocket = ${
     String(createSocket)};
        window.connect = () => createSocket('wss://' + location.host, true, true);
        </script>
        <button onclick="connect()">Connect</button>
    `, {
   
      headers: {
   
        'content-type': 'text/html'
      }
    });
  }
  const {
    socket, response } = Deno.upgradeWebSocket(req);
  socket.addEventListener("open", () => {
   
    console.log("a client connected!");
  });
  socket.addEventListener("message", (event) => {
   
    if (event.data === "ping") {
   
      socket.send("pong");
    }
  });
  return response;
});

setTimeout(() => {
   
  // 这里就是服务端直接跑一个客户端连接刚刚起来的服务端应用
  console.log(`server side client`);
  createSocket("wss://afraid-boar-70.deno.dev", true, false);
});

服务器端的websocket客户端连接:
8d3da5817788485790b667bdfb38c578.png

客户端的websocket客户端连接(点了connect之后)
5edaa5e9581243e5a0a72e4d7f744cc5.png

代码解析

服务端和客户端的集成

在上述代码中,Deno.serve() 方法用于创建一个 HTTP 服务器,并根据请求类型处理不同的响应:

  • 当请求头中不包含 "upgrade" : "websocket" 时,返回一个简单的 HTML 页面,该页面包含一个按钮用于手动连接到 WebSocket 服务端。
  • 当请求为 WebSocket 连接时,通过 Deno.upgradeWebSocket(req) 升级请求,并创建 WebSocket 连接。

客户端连接

我们在 HTML 中通过 <button> 元素来触发客户端 WebSocket 连接,并使用 createSocket() 函数来实现连接逻辑。该函数通过 JavaScript 原生的 WebSocket 对象来建立连接,并添加了一些监听事件用于响应连接的状态变化和消息接收。

createSocket(url: string, startPing = false, isWeb = false) 函数的主要逻辑:

  • onopen: 在 WebSocket 连接建立后调用,输出连接信息,并根据 startPing 参数发送 "ping" 消息。
  • onmessage: 在收到服务端消息时调用,输出消息内容,如果是网页端,则在页面上更新显示消息。
  • onerror: 在 WebSocket 出现错误时调用,输出错误信息。

服务端内部客户端连接

为了测试 WebSocket 连接,代码中还使用 setTimeout() 创建了一个延时调用,在服务端启动后通过 createSocket("wss://afraid-boar-70.deno.dev", true, false) 进行 WebSocket 客户端连接。这样可以让服务端自身成为一个客户端,与自己进行消息通信。

WebSocket 服务端处理流程

下面是一个使用 Mermaid 绘制的图,表示 WebSocket 服务端应用每个连接的处理流程:

graph TD
    A[接收请求] --> B{请求类型}
    B -- 非 WebSocket 请求 --> C[返回 HTML 页面]
    B -- WebSocket 请求 --> D[升级为 WebSocket]
    D --> E[监听 open 事件]
    E --> F[客户端连接成功]
    D --> G[监听 message 事件]
    G --> H{消息类型}
    H -- ping --> I[发送 pong]

运行示例(本地)

要运行这段代码,首先确保您已经安装了 Deno 运行时。然后可以通过以下命令运行代码:

deno run --allow-net your_file.ts

运行后,Deno 会启动一个 WebSocket 服务器,您可以在浏览器中访问相应的地址来看到网页客户端部分,点击 "Connect" 按钮即可连接到服务器并发送 ping 消息。

与 Node.js 创建 WebSocket 服务端应用的对比

在 Node.js 中创建 WebSocket 服务端通常需要借助第三方库,例如 wssocket.io。以下是与 Deno 创建 WebSocket 服务端的对比:

  • 依赖性:Deno 自带 WebSocket 支持,无需额外安装依赖,而在 Node.js 中,需要安装如 wssocket.io 等库。
  • 代码复杂性:使用 Deno 创建 WebSocket 服务端相对简单,只需调用 Deno.serve()Deno.upgradeWebSocket()。在 Node.js 中,通常需要编写更多的代码来处理 WebSocket 升级和连接。

例如,在 Node.js 中使用 ws 创建 WebSocket 服务器的代码如下:

const WebSocket = require('ws');

const wss = new WebSocket.Server({
    port: 8080 });

wss.on('connection', function connection(ws) {
   
  ws.on('message', function message(data) {
   
    console.log('received: %s', data);
    if (data === 'ping') {
   
      ws.send('pong');
    }
  });

  ws.send('connected');
});

与 Deno 相比,Node.js 的实现需要手动处理端口、连接事件等,相对复杂一些。但使用 socket.io 这样的库,可以提供更丰富的功能,例如房间管理、自动重连等。

与 Node.js 创建 WebSocket 客户端的对比

在 Node.js 中创建 WebSocket 客户端也需要依赖 ws 库,而在 Deno 中可以直接使用与前端一致的 WebSocket 接口进行连接,这使得代码更加统一,开发体验更好。

在 Deno 中,我们使用 WebSocket 对象来建立客户端连接,与前端 JavaScript 的使用方式完全相同,例如:

const ws = new WebSocket('wss://example.com');

而在 Node.js 中,代码如下:

const WebSocket = require('ws');

const ws = new WebSocket('wss://example.com');

ws.on('open', function open() {
   
  console.log('connected');
  ws.send('ping');
});

ws.on('message', function message(data) {
   
  console.log('received: %s', data);
});

Node.js 使用 ws 库来模拟浏览器中的 WebSocket 对象,但需要手动引入库,这使得代码在不同环境下不一致。而 Deno 则可以直接使用标准的 WebSocket 接口,这对于前端开发者来说更加自然和方便。

Deno、Bun 和 Node.js 对于 WebSocket 支持的对比

下表列出了 Deno、Bun 和 Node.js 在创建 WebSocket 服务端应用时的特性对比:

特性 Deno Bun Node.js (ws/socket.io)
内置 WebSocket 支持 否,需要额外库 否,需要额外库
升级 WebSocket 方法 Deno.upgradeWebSocket() 使用第三方库实现 使用 wssocket.io
依赖库 无需额外依赖 需要第三方库 需要 wssocket.io
代码复杂性 简单 依赖库特性,视实现而定 代码较多,依赖第三方库
性能 高效 高效 依赖库性能

下表列出了 Deno、Bun 和 Node.js 在创建 WebSocket 客户端应用时的特性对比:

特性 Deno Bun Node.js (ws)
WebSocket API 一致性 与前端一致 依赖库特性,可能不同 与前端不同,需要 ws
内置支持 否,需要额外库 否,需要 ws
依赖库 无需额外依赖 需要第三方库 需要 ws
代码复杂性 简单,与前端一致 依赖库特性,视实现而定 代码较多,需引入库

总结

通过上述代码示例,我们可以看到 Deno 提供了简洁高效的 WebSocket 支持,无需额外依赖包便可以快速搭建一个具备基本功能的 WebSocket 服务端和客户端。对于想要学习全栈开发的前端开发者来说,Deno 是一个值得尝试的新工具,它具有现代化的开发体验,同时又兼具简单易用的特性。希望这篇文章能帮助您迈出使用 Deno 的第一步,搭建自己的 WebSocket 应用。

怎么说呢?刚开始搭建这个后端的时候,我还走了不少弯路子,还在用Nodejs的思维 - -,实际上Deno简化了很多,作为客户端直接用Websocket就可以,而我还在jsr搜索。Deno2.0值得学习和使用,反正我是在慢慢的重写一个实时的应用了。

相关文章
|
1月前
|
Cloud Native 前端开发 JavaScript
前端开发者必看:不懂云原生你就OUT了!揭秘如何用云原生技术提升项目部署与全栈能力
【10月更文挑战第23天】随着云计算的发展,云原生逐渐成为技术热点。前端开发者了解云原生有助于提升部署与运维效率、实现微服务化、掌握全栈开发能力和利用丰富技术生态。本文通过示例代码介绍云原生在前端项目中的应用,帮助开发者更好地理解其重要性。
60 0
|
2月前
|
前端开发 JavaScript 中间件
前端全栈之路Deno篇(四):Deno2.0如何快速创建http一个 restfulapi/静态文件托管应用及oak框架介绍
Deno 是由 Node.js 创始人 Ryan Dahl 开发的新一代 JavaScript 和 TypeScript 运行时,旨在解决 Node.js 的设计缺陷,具备更强的安全性和内置的 TypeScript 支持。本文介绍了如何使用 Deno 内置的 `Deno.serve` 快速创建 HTTP 服务,并详细讲解了 Oak 框架的安装和使用方法,包括中间件、路由和静态文件服务等功能。Deno 和 Oak 的结合使得创建 RESTful API 变得高效且简便,非常适合快速开发和部署现代 Web 应用程序。
|
2月前
|
前端开发 安全 API
前端全栈之路Deno篇(三):一次性搞懂和学会用Deno 2.0 的权限系统详解和多种权限配置权限声明方式
本文深入解析了 Deno 2.0 的权限系统,涵盖主包和第三方包的权限控制机制,探讨了通过命令行参数、权限 API 和配置文件等多种权限授予方式,并提供了代码示例和运行指导,帮助开发者有效管理权限,提升应用安全性。
|
2月前
|
存储 人工智能 前端开发
前端大模型应用笔记(三):Vue3+Antdv+transformers+本地模型实现浏览器端侧增强搜索
本文介绍了一个纯前端实现的增强列表搜索应用,通过使用Transformer模型,实现了更智能的搜索功能,如使用“番茄”可以搜索到“西红柿”。项目基于Vue3和Ant Design Vue,使用了Xenova的bge-base-zh-v1.5模型。文章详细介绍了从环境搭建、数据准备到具体实现的全过程,并展示了实际效果和待改进点。
142 2
|
2月前
|
JavaScript 前端开发 程序员
前端学习笔记——node.js
前端学习笔记——node.js
44 0
|
2月前
|
人工智能 自然语言处理 运维
前端大模型应用笔记(一):两个指令反过来说大模型就理解不了啦?或许该让第三者插足啦 -通过引入中间LLM预处理用户输入以提高多任务处理能力
本文探讨了在多任务处理场景下,自然语言指令解析的困境及解决方案。通过增加一个LLM解析层,将复杂的指令拆解为多个明确的步骤,明确操作类型与对象识别,处理任务依赖关系,并将自然语言转化为具体的工具命令,从而提高指令解析的准确性和执行效率。
|
2月前
|
存储 弹性计算 算法
前端大模型应用笔记(四):如何在资源受限例如1核和1G内存的端侧或ECS上运行一个合适的向量存储库及如何优化
本文探讨了在资源受限的嵌入式设备(如1核处理器和1GB内存)上实现高效向量存储和检索的方法,旨在支持端侧大模型应用。文章分析了Annoy、HNSWLib、NMSLib、FLANN、VP-Trees和Lshbox等向量存储库的特点与适用场景,推荐Annoy作为多数情况下的首选方案,并提出了数据预处理、索引优化、查询优化等策略以提升性能。通过这些方法,即使在资源受限的环境中也能实现高效的向量检索。
|
2月前
|
机器学习/深度学习 弹性计算 自然语言处理
前端大模型应用笔记(二):最新llama3.2小参数版本1B的古董机测试 - 支持128K上下文,表现优异,和移动端更配
llama3.1支持128K上下文,6万字+输入,适用于多种场景。模型能力超出预期,但处理中文时需加中英翻译。测试显示,其英文支持较好,中文则需改进。llama3.2 1B参数量小,适合移动端和资源受限环境,可在阿里云2vCPU和4G ECS上运行。
|
2月前
|
前端开发 算法 测试技术
前端大模型应用笔记(五):大模型基础能力大比拼-计数篇-通义千文 vs 文心一言 vs 智谱 vs 讯飞vsGPT
本文对比测试了通义千文、文心一言、智谱和讯飞等多个国产大模型在处理基础计数问题上的表现,特别是通过链式推理(COT)提示的效果。结果显示,GPTo1-mini、文心一言3.5和讯飞4.0Ultra在首轮测试中表现优秀,而其他模型在COT提示后也能显著提升正确率,唯有讯飞4.0-Lite表现不佳。测试强调了COT在提升模型逻辑推理能力中的重要性,并指出免费版本中智谱GLM较为可靠。
前端大模型应用笔记(五):大模型基础能力大比拼-计数篇-通义千文 vs 文心一言 vs 智谱 vs 讯飞vsGPT
|
3月前
|
SpringCloudAlibaba JavaScript 前端开发
谷粒商城笔记+踩坑(2)——分布式组件、前端基础,nacos+feign+gateway+ES6+vue脚手架
分布式组件、nacos注册配置中心、openfegin远程调用、网关gateway、ES6脚本语言规范、vue、elementUI
谷粒商城笔记+踩坑(2)——分布式组件、前端基础,nacos+feign+gateway+ES6+vue脚手架

热门文章

最新文章