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

本文涉及的产品
函数计算FC,每月15万CU 3个月
Serverless 应用引擎免费试用套餐包,4320000 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值得学习和使用,反正我是在慢慢的重写一个实时的应用了。

相关文章
|
10天前
|
前端开发 JavaScript 开发者
颠覆传统:React框架如何引领前端开发的革命性变革
【10月更文挑战第32天】本文以问答形式探讨了React框架的特性和应用。React是一款由Facebook推出的JavaScript库,以其虚拟DOM机制和组件化设计,成为构建高性能单页面应用的理想选择。文章介绍了如何开始一个React项目、组件化思想的体现、性能优化方法、表单处理及路由实现等内容,帮助开发者更好地理解和使用React。
36 9
|
15天前
|
前端开发 JavaScript 安全
前端性能调优:HTTP/2与HTTPS在Web加速中的应用
【10月更文挑战第27天】本文介绍了HTTP/2和HTTPS在前端性能调优中的应用。通过多路复用、服务器推送和头部压缩等特性,HTTP/2显著提升了Web性能。同时,HTTPS确保了数据传输的安全性。文章提供了示例代码,展示了如何使用Node.js创建一个HTTP/2服务器。
29 3
|
4天前
|
前端开发 JavaScript API
前端界的秘密武器:掌握这些框架,让你轻松秒杀99%的同行!
前端开发日新月异,掌握几个明星框架如React、Vue.js和Angular,不仅能让工作更得心应手,还能轻松超越同行。React以高效的虚拟DOM和组件化著称;Vue.js简洁易懂,灵活性高;Angular提供全面的解决方案,适合大型应用。此外,轻量级的Svelte也值得关注,其编译时处理设计提升了应用性能。掌握这些框架,结合深刻理解和灵活运用,助你在前端领域脱颖而出。
17 9
|
16天前
|
Rust 前端开发 JavaScript
前端性能革命:WebAssembly在高性能计算中的应用探索
【10月更文挑战第26天】随着Web应用功能的日益复杂,传统JavaScript解释执行模式逐渐成为性能瓶颈。WebAssembly(Wasm)应运而生,作为一种二进制代码格式,支持C/C++、Rust等语言编写的代码在浏览器中高效运行。Wasm不仅提升了应用的执行速度,还具备跨平台兼容性和安全性,显著改善了Web应用的响应速度和用户体验。
31 4
|
15天前
|
前端开发 数据管理 测试技术
前端自动化测试:Jest与Cypress的实战应用与最佳实践
【10月更文挑战第27天】本文介绍了前端自动化测试中Jest和Cypress的实战应用与最佳实践。Jest适合React应用的单元测试和快照测试,Cypress则擅长端到端测试,模拟用户交互。通过结合使用这两种工具,可以有效提升代码质量和开发效率。最佳实践包括单元测试与集成测试结合、快照测试、并行执行、代码覆盖率分析、测试环境管理和测试数据管理。
31 2
|
15天前
|
前端开发 JavaScript
Bootstrap Web 前端 UI 框架
Bootstrap 是快速开发 Web 应用程序的前端工具包。
30 3
|
16天前
|
前端开发 安全 应用服务中间件
前端性能调优:HTTP/2与HTTPS在Web加速中的应用
【10月更文挑战第26天】随着互联网的快速发展,前端性能调优成为开发者的重要任务。本文探讨了HTTP/2与HTTPS在前端性能优化中的应用,介绍了二进制分帧、多路复用和服务器推送等特性,并通过Nginx配置示例展示了如何启用HTTP/2和HTTPS,以提升Web应用的性能和安全性。
17 3
|
16天前
|
前端开发 JavaScript 数据可视化
前端自动化测试:Jest与Cypress的实战应用与最佳实践
【10月更文挑战第26天】前端自动化测试在现代软件开发中至关重要,Jest和Cypress分别是单元测试和端到端测试的流行工具。本文通过解答一系列问题,介绍Jest与Cypress的实战应用与最佳实践,帮助开发者提高测试效率和代码质量。
27 2
|
16天前
|
前端开发 JavaScript API
前端框架新探索:Svelte在构建高性能Web应用中的优势
【10月更文挑战第26天】近年来,前端技术飞速发展,Svelte凭借独特的编译时优化和简洁的API设计,成为构建高性能Web应用的优选。本文介绍Svelte的特点和优势,包括编译而非虚拟DOM、组件化开发、状态管理及响应式更新机制,并通过示例代码展示其使用方法。
32 2
|
4月前
|
前端开发 网络协议 JavaScript
在Spring Boot中实现基于WebSocket的实时通信
在Spring Boot中实现基于WebSocket的实时通信

热门文章

最新文章