七叶笔记 » golang编程 » WebSoket、RTMP、Netty、即时通讯(万字)

WebSoket、RTMP、Netty、即时通讯(万字)

# WebSoket、RTMP、Netty、即时通讯

## 目录结构

一、WebSocket基础知识 – 参考附录1.2

1. 单工、半双工、双工概念

2. HTTP协议的工作模式

3. TCP三次握手四次挥手

4. WebSocket:WebSocket和HTTP什么关系?

5. 什么是长连接

6. 长连接和短连接的优点和缺点

7. TCP与UDP优缺点

二、RMTP基础知识 – 参考附录3.4

1. 什么是RTMP协议

2. RTMP协议种类

3. RTMP应用场景

三、高性能网络框架Netty – 参考附录5.6

1. Netty概述

2. 为什么使用Netty

3. Netty的架构设计

4. Netty的高性能设计

5. Netty的核心组件

6. Netty的应用场景

四、即时通讯IM框架

1. Centrifugo

2. goim

## 一、WebSocket基础知识 – 参考附录1.2

### 1. SOCKET原理

Socket大致是指在端到端的一个连接中,这两个端叫做Socket。

HTTP是基于传输层的TCP协议的,而Socket API也是,所以只是从使用上说,可以认为Socket和HTTP类似(HTTP是成文的互联网协议,Socket是一直沿用的一种编程概念),是对于传输层协议的另一种直接使用。

#### 1.1 套接字(socket)概念

套接字(socket)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。它是网络通信过程中端点的抽象表示, 包含进行网络通信必须的五种信息:

1. 连接使用的协议,

2. 本地主机的IP地址,

3. 本地进程的协议端口,

4. 远地主机的IP地址,

5. 远地进程的协议端口

应用层通过传输层进行数据通信时,TCP会遇到同时为多个应用程序进程提供并发服务的问题。多个TCP连接或多个应用程序进程可能需要通过同一个 TCP协议端口传输数据。 为了区别不同的应用程序进程和连接,许多计算机操作系统为应用程序与TCP/IP协议交互提供了套接字(Socket)接口。应用层可以和传输层通过Socket接口,区分来自不同应用程序进程或网络连接的通信,实现数据传输的并发服务。

#### 1.2 建立socket连接

建立Socket连接至少需要一对套接字,其中一个运行于客户端,称为ClientSocket ,另一个运行于服务器端,称为ServerSocket 。

套接字之间的连接过程分为三个步骤:服务器监听,客户端请求,连接确认。

1. 服务器监听:服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态,等待客户端的连接请求。

2. 客户端请求:指客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。

3. 连接确认:当服务器端套接字监听到或者说接收到客户端套接字的连接请求时,就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户 端,一旦客户端确认了此描述,双方就正式建立连接。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。

注意,Socket并不是一种协议,更多的是为了方便开发者提供友好的编程方式。Socket通过门面模式实现了对TCP/IP的封装,它实际对上层提供了一系列的接口,以方便我们在自己的应用中操作,而不必理会复杂的TCP/IP处理。这一网络层次属于数据传输层。

### 2. 单工、半双工、双工概念

1. 单工:数据传输只允许在一个方向上的传输,只能一方来发送数据,另一方来接收数据并发送。例如:发电报

2. 半双工:数据传输允许两个方向上的传输,但是同一时间内,只可以有一方发送或接受消息。例如:对讲机

3. 双工:同时可进行双向传输。例如打电话

单工、半双工和全双工 这三者都是建立在 TCP协议(传输层上)的概念,不要与应用层进行混淆。

### 3. HTTP协议的工作模式

1. http1.0:单工。因为是短连接,客户端发起请求之后,服务端处理完请求并收到客户端的响应后即断开连接。

2. http1.1:半双工。默认开启长连接keep-alive,开启一个连接可发送多个请求。

3. http2.0:全双工,允许服务端主动向客户端发送数据。

### 4. TCP三次握手四次挥手

### 5. WebSocket:WebSocket和HTTP什么关系?

1. WebSocket的特点

  • 1. 支持浏览器/Nodejs环境
  • 2. 支持双向通信
  • 3. API简单易用
  • 4. 支持二进制传输
  • 5. 减少传输数据量

2. WebSocket和http一样,都是处于OSI模型中的最高层:应用层。

2. WebSocket借助http协议进行握手,三次握手成功后,就会变身为TCP通道,从此与http不再相见。

