01.实时聊天应用简介

一灰灰blogIMIM约 3606 字大约 12 分钟

1. IM简介

1.1 什么是实时聊天应用?

实时聊天应用,又称即时通讯(Instant Messaging,简称IM),是一个允许两人或多人通过网络实时聊天应用,又称即时通讯(Instant Messaging,简称IM),是一个允许两人或多人通过网络实时传递文字消息、文件、语音与视频交流的系统。这类应用软件有两种架构形式:C/S架构和B/S架构。在C/S架构中,用户需要下载并安装客户端软件才能使用,例如微信、QQ等;而在B/S架构中,用户只需通过浏览器就可以进行聊天。

实时聊天应用具有极高的"实时性"和"可靠性",消息的传递几乎没有延迟,且不会丢失。因此,这类应用被广泛应用于各种社交互动领域,如个人通信、商务沟通、企业协作等。

1.2 实时聊天应用的应用场景

实时聊天应用的应用场景非常广泛,以下是一些常见的应用场景:

  1. 社交沟通:即时通信 IM 为应用于社交沟通提供能力支持,可实现单聊、群聊、弹幕等多种聊天模式,支持文字、图片、语音、短视频等多种消息类型。实时消息推送满足消息到达率的要求,并可与实时音视频 TRTC 共同实现实时音视频通话,有效提升用户粘性与活跃度。

  2. 在线协作和协同编辑:对于需要多用户协同工作的应用,如协同编辑文档或绘图,WebSocket 的实时性使得用户能够看到其他用户的操作。

  3. 视频会议和聊天:视频会议、聊天等高实时性的场景,都适合使用IM来做。

  4. 抽奖和互动游戏:这些需要高实时性反馈的活动,也是实时聊天应用的典型应用场景。

  5. 股票基金实时报价、体育实况更新:这些需要实时信息更新的场景,可以利用实时聊天应用的特性,快速准确地将信息传递给用户。

  6. 基于位置的应用:例如Uber、滴滴等打车软件,可以利用实时聊天应用获取司机的位置信息,提高服务的便捷性和效率。

2. WebSocket简介

2.1 什么是WebSocket

WebSocket是一种在单个TCP连接上进行全又向通信的协议。它是建立在TCP/IP协议之上,独立于HTTP协议,可以允许客户端和服务器之间进行双向通信。这种持久化的协议能够大幅度减少网络延迟和数据传输的开销,并提高资源利用率。

WebSocket的工作原理是,首先,客户端和服务端需要通过握手来建立连接。在握手成功之后,就会形成一条持久的连接通道,使得数据可以双向实时传输,一旦连接建立,服务端可以在任何时候将数据主动推送到客户端。这种方式不仅减少了频繁请求导致的网络延迟,还提高了用户体验。

此外,WebSocket还支持跨域通信,使得不同的域名、端口或协议之间的数据交换变得更容易。并且,WebSocket协议的端口是80,这使得其能够在大多数网络环境中顺利工作。

2.2 WebSocket与HTTP的区别

WebSocket和HTTP是两种完全不同的网络协议,它们在通信方式、连接方式以及应用场景上都存在显著的差异。

首先,两者的通信方式不同。WebSocket是一种双向通信协议,能够实现客户端与服务器间实时双向信息传输。这意味着,服务器可以在任何时候将数据“推送”到客户端。而HTTP协议则是单向的,信息传送总是从客户端发起,服务器对请求做出响应。

其次,两者的连接方式也有所不同。WebSocket在建立连接时,需要经历一次由服务器和客户端进行的握手过程。一旦连接建立,该连接就会持续保持,直到被明确终止。这与HTTP的无状态连接方式形成了鲜明的对比,后者的每次数据传输都需要建立新的TCP连接。

此外,WebSocket和HTTP在应用场景上也各有所长。WebSocket由于其双向通信和长连接的特性,常被用于如聊天应用、实时通知等需要频繁、实时交互的场景;而HTTP协议则更多地用在需要获取或提交资源(如网页、图片等)的信息交换中。

2.3 WebSocket协议

