WebSocket 原理和可能遇到的性能问题原创
📢 大家好,我是法医,不是验尸的法医,而是写代码的法医,哈哈😅
相信大家都听到过HTTP协议
、TCP协议
、UDP协议
,还有那啥离婚协议
等等很多协议,这都是一些既熟悉又陌生的词,很多小伙伴不理解这些协议到底是干嘛的?不用这协议行不行?其它协议还好说,这离婚协议我还是希望大家别用到,能走到一起不容易,冲动是魔鬼👿,且行且珍惜哈🤞
今天我们就来聊聊webSocket
,它也是协议的一种,是解决实时场景的方案,有句话说滴好啊,“长江后浪推前浪,前浪被拍到沙滩上”,作为后起之秀的明星webSocket到底有何魅力,坐好小板凳,听我细细道来,嗯🤓,还是先回忆回忆往事吧!😜
继往圣之绝学
先给大家看几张图:
1、约对象看场电影,先订票😍
2、发工资了,来,炒股😬
3、这该死的疫情,又该抢菜了,我去,库存又没了,画饼充饥吧😭
4、聊天,也欢迎小伙伴能来我滴群,我给大家抽奖,偶尔滴哈,天天抽,没钱😁
以上4张图是我们日常生活中的场景,细心的小伙伴应该已经发现了,它们有一个共性——实时性
,订完票需要实时显示到页面上,不然又有一对情侣订同一个座位,那是不是双方就要打起来了,怨天尤人,撕心裂肺,埋怨老天不公,看来我们不合适,分手吧!😂,好家伙,猫眼电影成功拆散一对情侣。
这些对实时性有要求的页面会带来一些问题,就是怎么来实现实时通信🤷♂️,比如下面场景:
📢
王小贱
是我大学同学,也是我发小,毕业两三年,拖着22岁滴高龄,拿着3000高薪,过着富人滴生活,反正咱是没法比,用一句话来形容,就是“小树叶过河,全靠一股子浪劲”,这不,求爷爷告奶奶,让我介绍对象,以便维持老王家香火,仅以此图表达我此刻滴心情,问题不大,安排😂
俺们村有个大美女,名叫
翠花
,真真滴名如其人,上知天文,下知地理,琴棋书画,样样精通,就是有一点,极其害羞,见不得生人,没办法,我只好充当中间人,为这段来之不易的姻缘传递书信,但我也是有原则滴人——绝不主动找你们,感情是自己的事,自己必须上心😎
此时,小贱和翠花相当于两个客户端
,而我相当于服务器
,这里的原则相当于HTTP协议——请求-响应模式
,就有了如下图:
基于我的原则,我是没有办法将书信传递给翠花的,因为HTTP协议要求服务器不能主动,只能被动 ,意思就是说只有翠花请求服务器之后,我才能回应,但是问题来了:翠花并不知道王小贱给自己发消息了,翠花也不知道什么时候写信给小贱,毕竟女孩子天生比较矜持,因此这就是问题,问题的根源就是HTTP协议是请求——响应模式,请求必须在前,响应必须在后,这就导致服务器没有办法将消息主动发送到客户端🤷♂️
那么如何解决这个问题呢?毕竟关系到老王家滴香火,一脉单传,决不能断喽!😵
当然终极解决方案就是今天的主题webSocket
,但是作为一名合格的开发者,必须知道webSocket出现的契机是什么?任何一个技术的出现都是有原因的,这也是为什么小标题叫继往圣之绝学的原因,学习过去的知识才能更好的创新
短轮询 short polling
什么是短轮询?你可以认为短轮询就是患有话痨疾病的猪八戒🐷和沙师弟💀,就是不停地哔哔,请看图
翠花等了又等,直到人已枯黄,花已谢,再也等不住了,每隔一小段时间就向法医牌服务器请求一次,询问有没有小贱的消息,这里可以设置一个setInterval
定时器就可以了,一请求,一回应算一次http请求,还要记得,请求之前还要三次握手
,服务器回应完还有四次挥手
,如下图:
1、会产生大量无意义的请求,客户端不停的问服务器,有没有我的消息,服务器回应没有消息,那这次请求是不是没啥意义🤷实现一个短轮询是比较简单的,因为只要客户端设置一个setInterval
定时器,然后不间断发送请求就行了,这种方式是有缺陷也很明显
2、频繁地建立网络连接,频繁三次握手、四次挥手,然而也没啥意义
3、最大的缺点就是实时性并不高,因为需要设置定时器不间断请求,那么问题来了,定时器的时间设置多少合适呢?时间定短了,服务器太烦了,压力太大,搁谁也吃不消啊,如果时间设置长了,实时性又出问题了,如果小贱发来消息,那是不是得等到延时时间到了才能拿到新消息,那这个问题又怎么解决呢?解决不好,小贱断香火,翠花守寡,我呢,里外不是人,吃力不讨好😭,作为聪明滴开发者,肯定有招,下面的长轮询就可以解决
长轮询 long polling
长轮询有效解决了短轮询的问题,那么长轮询又是怎样的呢?依然看个图瞬间明白
一开始翠花会向服务器发送请求,如果服务器没有收到小贱的消息,那么服务器是不会回应翠花的,只有当服务器收到小贱的消息后,翠花请求的时候,服务器才会回消息,紧接着翠花马上又发起一次请求,询问有没有消息,如果没有小贱消息,服务器依然不会回应翠花,反之,响应翠花,随后反复进行
有了长轮询,我们可以很清楚的发现,请求减少了特别多,不像话痨的猪八戒吵得悟空烦死了,哈哈🙈
但是长轮询依然存在问题:
1、如果长时间都没有收到服务器响应会导致响应超时,从而与服务器断开连接,当因为超时客户端与服务器断开连接后,客户端紧接着会再次向服务器发送请求,但同时也意味着之前的请求毫无意义,浪费掉了,然而与短轮询相比,已经好很多了
2、还有一个缺陷就是客户端有可能过早请求服务器,这样会导致服务器一直处于挂起状态,直到响应新消息,那么挂起到响应新消息这段时间,服务器会占用资源,是不是白白浪费了服务器的资源
开webSocket之太平
之所以会产生上述问题,原因就是服务器不能主动给客户端发送消息,最大的凶手就是HTTP协议不允许服务器主动,伴随着HTML5出现的webSocket,从协议上赋予服务器主动推送消息的能力,从根上解决了这些问题。先看个图:
虽然由于轮训方案,但是webSocket仍然是有缺点的从图上我们能知道,webSocket协议
会经过两个阶段握手阶段
和通信阶段
,webSocket协议跟HTTP协议一样,都是建立在TCP协议之上的,这里利用了TCP协议全双工通信的能力,灰色区域
表示通信连接已经建立,当通信连接建立完成之后,立马进行webSocket握手
,这里需要注意的是TCP握手
和webSocket握手
是完全不同的,webSocket握手
发生在TCP握手
之后,当webSocket握手
完成之后,表明服务器和客户端可以互相通信了,服务器可以发送任意消息给客户端,客户端也可以发送任意消息给服务器,我们把这种模式叫做全双工通信
,说简单点就是服务器和客户端两者之间随意交流,没有什么限制,想说啥说啥。将HTTP模式叫半双工通信
,只能客户端主动,服务器被动
1、 我们都知道webSocket是HTML5新增的内容,那么老版本的浏览器肯定是不支持的,所以兼容上有问题
2、维持TCP通信连接需要耗费服务器的资源,尤其是请求信息量比较少的时候,会造成资源浪费,所以大家需要注意的是并不是有了webSocket,ajax就不重要了,webSocket再好,请不要贪杯哦,在某些场景下,ajax还是优于webSocket的,比如只需要请求一两个数据,还需要大动干戈使用webSocket吗?
webSocket握手
这里我们重点看看webSocket握手
到底是怎么回事?
当客户端需要和服务器进行通信时,首先会使用HTTP协议
完成一次特殊的请求-响应,这一次请求-响应就是webSocket握手
在握手阶段,首先客户端会向服务器发送一个请求,必须是ws
开头,不再是http
了,但依然是HTTP请求,请求地址如下:
请求头是这样的:
如果服务器同意,就会响应下面的消息
握手完成后,后续消息收发不会再使用HTTP协议了,服务器和客户端终成眷属,知无不言言无不尽说着甜蜜滴情话,哈哈🙆♀️
以上就是今天的分享,这是 《法医奇遇记系列》 第一篇文章,故事情节也都是自己编的,目的也很简单,就是为了能让大家更好的理解知识点,之前写的文章比较单调,这次想换一种风格吧,还有一点是文章的题目爱情是WebSocket的坟墓并不是所谓的标题党,我不是瞎起的,也是有深意在里面,我觉得,在http协议下的服务器和客户端更像追女孩子的过程,会遇到各种问题,服务器表现得像一个矜持翠花小姐姐,只要客户端不找,绝不理你,有段时间没找了,心里边想着:这货,怎么还不找我?这么久了还不找我?然后王小贱委屈巴巴说:不是我不找,http协议不允许呐,webSocket的出现打破了这种限制,那不得天天腻歪在一起,时间久了,也许会变成坟墓吧,哈哈,我也不知道,反正是瞎编的......🙉