3. WebSocket是一种在单个TCP连接上进行全双工通信的协议。在WebSocket API中,浏览器和服务器只需要完成一次握手(不是指建立TCP连接的那个三次握手,是指在建立TCP连接后传输一次握手数据),两者之间就直接可以创建持久性的连接,并进行双向数据传输。

4. 握手过程:

  • 1. 浏览器、服务器建立TCP连接,三次握手。这是通信的基础,传输控制层,若失败后续都不执行。
  • 2. TCP连接成功后,浏览器通过HTTP协议向服务器传送WebSocket支持的版本号等信息。(开始前的HTTP握手)
  • 3. 服务器收到客户端的握手请求后,同样采用HTTP协议回馈数据。
  • 4. 当收到了连接成功的消息后,通过TCP通道进行传输通信。
  • 5. Websocket默认使用请求协议为:ws://,默认端口:80。对TLS加密请求协议为:wss://,端口:443。

### 6. 什么是长连接

1. HTTP1.1规定了默认保持长连接(HTTP persistent connection ,也有翻译为持久连接),数据传输完成了保持TCP连接不断开(不发RST包、不四次握手),等待在同域名下继续用这个通道传输数据;相反的就是短连接。

2. HTTP协议与TCP/IP协议的关系

1. HTTP的长连接和短连接本质上是TCP长连接和短连接。HTTP属于应用层协议,在传输层使用TCP协议,在网络层使用IP协议。 IP协议主要解决网络路由和寻址问题,TCP协议主要解决如何在IP层之上可靠地传递数据包,使得网络上接收端收到发送端所发出的所有包,并且顺序与发送顺序一致。TCP协议是可靠的、面向连接的。

3. TCP长连接

  • 1. 长连接是指的TCP连接,而不是HTTP连接
  • 2. 长连接意味着连接会被复用
  • 3. 服务器和客户端都设置 Connection: keep-alive
  • 4. 现在基本用的HTTP1.1协议,HTTP1.1默认长连接

4. TCP短连接

  • 1. 指通信双方有数据交互时,建立一个TCP连接,数据发送完成之后,则断开此连接。 连接过程: 建立连接——数据传输——断开连接——…——建立连接——数据传输——断开连接
  • 2. 目前 http 协议普遍使用的是 1.1 版本, 之前有个 1.0 版本,两者之间的一个区别是 1.1 支持 http 长连接
  • 3. http1.0 不支持 http 长连接, 每次一个 http请求响应后都关闭 tcp 连接, 下个 http 请求会重新建立 tcp 连接.

### 7. 长连接和短连接的优点和缺点

#### 7.1 长连接的优点

1. 优点

1. 长连接可以省去较多的TCP建立和关闭的操作,减少浪费,节约时间

2. 缺点

1. 存活功能的探测周期太长

2. 连接过多问题

#### 7.2 短连接的优点和缺点

1. 优点

1. 短连接对于服务器来说较为简单,存在的连接都是有用的连接,不需要额外的控制

2. 缺点

1. TCP的建立和关闭操作上浪费时间和带宽

### 8. TCP与UDP优缺点

1. udp:面向无连接的通信协议,数据包括目的端口信息和源端口信息

1. 优点:面向无连接,操作简单,要求系统资源较少,速度快,由于不需要连接,可进行广播发送

2. 缺点:发送数据之前不需要与对方建立连接,接收到数据时也不需要发送确认信号,发送端不知道接收端是否正确接接收,不会重发,不可靠。

2. tcp:面向连接的通讯协议,通过三次握手建立连接,通讯完成时四次挥手断开连接

1. 优点:在数据传输时,有确认、窗口、重传、拥塞控制机制,能保证数据正确性,较为可靠

2. 缺点:速度相对慢一点,要求系统资源较多

### 9. HTTP与TCP的区别和联系

#### 9.1 TCP连接

1. 建立起一个TCP连接需要经过“三次握手”:

1. 第一次握手:客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;

2. 第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;

3. 第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。

2. 握手过程中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据。理想状态下,TCP连接一旦建立,在通信双方中的任何一方主动关闭连 接之前,TCP 连接都将被一直保持下去。断开连接时服务器和客户端均可以主动发起断开TCP连接的请求,断开过程需要经过“四次握手”(过程就不细写 了,就是服务器和客户端交互,最终确定断开)

#### 9.2 HTTP连接

1. HTTP协议即超文本传送协议(Hypertext Transfer Protocol ),是Web联网的基础,也是手机联网常用的协议之一,HTTP协议是建立在TCP协议之上的一种应用。

