利用 SSE 进行实时聊天的最佳实践

随着移动互联网和社交媒体的飞速发展,实时聊天成为了越来越多网站和应用必不可少的功能之一。而 SSE (Server-Sent Events) 就是其中一种实现实时聊天的方式,它可以让服务器主动向客户端推送数据,没有轮询和刷新的过程,能够有效地减少网络传输量和服务器压力,同时也提高了用户体验。

本文将详细介绍利用 SSE 实现实时聊天的最佳实践,并附带示例代码和详细的指导意义,帮助前端开发者了解 SSE 技术的应用,并能够快速地在自己的项目中应用该技术。

SSE 的基本原理

SSE 是基于 HTTP 协议的,它利用了浏览器对于 HTTP 协议“流”的支持。当浏览器向服务器发送一个 SSE 请求时,服务器可以将需要推送的数据发送给客户端,浏览器会保持连接状态,直到服务器关闭连接或超时,就像与服务器一直保持着一个 WebSocket 连接一样。在这个过程中,服务器可以随时向客户端推送消息。

SSE 的消息使用 plain text 或者 JSON 格式,格式如下:

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

其中 data 是必须的 field,表示消息的主要文本内容;event 是可选的,表示事件的名称;id 是可选的,表示消息编号; retry 是可选的,表示重试时间间隔,即如果浏览器在指定时间内未收到服务器的响应,它会重新发送 SSE 请求。

SSE 的 JavaScript API 也非常简单,演示代码如下所示:

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

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

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

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

当浏览器向 EventSource 订阅一个 SSE 事件源时,可以注册 onopenonmessageonerror 三个事件。当连接建立成功时,onopen 事件会被调用;当收到服务器推送的消息时,onmessage 事件会被调用,并且 event.data 包含了消息的内容;当连接出现错误时,onerror 事件会被调用。

SSE 实现实时聊天的最佳实践

SSE 实时聊天的基本流程如下:

  1. 客户端向服务器发送 SSE 请求;
  2. 服务器监听客户端的 SSE 请求,并向其推送数据;
  3. 客户端通过 JavaScript API 监听服务器推送的消息,并在收到消息时更新 UI。

针对该流程,下面将介绍 SSE 实时聊天的最佳实践。

服务器端实现

为了方便起见,本文以 Node.js + Express 作为后端示例示例,实时聊天使用 Socket.io 实现。

首先,在服务器端建立一个 SSE 路由,处理客户端的 SSE 请求:

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

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

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

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

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

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

上述代码通过 sse 库创建了一个 SSE 路由,并在其 sse 路由上监听客户端的 SSE 请求。当有新的连接请求时,创建一个 EventSource 对象,并通过 send 方法向客户端推送第一条消息,接着通过 setInterval 持续向客户端推送消息。服务器通过定时器模拟发送多条聊天消息。

Socket.io 用于处理客户端与服务器之间的实时通信,需要在 sseRouter 路由中引入 Socket.io 并添加必要的监听器:

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

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

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

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

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

上述代码创建了 Socket.io 服务器,并将其添加到 SSE 路由中。当客户端连接上 Socket.io 服务器时(实际上已经在 SSE 路由中建立 SSE 连接),服务器会监听客户端发送的 message 事件,用于处理客户端发送的聊天消息。当服务器收到聊天消息后,调用 io.emit 方法广播消息,将消息发送给所有已连接的客户端。

到此为止,服务器端的实现就完成了。

客户端实现

接下来,针对上面服务器端的示例代码,介绍客户端的实现。HTML 结构如下:

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

上述代码包含了一个用于显示时间的 div 元素,一个用于显示聊天消息的 ul 元素和一个输入框和按钮,用于发送聊天消息。

下面是用于与 SSE 服务器建立连接的 JavaScript 代码:

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

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

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

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

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

上述代码通过 new EventSource('/sse') 建立了与服务器的 SSE 连接,并注册 onopenonmessageonerror 三个事件, 最关键的是处理来自服务器的消息。当接收到消息时,客户端会根据消息类型,更新 UI 的不同组件。

最后,是处理用户发送聊天消息的 JavaScript 代码:

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

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

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

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

上述代码通过获取 forminput 元素,监听表单提交事件,然后发送用户输入的聊天消息给 Socket.io 服务器;当收到服务器广播的聊天消息时,将其添加到 UI 中。

到此为止,前端部分的 SSE 实时聊天的最佳实践已经介绍完毕,完整的服务器和客户端代码请见示例代码。

总结

本文详细地介绍了利用 SSE 实现实时聊天的最佳实践,并附带示例代码和详细的指导意义。SSE 技术具有传输效率高、反应速度快、易于实现等优点,在实现实时通讯等场景中有着广泛的应用。希望通过本文,读者可以更好地理解 SSE 技术,并能够掌握 SSE 的基本原理和应用技巧。

来源:JavaScript中文网 ,转载请联系管理员! 本文地址:https://www.javascriptcn.com/post/65364a007d4982a6ebe4b835


