📜  Node.js 中的 Sockets.IO 简介

📅  最后修改于: 2022-05-13 01:56:43.177000             🧑  作者: Mango

Node.js 中的 Sockets.IO 简介

套接字.IO:

早些时候,网站在每次请求资源时都会重新加载。这引入了不必要的延迟,增加了平均等待时间。通常,用户必须等待几分钟才能获取特定页面或文件。另一方面,实时应用程序(即时通讯、在线游戏、推送通知等)是那些在给定时间段内运行的应用程序,以便向用户呈现资源的即时和最新副本。这些应用程序的延迟尽可能低,以提供流畅和一致的用户体验。 Socket.IO 就是这样一种 JavaScript 库,程序员在开发实时“Web 应用程序”时使用它。

为什么选择 Sockets.IO :
当今 Internet 上的大多数应用程序都是基于客户端-服务器架构的。客户端是从服务器请求某些东西的人。服务器根据请求以适当的结果进行响应。由于它们执行的任务的性质,这两个实体彼此完全不同。浏览器是客户端应用程序的完美示例。浏览器上的客户端通常通过 HTTP 请求和响应与服务器通信。这种通信的问题是一次可以发送请求或响应。为了理解,将其视为半双工链路。此外,HTTP 标头包含大量冗余信息,一旦建立客户端和服务器之间的连接,这些信息将毫无用处。另一方面,套接字工作在网络堆栈的传输层。没有太多冗余字段,因此提高了网络上信息传输的效率。

Socket.IO 的工作原理相同,并支持 Web 客户端和服务器之间的双向通信。为了分别有效地处理它们,它由两部分组成;

  • 在浏览器上运行的 JavaScript 客户端库。
  • 一个 Node.js 服务器

Socket.IO 依赖于 Engine.IO,Engine.IO 是基于传输的跨浏览器/跨设备双向通信层的实现。它为 Socket.IO 带来了以下特性;

  • 可靠性:即使存在代理、负载平衡器、个人防火墙和防病毒软件,它也可以建立连接。
  • 自动重新连接支持:除非在代码中明确提及,否则客户端库将尝试永远重新连接,直到服务器再次可用。
  • 断开连接检测:它允许服务器和客户端都知道对方何时不再响应。
  • 多路复用支持:它允许在同一个底层连接上拥有多个通信通道。
  • 二进制流支持:它还允许发出任何可序列化的二进制数据,如 ArrayBuffer、Blob 等。

安装:

    安装 Sockets.IO 所需
  • 已安装节点
  • npm(节点包管理器)已安装

如前所述,一个项目中包含两个不同的库。

  • 服务器:
    要将其安装在 Node.js 项目中,请运行以下命令,
    $ npm install --save socket.io
  • JavaScript 客户端:
    服务器默认在/socket.io/socket.io.js公开客户端的独立构建。否则,它也可以由任何 CDN 提供商提供。

    要从 Node.js 使用它,请通过以下命令安装它,

    $ npm install --save socket.io-client

例子:

这个例子是关于在 Socket.IO 中实现一个基本的 Upvote 按钮。它将显示实时服务器和客户端通信。首先,转到所需的项目目录并使用npm init命令或手动创建package.json文件对其进行初始化。

现在使用以下命令安装 express js,

$ npm install --save express@4.15.2

安装后,创建将设置应用程序的index.js文件。

这段代码的作用是为 Express 创建一个函数处理程序,然后将其提供给 HTTP 服务器。当请求/页面时,此处理程序向客户端响应“Hello World”。最后,HTTP 服务器开始监听 3000 端口。

运行它看起来像这样,

提供 HTML:
以前,只发送一个 HTML 行作为对 GET 请求的响应。这一次,使用sendFile方法附加一个 HTML 文件。

现在创建index.html文件并粘贴以下代码。



  

    SocketIO Upvote
    

  

    
           

Lorem ipsum dolor sit amet, consectetur adipiscing elit.  Aliquam sed turpis sit amet tellus convallis tincidunt quis ut massa. Phasellus maximus  orci quis mauris tincidunt, ut tempor turpis tincidunt. Curabitur vestibulum nunc consequat  venenatis ultrices. Aliquam eget congue risus, in imperdiet urna. Vestibulum varius velit   risus, non luctus arcu placerat vel. In hac habitasse platea dictumst. Pellentesque vitae  justo volutpat, euismod ligula quis, posuere nibh.

    
       
        
                         

0 Upvotes

        
    
  

重新启动项目并刷新页面,它应该看起来像这样,

集成 Socket.IO:
要安装服务器端模块,请运行以下命令,

$ npm install --save socket.io

现在对index.js进行如下更改,

额外的更改初始化了 Socket.IO 处理程序。当它发出一个“连接”信号时,一个日志记录动作被附加到这个处理程序上。

在客户端,只需要关闭标签之前的以下代码片段。这会暴露一个特定客户端使用的io全局。

从控制台再次重新启动项目并尝试在多个选项卡和浏览器上打开 localhost。它们中的每一个都将充当唯一的客户端连接。每次在客户端和服务器之间建立连接时,都会打印日志消息。

当客户端关闭或刷新选项卡时,每个套接字还会触发一个特殊的断开连接事件:

发射事件:
Socket.IO 背后的主要思想是人们可以发送和接收任何选择的事件,无论是否有任何数据。任何可以编码为 JSON 的对象都可以,并且也支持二进制数据。

假设当用户单击 upvote 按钮时,会发出一个名为upvote-event 的事件。所以在index.html文件中,插入以下脚本。

index.js中,按照代码片段记录事件数据。

结果应该是这样的,

广播:
下一个目标是从服务器向其余用户发出事件。这一次,基于点击的投票计数将被广播到连接到服务器的每个客户端。我们将此事件称为update-upvotes 。为了计算赞成票的数量,让我们创建一个变量upvote-count 。像这样更新index.js

在这里, upvote_count用零(0)初始化并根据upvote_flag的值进行更新。然后将更新的值发送给所有客户端,包括发生“更新事件”的客户端。

在客户端,像这样更新index.html

它将使用 upvote 计数的当前值更新 DOM 元素。结果看起来像这样,


要使这个示例在实际开发中健壮和可用,需要考虑很多事情。应该考虑这样一个事实,即当多个用户同时单击upvote 按钮时,此示例将遇到竞争条件问题。应该使用适当的锁定机制使其在现实世界的应用程序中工作。

获取此示例:
在 Github 上找到此示例的完整代码。

Git 仓库:

https://github.com/CherryGot/SocketIO-Upvote.git