WebSocket

计算机网络体系结构
- 应用层
- 任务: 通过应用进程间的交互来完成特定网络应用;
- 应用层协议定义的是应用进程间通信和交互的规则;
- 应用层交互的数据单元称为报文;
- 对于不同的网络应用需要有不同的应用层协议;
- 支持万维网应用的
HTTP协议 - 支持电子邮件的
SMTP协议 - 支持文件传送的
FTP协议
- 支持万维网应用的
- 运输层
- 任务: 负责向两个主机中进程之间的通信提供通用的数据传输服务;
- 应用层利用该服务传送应用层报文;
- 运输层主要使用以下两种协议
- 传输控制协议 TCP — 提供面向连接的、可靠的数据传输服务,数据传输的单位是报文段;
- 用户数据包协议 UDP — 提供无连接的、尽最大努力的数据传输服务(不保证数据传输的可靠性),其数据传输的单位是用户数据报。
- 网络层
- 任务1: 负责为分组交换网上的不同主机提供通信服务;
- 任务2: 选择合适的路由,使源主机运输层所传下来的分组能够通过网络中的路由器找到目的主机
- 因特网主要的网络层协议是无连接的网际协议
IP和许多中路由选择协议,因此因特网的网络层也叫做网际层或IP层
- 数据链路层
- 数据链路层将网络层交下来的IP数据报组装成帧,在两个相邻结点间的链路上传送。
- 每一帧包括数据和必要的控制信息(如同步信息,地址信息,差错控制等)。
- 在接收数据时,控制信息使接收端能够知道一个帧从哪个比特开始和到哪个比特结束。这样,数据链路在接收到一个帧后,就可从中提取出数据部分,上交给网络层。
- 物理层
- 在物理层上所传输的数据单位是比特。
- 物理层还要确定连接电缆的插头应当有多少根引脚以及各条引脚应如何连接。
注意:传递信息所利用的一些物理媒体,如双绞线、同轴电缆、光缆、无线信道等,并不在物理层协议之内而是在物理层协议的下面。
socket
socket是对TCP/IP协议的封装,socket本身并不是协议,而是一个调用接口, 通过socket,我们才能使用TCP/IP。socket编程接口在设计的时候,就希望也能适用于其他网络协议。所以说,socket的出现只是使得程序员更方便地使用TCP/IP协议栈而已,是对TCP/IP协议的抽象,从而形成了我们知道的一些最基本的函数接口,比如create、listen、connect、accept、send、read和write等等。
WebSocket
简介
WebSocket是一种网络传输协议,可在单个TCP连接上进行全双工通信,位于OSI模型的应用层。WebSocket允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性的连接,并进行双向数据传输。
对比 HTTP 协议
websocket是独立的、创建在TCP上的协议;websocket是一个持久化的协议;HTTP是非持久化协议;- 在
HTTP中,声明周期通过Request界定,一个Request对应一个Response,且这个Response是被动的,不能主动发起; websocket借用了HTTP协议来完成一部分握手🤝.
实时通讯
- 轮询
- 浏览器每隔一段时间向服务器发出
HTTP请求,然后服务器返回最新的数据给客户端。 - 缺点: 浏览器需要不断的向服务器发出请求,然而
HTTP请求与回复可能会包含较长的头部,其中真正有效的数据可能只是很小的一部分,所以这样会消耗很多带宽资源。
- 浏览器每隔一段时间向服务器发出
- websocket
- 能更好的节省服务器资源和带宽,并且能够更实时地进行通讯
统一资源标识符(URI)
websocket 使用 ws 或 wss 的统一资源标志符(URI)。其中 wss 表示使用了 TLS 的 websocket。
ws://example.com/wsapi
wss://secure.example.com/wsapi
默认端口
websocket与HTTP和HTTPS使用相同的TCP端口websocket协议使用80端口;- 运行在
TLS之上时,默认使用443端口。
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
服务器回应:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: chat
字段说明:
Connection必须设置Upgrade,表示客户端希望连接升级。Upgrade字段必须设置Websocket,表示希望升级到Websocket协议。Sec-WebSocket-Key是随机的字符串,服务器端会用这些数据来构造出一个SHA-1的信息摘要。把Sec-WebSocket-Key加上一个特殊字符串258EAFA5-E914-47DA-95CA-C5AB0DC85B11,然后计算SHA-1摘要,之后进行Base64编码,将结果做为Sec-WebSocket-Accept头的值,返回给客户端。如此操作,可以尽量避免普通HTTP请求被误认为Websocket协议。Sec-WebSocket-Version表示支持的Websocket版本。RFC6455要求使用的版本是13,之前草案的版本均应当弃用。Origin字段是可选的,通常用来表示在浏览器中发起此Websocket连接所在的页面,类似于Referer。但是,与Referer不同的是,Origin只包含了协议和主机名称。- 其他一些定义在
HTTP协议中的字段,如Cookie等,也可以在Websocket中使用。
SocketRocket
SocketRocket 是 facebook 推出的在 iOS 中使用 WebSocket 的库。
接口预览
@interface SRWebSocket : NSObject
// Make it with this
- (instancetype)initWithURLRequest:(NSURLRequest *)request;
// Set this before opening
@property (nonatomic, weak) id <SRWebSocketDelegate> delegate;
// Open with this
- (void)open;
// Close it with this
- (void)close;
// Send a Data
- (void)sendData:(nullable NSData *)data error:(NSError **)error;
// Send a UTF8 String
- (void)sendString:(NSString *)string error:(NSError **)error;
@end
代理回调
@protocol SRWebSocketDelegate <NSObject>
@optional
- (void)webSocketDidOpen:(SRWebSocket *)webSocket;
- (void)webSocket:(SRWebSocket *)webSocket didReceiveMessageWithString:(NSString *)string;
- (void)webSocket:(SRWebSocket *)webSocket didReceiveMessageWithData:(NSData *)data;
- (void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError *)error;
- (void)webSocket:(SRWebSocket *)webSocket didCloseWithCode:(NSInteger)code reason:(nullable NSString *)reason wasClean:(BOOL)wasClean;
@end
使用
为了方便现有项目使用,在SocketRocket基础上做了 简单封装