WebSocket WebRTC Scoket的理解
一直搞不明白Socket
、WebSocket
、WebRTC
的关系,最近有时间,就来研究一下。
HTTP
HTTP1.O 和 HTTP1.1
开发中,最常用的协议就是HTTP
,HTTP
是应用层中的协议,基于TCP
来实现传输数据。客户端请求一次数据会通过TCP
的三次握手建立连接,连接建立以后,服务器发送数据到客户端,之后断开连接,如此循环。这就造成了一些性能和资源的浪费。例如,一个包含许多图像网页文件中并没有包含真正的图像数据,只是指明了图像的URL地址,客户端需要建立好多连接来请求图片信息,这样会非常的耗时以及浪费资源。所以在Http1.1
时,添加了支持持久连接的特性,在一个TCP
连接上可以发送多个请求和响应,减少了建立和关闭连接的消耗和延迟。
Polling
但是HTTP
还有一个缺点,就是只能客户端主动去拉取数据,假如服务端有数据想主动推给客户端,那么HTTP
则无能为力。但是可以通过Polling
轮训的方式模拟实时数据。例如,客户端可以开启定时器,每1秒发送一次HTTP
请求,如果服务端有数据则返回。这种方式下,会消耗大量的流量以及资源。是最不适合做APP端的,因为APP端的流量,电量等都是比较稀缺的资源。
Long polling
长轮训是对轮训的改进版,客户端发送HTTP
给服务器之后,如果服务器这时没有新消息,就一直等待,当有新消息的时候,才会返回给客户端。当然,某种程度上减少了流量和CPU的消耗。但是这种方式还是有一种弊端,假如服务端的数据更新很快,但是只有当客户端再次询问时才能返回。而且每次发HTTP
请求都会携带很重的数据头,有时候这些数据并不是必须的,这就造成了网络资源的浪费。
iOS
端比较常用的HTTP
协议封装框架为AFNetWorking
。
TCP 三次握手以及四次挥手
三次握手
TCP/IP
协议中,TCP
协议提供可靠的传输服务,采用三次握手建立一个连接:
- 第一次握手:建立连接时,客户端A发送SYN包(SYN=j)到服务器B,并进入SYN_SEND状态,等待服务器B确认
- 第二次握手:服务器B收到SYN包以后,必须确定客户端A的SYN(ACK=j+1),同时自己也发送一个SYN包(SYN=k),即SYN+ACK包,此时服务器B进入SYN_RECV状态
- 第三次握手:客户端A收到服务器B的SYN+ACK包,向服务器B发送确认包ACK(ACK=k+1),此包发送完毕,客户端A和服务器B进入ESTABLISHED状态,完成三次握手。
完成三次握手,客户端与服务器开始传输数据。
四次挥手
- 客户端发送一个FIN,用来关闭客户端A到服务器B的数据传输
- 服务器B收到这个FIN,它发回一个ACK,确定序号为收到的序号加1,和SYN一样
- 服务器B关闭与客户端A的连接,发送一个FIN给客户端A
- 客户端A发回ACK报文确定,并将确定序号设置为收到序号加1
WebSocket
现在急需的需求是服务端有数据能主动发送到客户端。需要一种双向通信的协议,而且不需要大量的请求头,于是,在HTML5
中发布了一种新的应用层协议WebSocket
。
WebSocket protocol是HTML5一种新协议,它实现了浏览器与服务器的全双工通信,开始的握手需要借助HTTP请求完成 –百度百科
既然WebSocket
是依赖于HTTP
的,那么,通过抓包工具来看看WebSocket
到底是如何建立连接以及通信的。
先来看一下抓取的数据包:
上图可以看出,WebSocket
建立连接的过程为:通过TCP
的三次握手建立HTTP
连接->HTTP
携带标识WebSocket
的请求头字段去请求服务器建立WebSocket
连接->服务器返回数据,建立连接成功。
客户端请求头:
|
可以看到,HTTP
请求头中多了标识WebSocket
的字段。Sec-WebSocket-Key
是客户端使用Base64编码的密文,要求服务端必须返回一个对应加密的Sec-WebSocket-Accept
应答,否则客户端会校验错误,并关闭连接。Upgrade
标识客户端需要的是WebSocket
协议进行通信。
服务端响应头:
|
Sec-WebSocket-Accept
的值是服务端采用和客户端一致的秘钥计算出来后返回给客户端的,HTTP/1.1 101 Switching Protocols
表示服务器接受WebSocket
协议的客户端连接,经过这样的请求-响应处理后,客户端服务端的WebSocket
连接握手成功,之后通过TCP
连接,客户端和服务端都能主动向对方推送数据。
iOS
端常用的WebSocket
协议封装框架为SocketRocket
,它是基于NSInputStream
、NSOutputStream
进行数据传输。
Socket
首先,Socket
其实并不是一个协议,它工作在OSI
模型会话层,是为了方便大家直接使用更底层协议(一般是TCP
或UDP
)而存在的一个抽象层。Socket
是对TCP/IP
协议的封装,Socket
本身并不是协议,而是一个调用接口。
Socket
通常也称作套接字,用于描述IP
地址和端口,是一个通信链的句柄。网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个Socket
,一个Socket
由一个IP
地址和一个端口号唯一确定。应用程序通常通过套接字向网络发生请求或者应答网络请求。
WebRTC
WebRTC
名称源自网页实时通信(Web Real-Time Communication)的缩写,简而言之它是一个支持网页浏览器进行实时语音对话或视频对话的技术。
传统的客户端与客户端进行通信是这样的:首先需要客户端A和服务器,客户端B和服务器建立信道,A给B发送消息时,A先将消息发送到服务器上,服务器对A的消息进行中转,发送到B处,反过来也是一样。这样A和B之间的一次消息要通过两段信道,通信的效率同时受制于这两段信道的带宽,那为什么不让A和B直接通信呢?WebRTC
应运而生。WebRTC
是一种点对点技术,通过已系列的信令,在客户端A和客户端B之间建立一个信道,这样客户端A和客户端B就可以直接发送数据而不经过服务器。WebRTC
为我们提供了视频会议的核心技术,包括音视频的采集、编解码、网络传输、显示等功能,并且还支持跨平台:Windows、Linux、Mac、android、iOS。
WebRTC的服务与信令
首先要明确一点,WebRTC
虽然是基于P2P的音视频通信技术,但是,WebRTC
仍然需要服务器来进行信令的中转,只是音视频数据不再通过服务器中转。
另外,由于WebRTC
主要用来解决实时通信的问题,可靠性并不是很重要,因此,WebRTC
使用UDP
作为传输层协议。当然,WebRTC
还需要解决NAT
的问题。关于WebRTC
更详细的资料,有兴趣的可以查询相关文档。