2. HTTP连接最显著的特点是客户端发送的每次请求都需要服务器回送响应,在请求结束后,会主动释放连接。从建立连接到关闭连接的过程称为“一次连接”。

  • 1. 在HTTP 1.0中,客户端的每次请求都要求建立一次单独的连接,在处理完本次请求后,就自动释放连接。
  • 2. 在HTTP 1.1中则可以在一次连接中处理多个请求,并且多个请求可以重叠进行,不需要等待一个请求结束后再发送下一个请求。

3. 由于HTTP在每次请求结束后都会主动释放连接,因此HTTP连接是一种“短连接”,要保持客户端程序的在线状态,需要不断地向服务器发起连接请求。通常的 做法是即时不需要获得任何数据,客户端也保持每隔一段固定的时间向服务器发送一次“保持连接”的请求,服务器在收到该请求后对客户端进行回复,表明知道客 户端“在线”。若服务器长时间无法收到客户端的请求,则认为客户端“下线”,若客户端长时间无法收到服务器的回复,则认为网络已经断开。

  • 1. TCP是底层通讯协议,定义的是数据传输和连接方式的规范
  • 2. HTTP是应用层协议,定义的是传输数据的内容的规范
  • 3. HTTP协议中的数据是利用TCP协议传输的,所以支持HTTP也就一定支持TCP
  • 4. HTTP支持的是www服务 ;
  • 5. 而TCP/IP是协议是Internet国际互联网络的基础。TCP/IP是网络中使用的基本的通信协议。

### 10. websocket具体使用 – 参考附录2

## 二、RMTP基础知识 – 参考附录3.4

### 1. 什么是RTMP协议

RTMP协议是Real Time Message Protocol(实时信息传输协议)的缩写,它是由Adobe公司提出的⼀种应⽤层的协议,⽤来解决多媒体数据传输流的多路复⽤(Multiplexing)和分包(packetizing)的问题。随着VR技术的发展,视频直播等领域逐渐活跃起来,RTMP作为业内⼴泛使⽤的协议也重新被相关开发者重视起来。

RTMP协议是应⽤层协议,是要靠底层可靠的传输层协议(通常是TCP)来保证信息传输的可靠性的。在基于传输层协议的链接建⽴完成后,RTMP协议也要客户端和服务器通过“握⼿”来建⽴基于传输层链接之上的RTMP Connection链接,在Connection链接上会传输⼀些控制信息,如SetChunkSize,SetACKWindowSize。其中CreateStream命令会创建⼀个Stream链接,⽤于传输具体的⾳视频数据和控制这些信息传输的命令信息。RTMP协议传输时会对数据做⾃⼰的格式化,这种格式的消息我们称之为RTMP Message,⽽实际传输的时候为了更好地实现多路复⽤、分包和信息的公平性,发送端会把Message划分为带有Message ID的Chunk,每个Chunk可能是⼀个单独的Message,也可能是Message的⼀部分,在接收端会根据chunk中包含的data的⻓度,message id和message的⻓度把chunk还原成完整的Message,从⽽实现信息的收发。

### 2. RTMP协议种类

RTMP协议就像一个用来装数据包的容器,这些数据既可以是AMF格式的数据,也可以是FLV中的视/音频数据。

  • 1. RTMP工作在TCP之上,默认使用端口1935;
  • 2. RTMPE在RTMP的基础上增加了加密功能;
  • 3. RTMPT封装在HTTP请求之上,可穿透防火墙;
  • 4. RTMPS类似RTMPT,增加了TLS/SSL的安全功能;

一个单一的连接可以通过不同的通道传输多路网络流.这些通道中的包都是按照固定大小的包传输的。

### 3. RTMP应用场景

1. 主播PK

2. 直播带货

3. 多人相亲

4. 在线合唱

5. 在线教育

## 三、高性能网络框架Netty – 参考附录5.6

### 一、Netty概述

Netty是一个高性能、异步事件驱动的NIO框架,它提供了对TCP、UDP和文件传输的支持。作为当前最流行的NIO框架,Netty在互联网领域、大数据分布式计算领域、游戏行业、通信行业等获得了广泛的应用,一些业界著名的开源组件也基于Netty的NIO框架构建(文章尾有详细介绍)。

### 二、为什么使用Netty