RFC 6455 - The WebSocket Protocolopen in new window

2.3.1 WebSocket的工作原理

WebSocket是一种在单个TCP连接上进行全双工通信的协议,它允许服务端与客户端之间进行实时数据交互,且信息传递的方式可以是服务端主动向客户端推送。这种协议是建立在TCP协议之上的,能够实现双向通讯。

WebSocket协议的工作流程包括以下几个步骤:

  1. 握手阶段:这是建立连接时的第一个阶段。客户端向服务端发送一个HTTP请求;然后,服务器在响应头中添加一些特殊的字段,表明愿意将当前的HTTP连接升级为WebSocket连接;当客户端收到这个响应后,也会在请求头中添加类似的字段,同时,客户端还会将Sec-WebSocket-Key对应的值通过SHA-1算法进行编码,将编码后的值作为Sec-WebSocket-Accept放在请求头中;最后,服务器对Sec-WebSocket-Key对应的值进行同样的SHA-1编码。

  2. 数据传输阶段:一旦连接建立,数据就可以在客户端和服务器之间双向流动。这个阶段是全双工的,意味着数据可以同时从客户端发送到服务器,也可以从服务器发送到客户端。

此外,WebSocket协议还具有以下特点:

  • 信息传输的开销较小,因为其数据帧相较于HTTP请求报文小;
  • 较低的服务器资源占用。由于WebSocket的长连接特性,服务器能处理更多的并发连接。

2.3.2 WebSocket协议的握手过程

WebSocket协议的握手过程是建立WebSocket连接前的重要步骤,主要包括以下步骤:

  1. 客户端通过TCP连接到服务器。
  2. 客户端向服务器发送HTTP/1.1协议的GET请求,这个请求通常被称为握手请求。
  3. 握手请求中包含了几个特定的头信息,这些信息用于指示客户端希望升级到WebSocket协议。具体来说,这些头信息包括:
  • Upgrade: websocket,这表示客户端希望升级到WebSocket协议。
  • Connection: Upgrade,这表示客户端希望建立持久连接。
  • Sec-WebSocket-Key: 这是一个随机的Base64编码密钥,用于安全验证。
  • Sec-WebSocket-Version: 这指示了客户端使用的WebSocket协议版本。
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: http://example.com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
  1. 一旦服务器接收到并验证了这些头信息,它就会返回一个响应给客户端。这个响应也是一个HTTP/1.1协议的响应,对应的HTTP状态码为101,此外还包含了一些特定的头信息,例如Upgrade和Connection头信息,指示连接已经升级到了WebSocket协议。同时,响应的正文中包含了由服务器生成的Base64编码的握手响应。
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: chat
Sec-WebSocket-Version: 13
  1. 一旦客户端收到服务器的响应,它就会检查响应中的头信息以及正文中的握手响应。如果一切验证无误,那么WebSocket连接就建立起来了。

对应的校验机制如下:

  • 客户端应首先检查服务端返回的状态码是否为 101, 只有在 HTTP 状态码为 101 时才代表服务端同意了协议升级, 对于其它类型的状态码, 客户端应根据 HTTP 状态码的语义做相应的处理
  • 客户端应检查服务端返回的响应是否包含 Upgrade 字段, 若缺失, 代表 Upgrade 未成功, 客户端应终止 WebSocket 握手
  • 客户端应检查 Upgrade 字段的值是否为 websocket (该字段是大小写不敏感的, 如 websocket, WebSocket, webSocket 等都是合法的), 若不是, 客户端应终止 WebSocket 握手
  • 客户端应采用如上所表述的方式校验服务端返回的 Sec-WebSocket-Accept 字段的值是否合法, 若该字段不存在或值不符合预期, 则客户端应终止 WebSocket 握手
  • 若服务端返回的 Header 中包含 Sec-WebSocket-Extensions, 但其字段的值并不在客户端最初向服务端发起握手时传递的 Sec-WebSocket-Extensions 的值列表中, 则客户端应终止 WebSocket 握手
  • 若服务端返回的 Header 中包含 Sec-WebSocket-Protocol, 但该字段的值并不在客户端最初向服务端发起握手时传递的 Sec-WebSocket-Protocol 的值列表中, 则客户端应终止 WebSocket 握手

