其他
节约标兵IE的自述
在这场轰轰烈烈的运动中,我不等不靠, 主动参与其中,在领导的教导下, 同事的帮助下, 做了很多优化和改进, 并评为节约标兵, 现在给大家分享下我的经验, 共同进步。
忘了自我介绍了,我是IE, 作为人类的代理(User Agent), 我是为人类访问互联网而生。
人类每次想访问互联网了,就会告诉我一个网址, 比如www.jd.com , 我就会让TCP这个小伙子帮我和这个网址的服务器建立一个连接, 然后通过这个连接通道给服务器发消息, 消息格式是我和服务器约定好的。
这个服务器也会按照约定, 给我发回整个页面的数据(俗称HTML 文档) , 当然也是通过同一个连接通道。
然后,这个连接通道就被服务器关闭, 人类把这种方式叫做“请求<-->响应”。
我和服务器商量这个HTTP协议的时候, 网站还很少,网页当然很少,内容基本上是纯文本, 这种建立一个连接通道, 发出请求, 然后等待整个页面返回的方式完全没有问题。
随着网速的迅猛增长, 网页开始变得复杂, 开始出现图片, css 等在我看来乱七八糟的东西, 为了把这些东西快速的从网站上取下来, 然后呈现给焦急等待的人类, 我通常得让TCP小哥给我建立很多连接通道,有的下载图片, 有的下载CSS, 有的折腾javascript。
而我这里用一次就关闭连接, 用一次就关闭连接, 是很大的浪费啊。
(码农翻身注: 三次握手具体过程参见码农翻身的另外一篇文章《TCP/IP之大明王朝邮差》)
我问TCP小哥:“ 这种用一次就关掉的行为很不爽,你能不能保持一个连接通道,让我多收发一些数据呢?”
“那你和服务器之间的事情了, 我管不了啊”他确实管不了, 这是我们应用层的事情, 确切的说是我和服务器之间的事情。
我和服务器彻夜协商, 搞一个keep-alive 的机制,默认情况下, 我们会让TCP小哥一直保持住打开的连接通道, 可以持续的在这个连接通道上发送消息。
这么一个小改进, 连接通道可以复用了, 效率确实提高了不少。
随着页面变得越来越大,人类对响应速度的要求也越来越高, 大家都希望在页面上操作以后,迅速的看到效果。
可是无论是普通模式,还是keep-alive 模式, 我每次给服务器发出请求的消息以后, 服务器都会把整个HTML文档给我, 这直接导致我需要刷新整个页面。
TCP小哥说: “看看你, 这几次从服务器收到的数据基本上都一样, 只有那么一点点变化的内容, 你就不能只去问服务器要那一点点变化的东西, 然后进行局部的更新吗?”
他的眼光很毒辣啊, 我早就意识到这个问题了, 其实我装载了一个HTML文档以后, 后续的操作,大部分情况下我只想和服务器通过纯粹的数据(例如XML, JSON)进行交流, 不想使用庞大的HTML文档了, 这样会节省很多的流量, 大大加快访问速度。
我赶紧找来Javascript同学来帮忙, 因为在我这里,这有他才能运行程序,在背后偷偷搞一点点小东西。
又是一个彻夜讨论, 最后决定采用局部更新的办法: 用户在页面操作以后, 整个页面不会刷新(浏览器中地址不会变), Javascript会在背后请TCP建立一个连接通道,和服务器通信,获得更新的数据, 然后局部更新。
解决方法只有一个, 那就是异步: Javascript在发出HTTP请求以后,不等待服务器把数据返回, 立刻干别的事情去了, 这样就不会导致我“假死” , 等到服务器的数据回来了, 我来通知他处理。
对了,人类把这种方式成为AJAX。
人类的欲望是无止境的, 我改进了这么多还是不能满足他们的要求。
这些家伙们试图把桌面应用全部迁移到到我这里来。比如说有人想写Web版本的在线协作软件, 多人可以同时在一个页面上操作, 他们竟然想把每个人的鼠标运动的位置都广播给所有人! 让大家能互相知道别人在哪里操作。
我很痛苦, 因为向服务器发送数据很频繁, 但是每次发送信息非常少, 就是类似于x=100&y=200, x=20&y=70这样的东西。
即使是这点数据,我也不得不遵循HTTP协议,老老实实的构建一个HTTP请求, 其实里边大部分都是无用的东西:
POST / HTTP/1.1Host: localhostUser-Agent: ....略...Accept: text/html ....略...Accept-Language: en-us,en;q=0.5Accept-Encoding: gzip,deflateKeep-Alive: 300Connection: keep-aliveReferer: http://localhost/test.phpContent-Type: application/x-www-form-urlencodedContent-Length: 9x=20&y=70
看看这"无用"的HTTP头, 占据了90%的数据量, 有效的数据只有那么9个字符, 是不是浪费?
还有人一直嚷嚷着让服务器主动给浏览器发数据。 原来都是浏览器发出请求, 服务器被动响应, 现在服务器想主动请求, 怎么可能? 完全违背了HTTP协议设计的初衷, 这不胡闹吗?
但是领导的谆谆教导点醒了我: “人类现在已经进入的移动互联网时代, 大数据时代, 对实时性要求更高, 比如说像什么股票信息了, 朋友圈有什么最新更新了 , 你用HTTP协议是不是的经常性的去轮询服务器, 问问有没有新数据产生啊?大部分时候这种轮询是不是在做无用功, 白白的浪费了网络的流量 ! 不要老是局限于HTTP, 想想别的办法!”
是的,浪费确实不少, 我大致总结了一下: 1. 我不想要那些HTTP的头了, 2. 浏览器和服务器之间要能互相发送数据。
TCP小哥说:“呵呵,这不就是我的socket 吗? , 你看两个电脑建立一个socket连接以后, 想发什么数据就发什么数据, 数据格式完全由你定义,灵活的很呐! 此外服务器给客户端发送数据也毫无障碍啊”
是啊, 既然Socket这么好, 那我在应用层也搞一个 , 把HTTP抛弃掉, 新协议就叫WebSocket !
但是慢着, HTTP被用的太广泛了, 网络中处理HTTP的海量基础设施(防火墙,缓存, 代理...),为了让大家都能迅速的支持Websocket, 而不是重起炉灶, 还是要和HTTP保持一定的兼容性, 在建立Websocket连接通道的时候, 我们用HTTP来完成:
GET /chat HTTP/1.1Host: server.example.comUpgrade: websocketConnection: UpgradeSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==Origin: http://example.comSec-WebSocket-Version: 13
这段话的意思是说:服务器,咱们把HTTP升级为Websocket吧?
HTTP/1.1 101 Switching ProtocolsUpgrade: websocketConnection: UpgradeSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
服务器的回复说: 我同意,以后我们就切换到Websocket 协议开始通信了啊。 于是连接就建起来了, 接下来我和服务器就可以双向通信了。
我要是想发送数据, 就直接发送x=20&y=70, 根本没有浪费流量的HTTP header , 服务器有啥数据想给我, 也直接推送, 不用我去查询了。
好吧, 今天就给大家汇报这么多, 最后祝大家国庆节快乐。
(完)
你看到的只是冰山一角, 更多精彩文章,尽在“码农翻身” 微信公众号, 回复消息"m"或"目录" 查看更多文章
有心得想和大家分享? 欢迎投稿 ! 我的联系方式:微信:liuxinlehan QQ: 3340792577
掘金是一个高质量的技术社区,从 Swift 到 React Native,性能优化到开源类库,让你不错过互联网开发的每一个技术干货。长按图片二维码识别或者各大应用市场搜索「掘金」,技术干货尽在掌握中。