1. JDK原生NIO缺点

  • 1. NIO 的类库和 API 繁杂,使用麻烦:你需要熟练掌握 Selector、ServerSocketChannel、SocketChannel、ByteBuffer 等。
  • 2. 需要具备其他的额外技能做铺垫:例如熟悉 Java 多线程编程,因为 NIO 编程涉及到 Reactor 模式,你必须对多线程和网路编程非常熟悉,才能编写出高质量的 NIO 程序。
  • 3. 可靠性能力补齐,开发工作量和难度都非常大:例如客户端面临断连重连、网络闪断、半包读写、失败缓存、网络拥塞和异常码流的处理等等。NIO 编程的特点是功能开发相对容易,但是可靠性能力补齐工作量和难度都非常大。
  • 4. JDK NIO 的 Bug:例如臭名昭著的 Epoll Bug,它会导致 Selector 空轮询,最终导致 CPU 100%。官方声称在 JDK 1.6 版本的 update 18 修复了该问题,但是直到 JDK 1.7 版本该问题仍旧存在,只不过该 Bug 发生概率降低了一些而已,它并没有被根本解决。

2. Netty框架的优点

  • 1. API使用简单,开发门槛低;
  • 2. 功能强大,预置了多种编解码功能,支持多种主流协议;
  • 3. 定制能力强,可以通过ChannelHandler对通信框架进行灵活地扩展;
  • 4. 性能高,通过与其他业界主流的NIO框架对比,Netty的综合性能最优;
  • 5. 成熟、稳定,Netty修复了已经发现的所有JDK NIO BUG,业务开发人员不需要再为NIO的BUG而烦恼;
  • 6. 社区活跃,版本迭代周期短,发现的BUG可以被及时修复,同时,更多的新功能会加入;
  • 7. 经历了大规模的商业应用考验,质量得到验证。在互联网、大数据、网络游戏、企业应用、电信软件等众多行业得到成功商用,证明了它已经完全能够满足不同行业的商业应用了。

### 三、Netty的架构设计

1. 传输服务:支持 BIO 和 NIO;

2. 容器集成:支持 OSGI、JBossMC、Spring、Guice 容器;

3. 协议支持:HTTP、Protobuf、二进制、文本、WebSocket 等一系列常见协议都支持。还支持通过实行编码解码逻辑来实现自定义协议;

4. Core 核心:可扩展事件模型、通用通信 API、支持零拷贝的 ByteBuf 缓冲对象。

### 四、Netty的高性能设计

1. 高性能的三大要素

  • 1. 传输:用什么样的通道将数据发送给对方,BIO、NIO或者AIO,IO模型在很大程度上决定了框架的性能。
  • 2. 协议:采用什么样的通信协议,HTTP或者内部私有协议。协议的选择不同,性能模型也不同。相比于公有协议,内部私有协议的性能通常可以被设计的更优。
  • 3. 线程:数据报如何读取?读取之后的编解码在哪个线程进行,编解码后的消息如何派发,Reactor线程模型的不同,对性能的影响也非常大。

2. IO模型

1. Netty的I/O模型基于非阻塞I/O实现,底层依赖的是JDK NIO框架的Selector。

3. Reactor线程模型

### 五、Netty的核心组件

  • 1. Bootstrap or ServerBootstrap
  • 2. EventLoop
  • 3. EventLoopGroup
  • 4. ChannelPipeline
  • 5. Channel
  • 6. Future or ChannelFuture
  • 7. ChannelInitializer
  • 8. ChannelHandler

1.Bootstrap

一个Netty应用通常由一个Bootstrap开始,它主要作用是配置整个Netty程序,串联起各个组件。

Handler,为了支持各种协议和处理数据的方式,便诞生了Handler组件。Handler主要用来处理各种事件,这里的事件很广泛,比如可以是连接、数据接收、异常、数据转换等。

2.ChannelInboundHandler

一个最常用的Handler。这个Handler的作用就是处理接收到数据时的事件,也就是说,我们的业务逻辑一般就是写在这个Handler里面的,ChannelInboundHandler就是用来处理我们的核心业务逻辑。

3.ChannelInitializer

当一个链接建立时,我们需要知道怎么来接收或者发送数据,当然,我们有各种各样的Handler实现来处理它,那么ChannelInitializer便是用来配置这些Handler,它会提供一个ChannelPipeline,并把Handler加入到ChannelPipeline。

4.ChannelPipeline

一个Netty应用基于ChannelPipeline机制,这种机制需要依赖于EventLoop和EventLoopGroup,因为它们三个都和事件或者事件处理相关。