以上就是WebSocket协议的握手过程,这个过程确保了客户端和服务器都明确彼此将使用WebSocket协议进行通信,并且已经完成了必要的安全验证。

2.3.3 WebSocket协议的消息格式

WebSocket 以 frame 为单位传输数据, frame 是客户端和服务端数据传输的最小单元, 当一条消息过长时, 通信方可以将该消息拆分成多个 frame 发送, 接收方收到以后重新拼接、解码从而还原出完整的消息, 在 WebSocket 中, frame 有多种类型, frame 的类型由 frame 头部的 Opcode 字段指示, WebSocket frame 的结构如下所示:

Frame由两部分组成:头部和数据部分。

头部是一个二进制字节流,包含以下几部分内容:

  • Fin: 这是一个1比特的标志位,用于指示当前的frame是不是消息的最后一个分段。如果一个消息被切分为多个frame进行发送,那么除了最后一个frame,其他所有frame的Fin字段都会被设置为0,而最后一个frame的Fin字段则被设置为1。当然,如果一条消息没有被切分,那么一个frame就会包含完整的消息,此时该frame的Fin字段值就为1。
  • Rsv1, Rsv2, Rsv3: 这三个标志位各占1比特,目前还没有定义具体的含义,保留给后续的应用。
  • Opcode: 这是4比特的操作码,用于指示客户端和服务器之间要执行的具体操作。比如连接建立、关闭连接、文本消息、二进制消息等。
  • Mask: 这是一个1比特的标志位,用于指示是否需要对数据进行掩码处理。如果需要掩码处理,那么在数据字段中就会出现一个4字节的掩码键。
  • Payload length: 这是16比特的长度字段,表示接下来的数据长度。因为WebSocket协议支持传输的数据长度可以是任意的,所以这个字段是必要的。
  • Masking-key: 如果Mask标志位为1,那么这个字段就会出现。它是一个4字节的字段,用于对数据进行掩码处理。

数据部分就是根据Payload length字段确定的具体数据内容。

3. 实时聊天技术方案

实时聊天的通讯协议主要有以下几种:

  1. XMPP(可扩展消息与存在协议):这是一个成熟且开源的即时聊天协议,基于XMPP的开源技术有openfire(后台端)、spark(客户端)等。它的优势在于比较成熟的聊天协议,已在XMPP协议内支持单聊、群聊、加好友等功能。

  2. WebSocket:它是一种在单个TCP连接上进行全双工通讯的协议,可以实现客户端与服务器之间的实时数据交互。

  3. MQTT(轻量级发布/订阅消息传输协议):它是一种轻量级的发布/订阅模式的消息传输协议,适用于低带宽、不稳定网络环境下的通信。

  4. CoAP(受限应用协议):它是一种专为受限设备设计的应用层协议,适用于物联网等场景。

其中WebSocket在实时聊天应用中的优势主要体现在以下几个方面:

  1. 实时性:WebSocket提供了双向通信,服务器可以主动向客户端推送数据,实现的实时性非常高,适用于实时聊天、在线协作等应用。

  2. 减少网络延迟:与轮询和长轮询相比,WebSocket可以显著减少网络延迟,因为不需要在每个请求之间建立和关闭连接。

  3. 较小的数据传输开销:WebSocket的数据帧相比于HTTP请求报文较小,减少了在每个请求中传输的开销,特别适用于需要频繁通信的应用。

  4. 较低的服务器资源占用:由于WebSocket的长连接特性,服务器可以处理更多的并发连接,相较于短连接有更低的资源占用。

  5. 跨域通信:与一些其他跨域通信方法相比,WebSocket更容易实现跨域通信。

  6. 效率和可扩展性:WebSocket技术提供了一种在各种应用程序中实现实时通信的强大高效手段,包括聊天应用程序、协作工具、实时通知和多人游戏。

接下来我们将基于WebSocket来实现一个实时聊天应用的开发搭建

Loading...