01-websocket原理

websocket:

1.性能高:比普通的ajax高2-10倍,根据你的数据不同,环境不同。对于一个大型的数据而言,这个是非常方便的。 

2.双向:就跟打电话一样,你能说,他也能说,ajax的话服务器没法请求客户端。比如说一个聊天工具,你让ajax去做,搞个定时器,定时请求,这种方式会有很多缺点:

  - 不停的请求,浪费服务器资源,连接断开连接断开,对服务器有压力,浪费带宽,尤其是移动端。更讲求快速。

  - 双向的,websocket 是跟你连着,你不用去请求,有数据了服务器会去找你。

为什么性能高?

  因为像http通讯是一种基于字符的超文本通信,而webscoket在最开始的时候(建立连接的过程中)也是一个超文本,但是它一旦连接彻底建立,协议升级完成了,websocket会是一个二进制的协议。所以在这个时候就无需对那些数据进行转化的操作。

特性:

websocket不是一个独立的协议,它在建立连接的时候其实还是基于http协议(http是tcp的表现,tcp是http的爸爸),它还是通过普通的http请求来交换信息,比如密钥啊...,然后他才能正式建立连接。

websocket具有天然加密的特性,安全性比http协议高。

websocket具有自动重连的功能,如果在断开的期间,客户端试图去emit数据,websocket会自动的替你缓存起来,等到什么时候上线了它会自动再给发过去。

websocket是服务器一直在启动,是不是会造成对服务器资源的损耗更大?

  资源消耗大不大是相对而言的,比如如果前端一直开个定时器,3秒请求一次数据,对于服务器来说,接收到请求到返回数据(有可能没数据)再进行服务关闭,然后在启动服务,再关闭,这样才是对服务器带来了更大的压力,相对于websocket而言,websocket反而对服务器压力更小。websocket是属于长连接:这个长连接它消耗资源,但是消耗的只是保持信息的那一小块空间,它对CPU,对网络都没有任何负担。稍微浪费点一丁点内存,几个内存而已,并不是大问题。一般一个服务器同时保存几万个连接的数据是很轻松的。

websocket不存在跨域问题。

用websocket,要用一个socket.io 这个库,优点:

1.简单,方便

2.兼容到IE5

3.自动数据解析

安装: npm i socket.io -D

注意:本教程讲的是以下这个socket版本的写法

以下是服务器发,浏览器收:

后端要做的事:

 前端要做的事:

 前端的控制台不断(一秒间隔)的输出:

以下是浏览器发,服务器收:

前端:

 后端:

 接着浏览器一刷新页面,服务端就会输出:10

原生的websocket:

tcp请求,客户端向服务端发送请求要经历三次握手:

形象一点的比喻是这样的,有 A 和 B 想进行通话:

1、A 先对 B 说:“喂,你在么?我在的,我的口令是 j。”

2、B 收到之后大声回答:“我收到你的口令 j 并准备好了,你准备好了吗?我的口令是 k。”

3、A 收到之后也大声回答:“我收到你的口令 k 并准备好了,我们开始吧。”

为什么需要三次握手:

tcp连接的双方要确保各自的收发消息的能力都是正常的。
客户端第一次发送握手消息到服务端,
服务端接收到握手消息后把ack和自己的syn一同发送给客户端,这是第二次握手,
当客户端接收到服务端发送来的第二次握手消息后,客户端可以确认“服务端的收发能力OK,客户端的收发能力OK”,但是服务端只能确认“客户端的发送OK,服务端的接收OK”,
所以还需要第三次握手,客户端收到服务端的第二次握手消息后,发起第三次握手消息,服务端收到客户端发送的第三次握手消息后,就能够确定“服务端的发送OK,客户端的接收OK”,
至此,客户端和服务端都能够确认自己和对方的收发能力OK,,tcp连接建立完成。

握手的过程就是客户端与服务端交换信息的过程。

net模块就是原始的tcp连接,也就是socket,在其他语言里有的就叫socket,而在node中是叫net。

net模块的作用:

优点:帮助创建一个原始的服务器,这个原始的服务器可以接受任何种类的连接。

缺点:什么都得自己来写,平常的http服务,比如请求头的解析都帮你做完了,用net这种原始的服务器得需要自己来做很多事。

后台:

 前台:

后台通过node xxx.js文件运行;

前台通过:双击html文件运行

后台可以看到: 

前台可以看到:

 它比普通请求在request的请求头中多了四个东西:

1. Sec-WebSocket-Extensions:permessage-deflate; client_max_window_bits    ----》是一个扩展信息,影响力不大

2. Sec-WebSocket-Key:uMcHL9Q+M1LwTpuhNW6sCg==    ----》这里的key 是用来校验对方是真的知道 '我'在说什么的,这里的key值直接是给了一个websocket 才懂的一句话(比如,你不知道小明会说英语不,你不需要问你会吗?而是直接给他说了一句英语,如果他有反应和回应,而不是一脸懵逼,那就是他会啊。这里的key值就相当于一句英语。校验一下服务器懂不懂websocket。)

3. Sec-WebSocket-Version:13  ----》告诉websocket的版本是多少,因为不同的版本认证方法不一样

4. Upgrade:websocket    ----》浏览器告诉表示协议要升级

此时,后台能输出“有人连接我” 的console.log 信息,前台文件运行,通过alert('连接已建立')并没有弹出来。

这就是前台对后台的第一次握手;通过上面的请求头告知后台要走tcp协议;

那么后台就要去组织第二次握手:确认并回应

服务器通过once事件,接收到浏览器发过来的请求(双击html打开文件(file://xxxxxx 这种本地打开))得到请求信息

once是只有一次,这一次就是一个建立TCP请求的过程,当TCP请求建立成功(客户端与服务器相互确认过眼神,确认彼此是对的人~),websocket就建立起来了,以后就不走once了,就走sock.on()事件了。

 服务端处理接收到的http信息,处理为一个数组对象:

 拿到处理后的headers:

 TCP请求已建立,三次握手完成,所以会弹出“连接已建立”:处于pending状态就表明 这个socket就一直处于连接状态了。

 红框圈住的放大如下:

 至此,原生websocket 的三次握手就已经建立,要想用原生websocket还需要太多东西,这些都些只是建立客服端与服务端连接的第一步,只是帮助了解原理,要想使用websocket还是要用socket.io。

原文地址:https://www.cnblogs.com/haoqiyouyu/p/14225754.html