EventLoops的目的是为Channel处理IO操作,一个EventLoop可以为多个Channel服务。

EventLoopGroup会包含多个EventLoop。

5.Channel

代表了一个Socket链接,或者其它和IO操作相关的组件,它和EventLoop一起用来参与IO处理。

6.Future

在Netty中所有的IO操作都是异步的,因此,你不能立刻得知消息是否被正确处理,但是我们可以过一会等它执行完成或者直接注册一个监听,具体的实现就是通过Future和ChannelFutures,他们可以注册一个监听,当操作执行成功或失败时监听会自动触发。

总之,所有的操作都会返回一个ChannelFuture。

### 六、Netty的应用场景

1.互联网行业

在分布式系统中,各个节点之间需要远程服务调用,高性能的RPC框架必不可少,Netty作为异步高新能的通信框架,往往作为基础通信组件被这些RPC框架使用。

典型的应用有:阿里分布式服务框架Dubbo的RPC框架使用Dubbo协议进行节点间通信,Dubbo协议默认使用Netty作为基础通信组件,用于实现各进程节点之间的内部通信。

除了 Dubbo 之外,淘宝的消息中间件 RocketMQ 的消息生产者和消息消费者之间,也采用 Netty 进行高性能、异步通信。

2.游戏行业

无论是手游服务端还是大型的网络游戏,Java语言得到了越来越广泛的应用。Netty作为高性能的基础通信组件,它本身提供了TCP/UDP和HTTP协议栈。

非常方便定制和开发私有协议栈,账号登录服务器,地图服务器之间可以方便的通过Netty进行高性能的通信

3.大数据领域

经典的Hadoop的高性能通信和序列化组件Avro的RPC框架,默认采用Netty进行跨界点通信,它的Netty Service基于Netty框架二次封装实现。

## 四、即时通讯IM框架

### 一、Centrifugo

1. Centrifugo 是一个用 Golang 实现的基于 Websocket 或者 SockJS 的实时通信平台。

提供基于频道的发布/订阅(PUB/SUB)模式。

  • 1. 容易和现有系统集成– 不改变已有后端情况下为系统提供实时通信能力。
  • 2. HTTP API 和已有后端通信 . API clients for Python, Ruby, PHP, Go, NodeJS。
  • 3. 浏览器可以通过SockJS或者纯粹Websocket协议和centrifugal通信。 提供 iOS和Android平台SDK。
  • 4. 采用Redis实现分布式部署,也支持使用Memory引擎单机简单部署。
  • 5. SHA-256 HMAC连接认证和隐私保护。
  • 6. 多种类型的频道 – 私有, 用户限制,客户端限制。
  • 7. 通过名字空间灵活配置频道。
  • 8. 支持即时消息和历史消息。
  • 9. 支持用户加入/离开消息。
  • 10. 网络重连后可以恢复消息。
  • 11. 内置管理界面,提供多种计量(Metrics)。
  • 12. 可用于WebRTC信令服务器。
  • 13. 多种部署手段(docker 镜像, RPM/DEB 包, Nginx 配置, TLS certificates)。
  • 14. MIT license。

### 二、goim

goim 是一个支持集群的im及实时推送服务(支持websocket,http和tcp协议)

  • 1. 轻量级
  • 2. 高性能
  • 3. 纯Golang实现
  • 4. 支持单个、多个以及广播消息推送
  • 5. 支持单个Key多个订阅者(可限制订阅者最大人数)
  • 6. 心跳支持(应用心跳和tcp、keepalive、http log pulling)
  • 7. 支持安全验证(未授权用户不能订阅)
  • 8. 多协议支持(websocket,tcp,http)
  • 9. 可拓扑的架构(job、logic模块可动态无限扩展)
  • 10. 基于Kafka做异步消息推送

## 参考资料

– 附录1:[WebSocket能干些啥?](

– 附录2:[精读Websocket原理大全需知,以及具体使用(ws+socket.io)](

– 附录3:[超详细RTMP协议详解(资深流媒体架构师推荐)](

– 附录4:[直播中不可缺少的一环-rtmp直播推流](

– 附录5:[超详细Netty入门,看这篇就够了](

– 附录6:[高并发架构系列:Netty的实现原理、特点与优势、以及适用场景](

– 附录7:[互联网码农必备技能,Netty前奏篇,简单易懂的零拷贝技术](

相关文章