猜你喜欢

  • PWA 开发中使用 Redux 进行状态管理的最佳实践

    在现代的 Web 应用中,状态管理是一项很重要的任务,它可以让我们实现更好的用户体验和功能。在开发 PWA (Progressive Web App) 的过程中,我们需要对应用程序状态进行管理,以便在...

    1 年前
  • Redis 的数据持久化问题解析

    Redis 的数据持久化问题解析 Redis 是一款使用内存作为数据存储的 NoSQL 数据库,相对于传统的磁盘存储方式,Redis 提供了更高的访问速度和更低的延迟。

    1 年前
  • 使用 Enzyme 测试 React 组件中的多个事件

    Enzyme 是 React 的一款测试工具,它可以方便地模拟组件的渲染过程,以便我们进行有效的测试。本文将介绍如何使用 Enzyme 来测试 React 组件中的多个事件,包括事件绑定、触发、数据验...

    1 年前
  • 如何使用 CSS Grid 实现卡片堆叠布局

    什么是卡片堆叠布局 卡片堆叠布局是一种常见的 UI 设计方式,通常用于轮播图、新闻列表等场景中。它的主要特点是一次只显示一张卡片,以层叠的方式展示。当用户进行操作(如翻页)时,当前卡片消失,下一张卡片...

    1 年前
  • Web Components 与 Webpack 整合的最佳实践解读

    前言 Web Components 是一种新型的前端技术,它可以让我们方便地创建可复用的自定义 HTML 元素。然而,由于 Web Components 的标准尚未被所有主流浏览器广泛支持,我们需要使...

    1 年前
  • 如何使用 SASS 实现雪碧图

    如何使用 SASS 实现雪碧图 随着 Web 前端的快速发展,Web 页面的复杂度也在不断提高。为了提高页面的速度和加载效率,我们通常需要将多张小图标合并成一张大图,这就是雪碧图(Sprite)。

    1 年前
  • 如何在 TypeScript 中使用 React

    React 是一个流行的用于构建用户界面的 JavaScript 库。TypeScript 是一种强类型的 JavaScript 超集语言,它增加了类型检查和静态类型分析的优势。

    1 年前
  • 使用 Node.js 发送 HTTP 请求时遇到的问题及解决方式

    前言 在前端开发中,发送 HTTP 请求是非常常见的需求。Node.js 提供了方便的 HTTP 模块,使我们可以在前端代码中发送 HTTP 请求。本文将介绍在使用 Node.js 发送 HTTP 请...

    1 年前
  • 如何在 React Native 中使用 Tailwind CSS?

    在现代的前端开发中,UI库和样式的库很受欢迎。Tailwind CSS 是一款快速开发实用且自定义程度极高的CSS框架,可以帮助开发者在几乎没有CSS代码的情况下快速搭建出漂亮的界面。

    1 年前
  • 在 Chai 和 Supertest 中使用 expect 和 should 断言库的比较与分析

    在前端开发中,测试是一门不可或缺的技术。而在测试中,使用断言库则是一种非常常见的方法,它可以帮助开发者更加方便地进行测试。 在 Node.js 中,有两个非常流行的断言库分别是 Chai 和 Supe...

    1 年前
  • ES12 之平时我们都用得多的 Object.keys()、Object.values() 与 Object.entries() 详解

    ES12(ECMAScript 2021)是 JavaScript 的最新标准,它为开发者提供了更多方便快捷的 API 和语言特性。其中,Object.keys()、Object.values() 与...

    1 年前
  • Jest 在使用 Mock 函数时遇到的对象调用失败问题解决方法

    前端开发中,我们经常使用 Jest 进行单元测试。而在单元测试中使用 Mock 函数是非常常见的技巧。但是,当我们使用 Mock 函数时,有时会遇到对象调用失败的问题,导致我们的测试用例无法运行。

    1 年前
  • Angular 表格控件的实现指南

    随着 Angular 在前端开发中的广泛应用,表格控件也成为了一种常见的需求。在 Angular 中,我们可以通过自定义组件来实现一个灵活可扩展的表格控件,本篇文章将为大家介绍如何实现一个 Angul...

    1 年前
  • 如何使用 Promise 实现动态加载模块以及异步路由?

    在前端开发中,我们常常需要动态加载一些模块或者按需加载路由组件。这样可以减少初始加载的时间和流量,提高网站的性能。而 Promise 就是一个非常好的工具来帮助我们实现这个功能。

    1 年前
  • 高性能 JavaScript 编程实践技巧

    在前端开发中,JavaScript 扮演了至关重要的角色,它不仅仅用于实现各种动态交互效果,更是现代 Web 应用程序的核心语言。在实际开发中,我们往往需要面对大量数据处理、复杂的业务逻辑以及用户体验...

    1 年前
  • 使用 ARIA 属性实现验证、可访问性和可用性:无障碍 Web 表单设计

    在今天的数字时代,Web 表单已经成为了我们生活中不可或缺的一部分。但是对于部分残障人士来说,如视力障碍者、听力障碍者、肢体残疾者等,使用 Web 表单可能会面临一些困难。

    1 年前
  • Sequelize 如何使用数据验证

    Sequelize 是一个 Node.js 的 ORM(Object-Relational Mapping),可以很方便地使用 JavaScript 的方式操作数据库。

    1 年前
  • 使用 Kubernetes 部署 Docker 应用的前置条件

    本文将介绍使用 Kubernetes 部署 Docker 应用的前置条件,包括安装 Docker、安装 Kubernetes、创建 Docker 镜像等方面的内容。

    1 年前
  • ES10 中的 ArrayBuffer 对象和各种 TypedArray 的运用

    在 ES10 中,JavaScript 引入了 ArrayBuffer 对象和各种 TypedArray 类型的数据格式,这些新的数据类型给前端开发带来了更强大的数据存储和处理能力。

    1 年前
  • Next.js 框架中生成静态站点的方法与技巧

    随着前端技术的不断发展,构建静态站点的需求也越来越多。Next.js 框架提供了一种简单而强大的方法来生成静态网站,本文将介绍 Next.js 框架中生成静态站点的方法与技巧,并提供示例代码。

    1 年前

相关推荐

    暂无文章