本篇内容介绍了“websocket的原理及作用是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
首先我们看一下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的原理及作用是什么”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。