8. 怎样制造出实时效果-ws
Last updated
Was this helpful?
Last updated
Was this helpful?
我前两天在折腾一个网页 Terminal (名字叫gotty), 就有时候你在Chrome里执行一些简单的命令, 但是切屏去命令行太麻烦了. 因此搞了一个这个, 用着用着觉得有一点很神奇, 就这种"实时"的效果是怎么做出来的? 很多网页也想做到实时的效果, 比如实时股价, 实时交通拥堵地图等, 他们的做法简单点就是疯狂用http刷(就是Ajax轮询) 或是long polling. 这个用的那种?
我们仔细想想这种东西... http 是什么样的, 客户端问, 服务端答, 就写死了只能这样, 服务器能主动说些什么吗? 不行, 如果客户端不问你就不能主动说任何东西. 就算搞 http-pipeline, 那也是一次问好几个问题, 然后服务器回答好几个问题, 那说到底还不是一问一答...
那么tcp是什么样的呢? tcp可以"不问自答"吗? 服务端可以主动给客户端发消息吗? 答案是可以的, tcp连接建立完成, 双方开始正常通信以后, 双方就是平等的关系: 其中一个人主动发问, 另一个人回答ACK, 无论谁都可以主动联系对方, 因此就不存在只有固定一个人提问另一个人回答的形式. 这种"平等聊天"的特性成为了websocket的基础
说到这儿不禁让人想起iPhone上的App推送, 或者微信消息来了你的手机会主动"叮"一下提醒你, 他是怎么主动告诉你的? 明明没有人主动去请求最新消息呀. 现在常用的做法是弄出一个tcp长连接 + 心跳. 服务端每次发现有你的消息的时候, 就根据你的Channel ID拿到你的长连接, 然后把你的消息发送给你, 实现服务端主动发消息的效果
上面的那个 WebTerminal 就使用了TCP平等聊天的特点, 本质上是一个TCP长连接, 考虑到没有人能裸用TCP所以我们对它做了一个最简单的封装, 我们叫它 websocket 协议.
ws协议实现了我们设想中: "既然TCP不能裸用, 那我们对它进行最minimized的封装", 报头只有两个byte, 非常简单, 是最接近裸TCP特性的 (正文里的 rgb255 是设置网页背景颜色的)
ws的握手是用http做的. 也就是在某几个http消息发完以后双方就正式开始使用ws协议通信了, 报文就要带上两字节的报头了 (用http做握手挺魔性的, 我没见过用一个复杂协议去握手一个简单协议的, 不过非要这么做好像也不会损失什么, 我猜ws被设计之初就是为了在网页上做出实时的效果, 而网页上搞http是最容易最方便的, 因此使用http做握手, 因此也才叫它 WEB-socket 吧, 我猜的)