Commit 29b5c9ab authored by zhangfangli's avatar zhangfangli

websocket

parent a619c528
Pipeline #16582 canceled with stage
---
title: WebSocket
date: 2022/7/29 15:00:00
tags:
author: 张芳利
---
<a name="d3db997e"></a>
## 一、什么是WebSocket
- WebSocket是一种通信协议,可在单个TCP连接上进行全双工通信。WebSocket使得客户端和服务器之间的数据交<br />换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就可以建立持久性的连接,并进行双向数据传输。
1. WebSocket是一种通信协议
2. 区别于HTTP协议,HTTP协议只能实现客户端请求,服务端响应的这种单项通<br />而WebSocket可以实现客户端与服务端的双向通讯,,最大也是最明显的区别就是可以做到服务端主动将消息推送给客户端。
<a name="554bf4d4"></a>
## 二、为什么需WebSocket?
- 因为 HTTP 协议有一个缺陷:通信只能由客户端发起。
> 由于http协议只能由客户端发起通信,如果服务器有连续的状态变化,客户端要获知就非常麻烦。我们只能使用"轮询":每隔一段时候,就发出一个询问,了解服务器有没有新的信息。最典型的场景就是聊天室。Websocket在解决这样的需求上非常方便。<br />如果不使用WebSocket与服务器实时交互,一般有两种方法。AJAX轮询和Long Polling长轮询。
- 上边这两种方式都有个致命的弱点,开销太大,被动性。假设并发很高的话,这对服务端是个考验。<br />而WebSocket一次握手,持久连接,以及主动推送的特点可以解决上边的问题,又不至于损耗性能。
1. AJAX轮询
- AJAX轮询也就是定时发送请求,也就是普通的客户端与服务端通信过程,只不过是无限循环发送,这样,可以保证服务端一旦有最新消息,就可以被客户端获取。
2. Long Polling长轮询
- Long Polling长轮询是客户端和浏览器保持一个长连接,等服务端有消息返回,断开。<br />然后再重新连接,也是个循环的过程,无穷尽也。。。<br />客户端发起一个Long Polling,服务端如果没有数据要返回的话,<br />会hold住请求,等到有数据,就会返回给客户端。客户端又会再次发起一次Long Polling,再重复一次上面的过程。
<a name="bed9b70f"></a>
## 三、WebSocket特点
- 最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种。
![image.png](https://cdn.nlark.com/yuque/0/2021/png/22328960/1636711322013-09ef7bd7-f732-4195-840c-83fcbdcfc248.png#clientId=u73f4536e-0f71-4&from=paste&height=428&id=uda8cb238&margin=%5Bobject%20Object%5D&name=image.png&originHeight=428&originWidth=526&originalType=binary&ratio=1&size=63554&status=done&style=none&taskId=u4874871e-60bf-492c-87a3-4baa20ad6c6&width=526)
- 建立在 TCP 协议之上,服务器端的实现比较容易。
- 与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。
- 数据格式比较轻量,性能开销小,通信高效。
- 可以发送文本,也可以发送二进制数据。
- 没有同源限制,客户端可以与任意服务器通信。
- 协议标识符是ws(如果加密,则为wss),服务器网址就是 URL。
<a name="b15a1ba5"></a>
## ![image (2).png](https://cdn.nlark.com/yuque/0/2021/png/22328960/1636711353419-ab381e4d-8184-4922-8124-1f2d5413c719.png#clientId=u73f4536e-0f71-4&from=paste&height=312&id=u9624ffb4&margin=%5Bobject%20Object%5D&name=image%20%282%29.png&originHeight=312&originWidth=418&originalType=binary&ratio=1&size=98792&status=done&style=none&taskId=u68c59bb0-8f55-4ea3-8e63-42d7891d833&width=418)
<a name="367b4b6d"></a>
## 四、WebSocket的API
1、WebSocket构造函数: 新建WebSocket实例后,会创建客户端与服务端的WebSocket连接
```jsx
let ws = new WebSocket(url)
```
2、 WebSocket实例的当前状态:
```jsx
ws.readyState
// 0: 'CONNECTING',表示正在连接
// 1: 'OPEN', 表示连接成功,可以通信了
// 2: 'CLOSING', 表示连接正在关闭
// 3: 'CLOSED', 表示连接已经关闭,或者打开连接失败。
```
3、WebSocket实例的事件:
```jsx
ws.onopen = function () {
// 指定连接成功后的回调函数
}
ws.onclose = function () {
// 指定连接关闭后的回调函数
}
ws.onmessage = function () {
// 指定收到服务器数据后的回调函数
}
ws.onerror = function () {
// 指定报错时的回调函数
}
```
4、WebSocket实例向后台推送消息的方法:
```jsx
ws.send(message) 向服务器发送数据
ws.close() 关闭当前连接
```
<a name="502a7fcf"></a>
## 五、WebSocket的解读
1、申请一个WebSocket对象,参数是需要连接的服务器端的地址,同http协议使用http://开头一样,WebSocket协议的URL使用ws://开头,另外安全的WebSocket协议使用wss://开头。
2、WebSocket对象一共支持四个消息 onopen, onmessage, onclose和onerror,<br />所有的操作都是采用消息的方式触发的,这样就不会阻塞UI,使得UI有更快的响应时间,得到更好的用户体验。<br />当Browser接收到WebSocketServer发送过来的数据时,就会触发onmessage消息,参数evt中包含server传输过来的数据;
```jsx
ws.onmessage = function(evt) {
};
```
3、WebSocket与TCP、HTTP的关系WebSocket与http协议一样都是基于TCP的,所以他们都是可靠的协议,Web开发者调用的WebSocket的send函数在browser的实现中最终都是通过TCP的系统接口进行传输的。
4、WebSocket和Http协议一样都属于应用层的协议,那么他们之间有没有什么关系呢?答案是肯定的,WebSocket在建立握手连接时,数据是通过http协议传输的,但是在建立连接之后,真正的数据传输阶段是不需要http协议参与的
![image (3).png](https://cdn.nlark.com/yuque/0/2021/png/22328960/1636711400876-41c6837d-6910-48f7-920b-895c2a9c57c4.png#clientId=u73f4536e-0f71-4&from=paste&height=231&id=u56457dac&margin=%5Bobject%20Object%5D&name=image%20%283%29.png&originHeight=231&originWidth=540&originalType=binary&ratio=1&size=13694&status=done&style=none&taskId=u2fa8d643-8a2c-4a8e-8833-f637541b8d5&width=540)
<a name="14106cbc"></a>
## 六、WebSocket通讯详细解读
![image (4).png](https://cdn.nlark.com/yuque/0/2021/png/22328960/1636711417314-0d2f463f-929f-4024-ab1b-6a16eb1f51e8.png#clientId=u73f4536e-0f71-4&from=paste&height=506&id=u9dcdacf6&margin=%5Bobject%20Object%5D&name=image%20%284%29.png&originHeight=506&originWidth=531&originalType=binary&ratio=1&size=74952&status=done&style=none&taskId=ue61af358-9ee9-481d-af16-a97863d1fd4&width=531)
从图可以明显的看到,分三个阶段:
- 打开握手
- 数据传递
- 关闭握手
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment