2017的北京的冬天,显得格外的冷,又干又冷,新闻里说,这样的天气有利于北京的空气质量的提升,霾没了,截止到29号看来,并没有,而且雪也没了,等了一冬天,毛都没有见到。一个人等雪的时候,稍微略显寂寞,不如来看看websocket吧~
阿伟
阿伟第一次接触互联网的的时候是 2001年,十几岁的他,就好像同样豆蔻年华的互联网一样,还是略显稚嫩,不知道怎么样跟心爱的女孩子交流,也不知道怎样才能叩开花季少女的心扉。阿伟一直在想,一直在冥思苦想,人与人之间应该怎样交流,人与人之间怎么样才能建立联系,人与人之间又怎么样才能坠入爱河,直到他学了计算机网络,他才恍然大悟。
而让他悟出这一切的正是OSI七层数据模型,如下图
点击图片查看大图
在网络中的两个点如果需要进行通信,他们需要经过一层层协议的封装,我们常见的就像是TCP协议,IP协议,他们在网络模型中都有对应的层级,而我们最常用的HTTP协议就是最顶端应用层的协议。
阿伟懂了,两个人如果在茫茫人海中相遇,必须通过一定的协议来进行交流和沟通,否则一切都是空谈,我听不懂你,你不了解我。
阿伟有了心爱的姑娘,他想和她在一起一辈子。
说好的一辈子,差一分,差一秒,都不算。
可是那个年代,怎么样才能跟心爱的姑娘实时在一起啊,大多数人还是选择了写信。可是写信啊,你写一封,对方回一封,这个过程没有任何错误。就好像HTTP协议一样,我发送一个请求,就必然要收到一个请求,不然浑身难受。
可是,年轻的阿伟,热血的阿伟等不及啊。这时候他就有了一个大胆的想法,他从ajax轮询中得到了启发,客户端隔个几秒就发送一次请求,向服务器询问数据是否更新。于是他每天都给心爱的小姐姐写信,询问是否有新鲜的事情,善良的小姐姐也会给他回信,只是并不是每次回信都有新内容。
但是他觉得这样不好,太浪费纸了。
后来他又从long poll中找到了灵感,所谓long poll,即客户端和服务端通过请求建立了连接之后,连接一直保持,服务端直到有消息了才把请求返回给客户端。阿伟之所以能这样做,因为他要到了姑娘的电话,他打电话,两人羞涩,竟不知说些什么好,谁也不肯挂掉电话,但是两人的心头都是暖暖的。
后来,电话费太贵了,阿伟还是受不了。
可是这有何妨,阿伟的努力还是得到了回报,二人终于在一起了。
阿伟终于明白了,原来他们说的是真的,从前车马很慢,书信很远,一生只够爱一个人。
在那个年代,HTTP协议,还是浏览器和服务器交互的标准,一个又一个的请求从发出到返回,不知道多少思念和祝福在网上流转着,但是始终实时交流考验着每个人的心儿,无论ajax轮询还是long poll,都有着不可规避的缺点,前者创造了太多的无用请求,后者则对服务器造成了巨大的负荷,时代渴望着一个可以支持实时的协议。上帝说,要有光,于是,就有了光。而这道光就是Websocket。
阿辉
阿辉喜欢《王者荣耀》的张飞,叱咤风云,神挡杀神,佛挡杀佛,当然需要变身。室友问如果你女朋友住院了,你朋友找你王者开黑,你选哪一个,阿辉说,我选张飞吧,我张飞贼溜。老段子了,上次讲这个段子的时候,阿辉还是有女朋友小洁的。
小洁是个学霸,最喜欢跟阿辉讲Websocket。
辉仔,你知道什么是Websocet么?
打团了,打团了,程咬金,不要瞎跑!并没有理她。
哼,小洁冷哼一声
知道知道,不就是HTML5集成的那套规范么?太简单了,待会我给你写一遍~先让我打一波团。阿辉不耐烦道。
你说的这个,没想到小洁拿出了一张纸,上面写着几行代码
if ("WebSocket" in window) { alert("您的浏览器支持 WebSocket!"); // 打开一个 WebSocket var ws = new WebSocket("ws://localhost:9000"); ws.onopen = function(){ // WebSocket 已连接上,使用 send() 方法发送数据 ws.send("发送数据"); alert("数据发送中..."); }; ws.onmessage = function (evt){ // 监测信息 var received_msg = evt.data; alert("数据已接收..."); }; ws.onclose = function(){ // 关闭 WebSocket alert("连接已关闭..."); }; }else{ // 浏览器不支持 WebSocket alert("您的浏览器不支持 WebSocket!"); }
对对,不就是这个么,这个不就是Websocket么!兄弟,等我再开团~。
小洁小嘴一撅,瞬间不大开心了。跟你说了多少次了,WebSocket指的是Websocket协议,WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端,而HTML5集成的是Websocket API。算了,我觉得我们不合适,我们分手吧。
打啊,推塔啊。啊?你说啥?
我说我们不合适,分手吧。小洁转身离去,留下了阿辉错愕而震惊的表情,但是阿辉还是忍受着失恋的痛苦坚持打完了游戏,赢了,但是阿辉突然觉得没意思了,赢得了游戏,失去了你,又有什么意义。可惜阿辉醒悟的太晚。
小洁走后,阿辉开始真正理解Websokcet的真正含义,他常常在心中模拟Websocket连接建立的过程。
阿辉开启了一个Websocket服务器,然后打开了Chrome,在浏览器立认认真真的开启了一个连接,然后打开network面板,他看到了一个请求,他想起了小洁,善良可爱的小洁。 就像小洁讲的那样,第一个请求是HTTP协议,但是附带了升级协议的Header
眼泪噙满了阿辉的眼睛,阿辉紧握着手,鼠标一点点打开了折叠的Response Headers, 协议被升级了,阿辉终于控制不住自己,留下了悔恨的泪水,他想小洁了,灰常想。
阿辉想小洁的时候,就去默默去看Websocket的协议,这个协议是独一无二的,就好像小洁是独一无二的。 阿辉甚至把下面Websocket的协议帧格式做成了自己的被套,每天盖在身上,他觉得,这样,小洁还在他身边,还在陪着他。
阿辉还在打游戏,只是打游戏的时候还会想起小洁。又是一个夜晚,阿辉梦见自己变成了张飞,一开始就像第一个发出的HTTP请求一样,羞涩,突然cd时间一到,就像服务器收到了请求一样,协议升级成了Websocket协议,自己也壮实起来了,很好,很强大,只是,没了小洁。
阿江
阿江是个90后,可是开始秃了。阿江虽然开始秃了,可是阿江有女朋友。阿江虽然有女朋友,但是阿江是有了女朋友之后,才开始秃的。阿江很担心,阿江很惆怅。
不知道为何,阿江发现女朋友最近开始研究使用node写一个Websocket服务器了,这样阿江的头皮发麻了一下,阿江不知所措,难道女友要离开自己了么。
有一天,女友把阿江叫了过来,一起review代码
const http = require('http'); const crypto = require("crypto"); const server = http.createServer((req, res) => { res.end(); }); server.on('upgrade', (req, socket, head) => { // 获取请求头的信息,并处理 let key = req.headers['sec-websocket-key']; key = crypto.createHash("sha1").update(key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11").digest("base64"); // 返回对应的Headers信息 const headers = [ 'HTTP/1.1 101 Switching Protocols', 'Upgrade: websocket', 'Connection: Upgrade', 'Sec-WebSocket-Accept: ' + key ]; socket.setNoDelay(true); socket.write(headers.join("\r\n") + "\r\n\r\n", 'ascii'); }); server.on('clientError', (err, socket) => { socket.end('HTTP/1.1 400 Bad Request\r\n\r\n'); }); server.listen(9000);
女友说,你看,我照着网上的教程写了个Websokcet的服务器耶,但是我还有好多不懂的地方,你给我讲讲~
阿江细心跟女友讲解着,这个demo只是成了当服务器接收到请求之后,如果监听到upgrade,就会取请求头里面的sec-websocket-key,经过处理,并且返回对应的Headers,告知客户端已经升级成Websocket协议了。只是这还是个简单的demo,还没有添加将信息处理成Websocket协议帧的方法,还有好多要做的地方要完善,阿江不懂女友为什么要学这个,学好了这个,女友就会离开自己了么,我就知道当初就是看中我的技术好,现在我开始秃了,技术的Buff不再了,一定是因为这样,阿江还是忍不住问了,你是不是要离开我了。
傻瓜,为什么这样说。
你为什么要学这个。
你是不是之前学过这个?
我啊,最近看你愁眉不展,就像走走你走过的路,听你听过的歌,尝试你曾经做过的一切,但这并不是想证明我有多爱你,我只是想离你更近一点。你那么可爱,我怎么舍得离开呢。而且看你最近不开心,想知道你为什么而已。
阿江的眼里噙满了泪水,将女朋友拥入怀中~
阿欢
阿欢最近开始研究Websocket,他查遍资料,很多论坛都推荐了socketio,为什么呢,阿欢不禁问道。
阿欢把官方的demo clone下来仔细研究起来。
以聊天室为例,浏览器客户端的代码
html // 页面上引用socketio.js <script src="/socket.io/socket.io.js"></script> js代码 // 创建一个链接 var socket = io(); // 监听login事件 socket.on('login', function (data) { // Todo }); // 触发add user事件,服务端会接收到 socket.emit('add user', username);
node服务端的代码
//不是完整代码 const server = require('http').createServer(app); const io = require('../lib')(server); let numUsers = 0; io.on('connection', function (socket) { var addedUser = false; // 监听到客户端发送的new message信息,并做处理 socket.on('new message', function (data) { // 向所有的客户端广播new message socket.broadcast.emit('new message', { username: socket.username, message: data }); }); // 当监测到添加用户的时候的处理 socket.on('add user', function (username) { if (addedUser) return; // 保存用户名 socket.username = username; ++numUsers; addedUser = true; // 像对应客户端触发login事件 socket.emit('login', { numUsers: numUsers }); // 向所有客户端广播user joined事件 socket.broadcast.emit('user joined',{ username: socket.username, numUsers: numUsers }); }); });
阿欢疑惑,代码太简单了, 客户端 代码甚至没有看到使用Websocket啊,突然阿欢有个大胆的想法,机智的阿欢打开了调试界面,惊奇的发现,竟然发出了三个请求,原来socketio竟然做了兼容,不紧有Websocket,同时考虑到不支持Websocket的环境,它尽然主动polyfill了,当然兼容主要用的还是轮询的方式。
再看服务端的代码也不难发现,没有涉及到协议的升级,这就说明socketio做了程度很大的包装,让使用者更注重业务的开发。
阿欢心头一暖,内心激动无比,不禁感谢这个时代,这个美妙而和谐的时代。这么多人努力着,奋斗者,为了把这个世界弄得更美好。
阿寻
阿寻很是忧伤,忧伤的不知所以,回想这一年,前端的技术发展让他有些不知所措,日新月异的速度让他觉得这个世界都有点假假的感觉了,但是看了看比特币的价格变化,阿寻又觉得前端的变化速度也不是很快。
Alice发给了阿寻的一篇文章 Will WebSocket survive HTTP/2?
https://www.infoq.com/articles/websocket-and-http2-coexist/
阿寻想,为什么要发给我这种文章,知道我最近正在学习Websocket么?阿寻大致看了下文章,在比较了Websocket和HTTP2,之后,作者给出了自己的观点,Websocket会存活下来,只是阿寻又陷入了惆怅,说不定哪天会被其他技术干掉呢。
阿寻心头一紧,觉得Alice是在嘲笑自己,嘲笑自己没有能洞悉时代的趋势,没能紧跟技术的浪潮啊,阿寻更加沮丧了。
阿寻对Alice说,完了,我跟不上这个时代了。
Alice很诧异,说咋啦。
阿寻说,我看你发我的文章,Websocket我还没吃透,感觉随着技术的发现,早晚又会被淘汰了呢。
Alice说,啊,我就是让你看看,你英文这么差,练练英文啊,哪有想这么多。再说,根据文章的描述以及国内的环境, Websocket还是目前最被认可的技术, 那么现在来说Websocket还是大有用途的。
阿寻说,我最近觉得我就像被上帝抛弃了一样,感觉要被淘汰,我觉得我快失业了。
Alice说,至于么,或许某天,Websocket会被新技术取代,但是至少肯定不是今天。如果那天真到了,你也不一定失业啊。如果你真的失业了,我养你啊~
阿寻有些懵逼,你再说一遍。
Alice说我说,我养你啊~
阿寻身体忍不住颤抖起来,你再说一遍。
Alice:我说你失业了,我养你啊~
阿寻说想了一会儿,说好,我也养你~
是啊,只要Alice还在,阿寻就充满了斗志。技术的更迭不再困惑阿寻了,兵来将挡水来土掩,再学就是了。
结语
这一年,阿猿们依旧努力奋斗着,与天斗,与地斗,与八阿哥斗,昼伏夜出,披星戴月,吸天地之灵气,取日月之精华,有些人倒下了,有些人离开了,但是还有些人任然坚持着,他们感激着过去奋斗着2017的每一天,展望着即将到来的2018的每一天。
两句歌词送给大家~
一往无前虎山行,拨开云雾见光明。
梦里花开牡丹亭,幻想成真歌舞升平。
——GAI
祝大家新年快乐
买彩票中大奖
据说留言许愿,来年实现的概率就会翻倍哦~
参考文献
-
Web 通信 之 长连接、长轮询(long polling)
https://www.cnblogs.com/hoojo/p/longPolling_comet_jquery_iframe_ajax.html
-
webSocket、Ajax轮询、长轮询(long poll)
http://blog.csdn.net/lb7758zx/article/details/51513353
-
nodejs socket 服务端和客户端
http://blog.csdn.net/lxhjh/article/details/40686481
-
学习 NodeJS 第八天:Socket 通讯
http://blog.csdn.net/zhangxin09/article/details/12844975
-
nodejs实现Websocket的数据接收发送
https://www.cnblogs.com/axes/p/4514199.html
-
HCNA-HNTD——以太网帧结构
http://blog.csdn.net/wdkirchhoff/article/details/43915825
-
OSI七层模型详解
http://blog.csdn.net/yaopeng_2005/article/details/7064869
-
OSI七层模型与TCP/IP五层模型
https://www.cnblogs.com/qishui/p/5428938.html
-
TCP/IP、Http、Socket的区别
http://jingyan.baidu.com/article/08b6a591e07ecc14a80922f1.html
-
WebSocket数据包协议详解
https://www.cnblogs.com/smark/archive/2012/11/26/2789812.html
-
The WebSocket Protocol
https://datatracker.ietf.org/doc/rfc6455/?include_text=1
-
Will WebSocket survive HTTP/2?
https://www.infoq.com/articles/websocket-and-http2-coexist/
注:本文内容来自互联网,旨在为开发者提供分享、交流的平台。如有涉及文章版权等事宜,请你联系站长进行处理。