本篇内容介绍了“websocket的原理及作用是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
坚守“ 做人真诚 · 做事靠谱 · 口碑至上 · 高效敬业 ”的价值观,专业网站建设服务10余年为成都成都雨棚定制小微创业公司专业提供成都定制网站营销网站建设商城网站建设手机网站建设小程序网站建设网站改版,从内容策划、视觉设计、底层架构、网页布局、功能开发迭代于一体的高端网站建设服务。
首先我们看一下websocket的出现背景,我们知道http系列协议是建立在tcp上的,理论上,他是可以可以双向通信的。但是http1.1之前,服务器没有实现推送的功能。每次都是客户端请求,服务器响应。下面看一下http协议关于请求处理的发展。
http1.0的时候,一个http请求的生命周期是客户端发起请求,服务器响应,断开连接。但是我们知道tcp协议的缺点就是,三次握手需要时间,再加上慢开始等特性,每一个http请求都这样的话,效率就很低。
http1.1的时候,默认开启了长连接(客户端请求中设置了keep-alive头),服务器处理一个请求后,不会立刻关闭连接,而是会等待一定的时间。如果没有请求才关闭连接。这样浏览器不仅可以在一个tcp连接中,不断地发送请求(服务器也会限制一个连接上可以处理的请求阈值),甚至可以一次发很多个请求。这就是http1.1的管道化(pipeline)技术。但是他也有个问题,因为对于基于http协议的客户端来说,虽然他可以发很多请求出去,但是当一个请求对于的回包回来时,他却无法分辨是属于哪个请求的。所以回包只能按请求顺序返回,这就引来了另一个问题-线头阻塞(Head-of-Link Blocking)。并且http1.1虽然支持长连接,但是他不支持服务端推送(push)的能力。如果服务器有数据要给客户端,也只能等着客户端来取(pull)。
来到了http2.0,不仅实现了服务器推送,还使用了帧(iframe),流(stream)等技术解决了线头阻塞的问题,http2.0在一个tcp连接中,可以同时发送多个http请求,每个请求是一个流,一个流可以分成很多帧,有了标记号,服务器可以随便发送回包,客户端收到后,根据标记,重新组装就可以。
以上是http协议的关于请求的一些发展,而websocket就服务端推送提供了另外一种解决方案。他本质上是在tcp协议上封装的另一种应用层协议(websocket协议)。因为他是基于tcp的,所以服务端推送自然不是什么难题。但是在实现上,他并不是直接连接一个tcp连接,然后在上面传输基于websocket协议的数据包。他涉及到一个协议升级(交换)的过程。我们看看这个过程。
1 客户端发送协议升级的请求。在http请求加上下面的http头
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Sec-WebSocket-Key: k1kbxGRqGIBD5Y/LdIFwGQ==
Sec-WebSocket-Version: 13
Upgrade: websocket
2 服务器如果支持websocket协议的话,会返回101状态码表示同意协议升级,并且支持各种配置(如果服务器不支持某些功能或版本,或告诉客户端,客户端可以再次发送协议升级的请求)。服务会返回形如下面的http头(可以参考websocket协议)。
Connection: Upgrade
Sec-WebSocket-Accept: y73KZR4t+hqD6KKYbkx2tULfBsQ=
Upgrade: websocket
3 这样就完成了协议的升级,后续的数据通信,就是基于tcp连接之上,使用websocket协议封装的数据包。
下面我们通过wireshark来了解这个过程。首先我们启动一个服务器(ip:192.168.8.226)。
var http = require('http');
var fs = require('fs');
const WebSocket = require('ws');
// 如果在浏览器控制台进行测试,可以不起http服务器
const server = http.createServer(options,function(req,res){
res.end(fs.readFileSync(`${__dirname}/websocket.html`));
}).listen(11111);
const wss = new WebSocket.Server({ server });
wss.on('connection', function connection(ws) {
ws.on('message', function(message) {
ws.send(message);
});
ws.send('get it');
});
我们可以直接在浏览器控制台进行测试
var ws = new WebSocket("ws://192.168.8.226:11111");
// 连接上后执行
ws.send(11)
这时候,我们看看wireshark的包。
我们再来看看安全版本的websocket。我们启动一个https服务器。
var https = require('https');
var fs = require('fs');
const WebSocket = require('ws');
var options = {
key: fs.readFileSync('./server-key.pem'),
ca: [fs.readFileSync('./ca-cert.pem')],
cert: fs.readFileSync('./server-cert.pem')
};
const server = https.createServer(options,function(req,res){
res.end(fs.readFileSync(`${__dirname}/websocket.html`));
}).listen(11111);
const wss = new WebSocket.Server({ server });
wss.on('connection', function connection(ws) {
ws.on('message', function(message) {
ws.send(message);
});
});
然后在浏览器控制台执行。
var ws = new WebSocket("wss://192.168.8.226:11111");
ws.sned(11);
然后来看看wireshark。
经过一系列的分析,我们对websocket协议应该有了更多的了解,最后再说一个关于websocket的点。我们发现如果在websocket连接上,一直不通信的话,websocket连接所维持的时间是依赖tcp实现的。因为我们发现tcp层会一直发送探测包。达到阈值之后,连接就会被断开。所以我们想维持websocket连接的话,需要自己去发送心跳包,比如ping,pong。
总结:本文分析了websocket的基本原理,但不涉及协议的内容,如需了解协议的内容,可以参考rfc文档。
“websocket的原理及作用是什么”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注创新互联网站,小编将为大家输出更多高质量的实用文章!