什么是WebSocket
WebSocket 是一种在单个TCP连接上进行全双工通讯的协议,属于应用层协议。它基于TCP传输协议,并复用HTTP的握手通道。在WebSocket API中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。
WebSocket和HTTP的关系
相同点:
- 都是一样基于TCP的,都是可靠性传输协议。
- 都是应用层协议
不同点: - WebSocket是双向通信协议,http是单向的;
- WebSocket是需要浏览器和服务器握手进行建立连接的。而http是浏览器发起向服务器的连接,服务器预先并不知道这个连接。
联系: - WebSocket在建立握手时,数据是通过HTTP传输的。但是建立之后,在真正传输时候是不需要HTTP协议的。
WebSocket如何建立连接
首先,WebSocket连接必须由浏览器发起,因为请求协议是一个标准的HTTP请求,格式如下:
GET ws://localhost:3000/ws/chat HTTP/1.1
Host: example.com:8000
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
该请求和普通的HTTP请求有几点不同:
1、GET请求的地址不是类似/path/
,而是以ws://
开头的地址;
2、请求头Upgrade: websocket
和Connection: Upgrade
表示这个连接将要被转换为WebSocket
连接;
3、Sec-WebSocket-Key
是用于标识这个连接,并非用于加密数据;
4、Sec-WebSocket-Version
指定了WebSocket
的协议版本。
随后,服务器如果接受该请求,就会返回如下响应:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: chat
1、首行返回的是HTTP/1.1协议版本和状态码101,表示变换协议(Switching Protocol
)
2、Upgrade
和 Connection
:这两个字段是服务器返回的告知客户端同意使用升级并使用websocket
协议,用来完善HTTP
升级响应
3、Sec-WebSocket-Accept
:服务器端将加密处理后的握手Key通过这个字段返回给客户端表示服务器同意握手建立连接。
4、Sec-Websocket-Procotol
:服务器选择的一个应用层协议。
webSocket和Socket的关系
Socket其实并不是一个协议,而是为了方便使用TCP或UDP而抽象出来的一层,是位于应用层和传输控制层之间的一组接口。
当两台主机通信时,必须通过Socket连接,Socket则利用TCP/IP协议建立TCP连接。TCP连接则更依靠于底层的IP协议,IP协议的连接则依赖于链路层等更低层次。
WebSocket就像HTTP一样,则是一个典型的应用层协议。
总结:
Socket是传输控制层接口,WebSocket是应用层协议。
为什么需要WebSocket
因为HTTP协议有一个缺陷:通信只能由客户端发起。而WebSocket的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种。
其他特点:
- 建立在 TCP 协议之上,服务器端的实现比较容易。
- 与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。
- 数据格式比较轻量,性能开销小,通信高效。
- 可以发送文本,也可以发送二进制数据。
- 没有同源限制,客户端可以与任意服务器通信。
- 协议标识符是
ws
(如果加密,则为wss
),服务器网址就是 URL。
WebSocket客户端的API
- 1、创建WebSocket对象
var Socket = new WebSocket(url, [protocol] );
- 2、WebSocket 对象的属性
2.1Socket.readyState
只读属性readyStat
表示连接状态:
0 - 表示链接尚未建立
1 - 表示连接已建立,可以进行通信
2 - 表示连接正在进行关闭
3 - 表示连接已经关闭或者连接不能打开。
2.2Socket.bufferedAmount
只读属性bufferedAmount
,表示还有多少字节的二进制数据没有发送出去。它可以用来判断发送是否结束。 - 3、WeSocket事件
事件 | 事件处理程序 | 描述 |
---|---|---|
open | Socket.onopen | 连接建立时触发 |
message | Socket.onmessage | 客户端接收服务端数据时触发 |
error | Socket.onerror | 通信发生错误时触发 |
close | Socket.onclose | 连接关闭时触发 |
- 4、WebSocket方法
事件 | 描述 |
---|---|
Socket.send() | 使用连接发送数据 |
Socket.close() | 关闭连接 |