一、引言

WebSocket是一种比较新的协议,它是伴随着html5规范而生的,虽然还比较年轻,但大多主流浏览器都已经支持。它使用方面、应用广泛,已经渗透到前后端开发的各种场景中。

对http一问一答中二式流程(就是从所周之的“长轮询”技要啦)的不满,催生了支持双向通信的WebSocket诞生。WebSocket是个不太干净协议。

本文将从8个常见的疑问入手,为还不了解WebSocket协议的开发者快速普及相关知识,从而节省您学习WebSocket的时间。

另外,如果您对Web端的即时通讯技术还完全不了解,那么《新手入门贴:详解Web端即时通讯技术的原理》、《Web端即时通讯技术盘点:短轮询、Comet、Websocket、SSE》这两篇文章请您务必抽时间读一读。

学习交流:

- 即时通讯/推送技术开发交流4群:101279154[推荐]

- 移动端IM开发入门文章:《新手入门一篇就够:从零开发移动端IM

(本文同步发布于:http://www.52im.net/thread-2488-1-1.html

二、参考文章

三、更多资料

Web端即时通讯新手入门贴:
新手入门贴:详解Web端即时通讯技术的原理

Web端即时通讯技术盘点请参见:
Web端即时通讯技术盘点:短轮询、Comet、Websocket、SSE

关于Ajax短轮询:
找这方面的资料没什么意义,除非忽悠客户,否则请考虑其它3种方案即可。

有关Comet技术的详细介绍请参见:
Comet技术详解:基于HTTP长连接的Web端实时通信技术
WEB端即时通讯:HTTP长连接、长轮询(long polling)详解
WEB端即时通讯:不用WebSocket也一样能搞定消息的即时性
开源Comet服务器iComet:支持百万并发的Web端即时通讯方案

更多WebSocket的详细介绍请参见:
新手快速入门:WebSocket简明教程
Socket.IO介绍:支持WebSocket、用于WEB端的即时通讯的框架
socket.io和websocket 之间是什么关系?有什么区别?

有关SSE的详细介绍文章请参见:
SSE技术详解:一种全新的HTML5服务器推送事件技术

更多WEB端即时通讯文章请见:
http://www.52im.net/forum.php?mod=collection&action=view&ctid=15

四、1问WebSocket:WebSocket协议只能浏览器发起么?

不是。目前此协议的受众的也不仅仅是web开发者。

WebSocket只是一种协议,它和http协议一样,使用类似okhttp的组件,可以在任何地方进行调用,甚至可以借助WebSocket实现RPC框架。

 

五、2问WebSocket:WebSocket和HTTP什么关系?

WebSocket和http一样,都是处于OSI模型中的最高层:应用层。

 

WebSocket借助http协议进行握手,握手成功后,就会变身为TCP通道,从此与http不再相见。

使用netstat或者ss,能够看到对应的连接,它与处于抽象层的socket,在外观上没有区别。

更多WebSocket和HTTP的关系,以及与Socket的区别,可进一步阅读以下文章:

WebSocket详解(四):刨根问底HTTP与WebSocket的关系(上篇)

WebSocket详解(五):刨根问底HTTP与WebSocket的关系(下篇)

WebSocket详解(六):刨根问底WebSocket与Socket的关系

六、3问WebSocket:WebSocket和长轮询有什么区别?

长轮询,就是客户端发送一个请求,服务端将一直在这个连接上等待(当然有一个超长的超时时间),直到有数据才返回,它依然是一个一问一答的模式。比如著名的comted。

WebSocket在握手成功后,就是全双工的TCP通道,数据可以主动从服务端发送到客户端,处于链接两端的应用没有任何区别。

WebSocket创建的连接和Http的长连接是不一样的。由于Http长连接底层依然是Http协议,所以它还是一问一答,只是Hold住了一条命长点的连接而已。

长轮询和Http长连接是阻塞的I/O,但WebSocket可以是非阻塞的(具体是多路复用)。

 

这方面更深入的资料,请进一步学习:

Comet技术详解:基于HTTP长连接的Web端实时通信技术

WEB端即时通讯:HTTP长连接、长轮询(long polling)详解

七、4问WebSocket:如何创建一个WebSocket连接?

WebSocket的连接创建是借助Http协议进行的。这样设计主要是考虑兼容性,在浏览器中就可以很方便的发起请求,看起来比较具有迷惑性。

下图是一个典型的由浏览器发起的ws请求,可以看到和http请求长的是非常相似的。

但是,它只是请求阶段长得像而已:

 

请求的地址,一般是:ws://\*\*\*,或者是使用了SSL/TLS加密的安全协议wss:,用来标识是WebSocket请求。

1)首先,通过Http头里面的Upgrade域,请求进行协议转换。如果服务端支持的话,就可以切换到WebSocket协议。简单点讲:连接已经在那了,通过握手切换成ws协议,就是切换了连接的一个状态而已。

2)Connection域可以认为是与Upgrade域配对的头信息。像nginx等代理服务器,是要先处理Connection,然后再发起协议转换的。

3)Sec-WebSocket-Key 是随机的字符串,服务器端会用这些数据来构造出一个 SHA-1 的信息摘要。如此操作,可以尽量避免普通 HTTP 请求被误认为 WebSocket 协议。

其他的,像Sec-WebSocket*字样的头信息,表明了客户端支持的子协议以及其他信息。像loT中很流行的mqtt,就可以作为WebSocket的子协议。

 

使用javascript,可以很容易连接一个WebSocket服务端:

<script>

varws = newWebSocket('ws://localhost:80');

ws.onopen = function() {

console.log('ws onopen');

ws.send('from client: hello');

};

ws.onmessage = function(e) {

console.log('ws onmessage');

console.log('from server: '+ e.data);

};

...

</script>

更详细的资料,请阅读:《WebSocket详解(三):深入WebSocket通信协议细节》。

八、5问WebSocket:WebSocket如何处理数据?

WebSocket是通过事件通知的方式运行的。它包含四个事件和两个动作(发送和关闭)。

WebSocket的事件:

 

数据可直接通过Socket.send()方法进行传输。

通过chrome的Inspect->Network->WS,可以看到页面上的WebSocket连接。

如图Opcode为2,表明它是一个二进制帧:

 

WebSocket有类似tcp协议的帧格式,在此不做过多解释。(可以详细阅读:《理论联系实际:从零理解WebSocket的通信原理、协议格式、安全性》)

参考:https://tools.ietf.org/html/rfc6455#section-5.1

九、6问WebSocket:如何使用Nginx做WebSocket的负载均衡?

nginx官网已经给出了例子。主要是Upgrade和Connection头的设置。

Nginx的中的配置如下:

map $http_upgrade $connection_upgrade {

default upgrade;

''close;

}

location /chat/{

proxy_pass http://backend;

proxy_http_version 1.1;

proxy_set_header Upgrade $http_upgrade;

proxy_set_header Connection $connection_upgrade;

}

需要注意的是,nginx做负载均衡,不需要配置ip_hash等参数,nginx天然支持。由于ip_hash仅使用ip地址的前三个数字做hash,还有可能造成服务端的不均衡。

特别注意:

在IM聊天系统场景下,Nginx提供给WebSocket的这种所谓的“负载均衡”,只能解决传统分布系统中的SLB服务器要做的事。

通俗地说,Nginx只能帮助完成引导WebSocket客户连接到哪一个WebSocket服务端实例,在IM集群情况下,如果两个用户处于不同的WebSocket实例下时,它们之间的跨实例通信,Nginx是没有办法实现的,这一块的逻辑还是得IM开发者自已来实现。

总而言之,Nginx提供给WebSocket的所谓“负载均衡”,并不是IM开发者认为的那种全功能集群!

十、7问WebSocket:Java服务端怎么实现WebSocket?

可以使用javax.WebSocket下的包,简单的实现ws服务端。目前基本可以通过注解的方式去编写代码,比如ServerEndpoint。

推荐使用基于netty的netty-socketio进行服务端的编写。由于使用的是netty,所以能够在多个层面进行切入,获取一些统计数据,执行一些控制指令。socketio是一套解决方案,它有多个语言的客户端,并处理了市面上大多数的兼容问题。

友情忠告:socket.io几乎是市面上最好的开源WebSocket解决方案,但netty-socketio这个开源工程并非socket.io官方团队维护,而对于socket.io这个版本帝来说,其他的非官方版本能不能即时跟进,也是一个需要考虑的风险因素。

十一、8问WebSocket:WebSocket能干些啥?

1)通知功能:

保持一个长连接,当服务端游新的消息,能够实时的推送到使用方。像知乎的点赞通知、评论等,都可以使用WebSocket通信。

某些使用H5的客户端,为了简化开发,也会使用WebSocket进行消息的通知,由于它是实时推送的,会有更好的用户体验。

2)数据收集:

一些次优级别的数据,比如行为日志、trace、异常执栈收集等,都可以开辟专门的WebSocket通道进行传输。这能够增加信息的集中度,并能及时的针对用户的行为进行合适的配置推送。由于大多数浏览器内核都支持,它将使客户端APM编程模型变得简单。

3)加密 && 认证:

虽然使用Fiddler、Charles等能够抓到很多WebSocket包。但如果同时开启SSL,传输加密后的二进制数据,会大幅增加破解的成本,会安全的多。

4)反向控制钩子:

这个...由于是双工长连接,服务端完全可以推送一些钩子命令,甚至直接是代码,在客户端进行执行。比如截个屏,录个音,种个小马。用户只要通过了授权申请,剩下的就随你发挥了。

支付宝偷偷调用你的相机给你拍照的梗,我是相信的。

十二:本文小结

想当年,cometd的出现,惊为天人,振奋了很久。但技术日新月异,cometd已经衰老,而Socket.io得到了快速发展。WebSocket经过一段时间的混沌期,规范已经越来越完善,使用也越来越方便,不需要再处理那么多的兼容。

但它的本质,还是新瓶装旧酒,换汤不换药。WebSocket的发展得益于HTML5规范的制定。规范的意义,就是约束厂商们天马行空的实现,以及指明发展的方向。

这当然有典型的反例,那就是ie。现在,只有一群公认的**,还坚持在用。

附录:更多WEB端即时通讯资料

新手入门贴:史上最全Web端即时通讯技术原理详解
Web端即时通讯技术盘点:短轮询、Comet、Websocket、SSE
SSE技术详解:一种全新的HTML5服务器推送事件技术
Comet技术详解:基于HTTP长连接的Web端实时通信技术
新手快速入门:WebSocket简明教程
WebSocket详解(一):初步认识WebSocket技术
WebSocket详解(二):技术原理、代码演示和应用案例
WebSocket详解(三):深入WebSocket通信协议细节
WebSocket详解(四):刨根问底HTTP与WebSocket的关系(上篇)
WebSocket详解(五):刨根问底HTTP与WebSocket的关系(下篇)
WebSocket详解(六):刨根问底WebSocket与Socket的关系
socket.io实现消息推送的一点实践及思路
LinkedIn的Web端即时通讯实践:实现单机几十万条长连接
Web端即时通讯技术的发展与WebSocket、Socket.io的技术实践
Web端即时通讯安全:跨站点WebSocket劫持漏洞详解(含示例代码)
开源框架Pomelo实践:搭建Web端高性能分布式IM聊天服务器
使用WebSocket和SSE技术实现Web端消息推送
详解Web端通信方式的演进:从Ajax、JSONP 到 SSE、Websocket
MobileIMSDK-Web的网络层框架为何使用的是Socket.io而不是Netty?
理论联系实际:从零理解WebSocket的通信原理、协议格式、安全性
微信小程序中如何使用WebSocket实现长连接(含完整源码)
八问WebSocket协议:为你快速解答WebSocket热门疑问
>> 更多同类文章 ……

(本文同步发布于:http://www.52im.net/thread-2488-1-1.html

 

八问WebSocket协议:为你快速解答WebSocket热门疑问的更多相关文章

  1. WebSocket协议详解及应用

    WebSocket协议详解及应用(七)-WebSocket协议关闭帧 本篇介绍WebSocket协议的关闭帧,包括客户端及服务器如何发送并处理关闭帧.关闭帧错误码及错误处理方法.本篇内容主要翻译自RF ...

  2. MQTT协议笔记之mqtt.io项目Websocket协议支持

    前言 MQTT协议专注于网络.资源受限环境,建立之初不曾考虑WEB环境,倒也正常.虽然如此,但不代表它不适合HTML5环境. HTML5 Websocket是建立在TCP基础上的双通道通信,和TCP通 ...

  3. jmeter针对websocket协议的压测

    之前一直没有接触过websocket协议,所以一直对websocket的压测存在疑惑,在网上参考文章并不断尝试之后,终于有所得:第一次用jmeter的websoket插件,用的ws非加密协议,请求都能 ...

  4. WebSocket协议探究(一)

    一 复习和目标 1 复习 上一节使用wireshark抓包分析了WebSocket流量 包含连接的建立:HTTP协议升级WebSocket协议 使用建立完成的WebSocket协议发送数据 2 目标 ...

  5. WebSocket协议 8 问

    WebSocket是一种比较新的协议,它是伴随着html5规范而生的,虽然还比较年轻,但大多主流浏览器都已经支持.它使用方面.应用广泛,已经渗透到前后端开发的各种场景中. 对http一问一答中二式流程 ...

  6. http协议与websocket协议(转)

    一.WebSocket是HTML5中的协议,支持持久连接:而Http协议不支持持久连接. 首先HTMl5指的是一系列新的API,或者说新规范,新技术.WebSocket是HTML5中新协议.新API. ...

  7. 阿里云全站加速DCDN全面支持WebSocket协议

    WebSocket协议可以为网站和应用提供真正的双向通信,具有控制开销.保持连接状态.更强实时性.更好的压缩效果等优点,是当下低延时应用最常采用的一种技术协议.为了更好的满足客户在实时通讯场景下的加速 ...

  8. Websocket 协议解析

    WebSocket protocol 是HTML5一种新的协议.它是实现了浏览器与服务器全双工通信(full-duplex).          现 很多网站为了实现即时通讯,所用的技术都是轮询(po ...

  9. WebSocket协议开发

    一直以来,网络在很大程度上都是围绕着HTTP的请求/响应模式而构建的.客户端加载一个网页,然后直到用户点击下一页之前,什么都不会发生.在2005年左右,Ajax开始让网络变得更加动态了.但所有的HTT ...

随机推荐

  1. 解决持久化数据太大,单个节点的硬盘无法存储的问题;解决运算量太大,单个节点的内存、CPU无法处理的问题

    需要学习的技术很多,要自学新知识也不是一件容易的事,选择一个自己比较感兴趣的会是一个比较好的开端,于是,打算学一学分布式系统. 带着问题,有目的的学习,先了解整体架构,在深入感兴趣的细节,这是我的计划 ...

  2. 你不知道的JavaScript--Item16 for 循环和for...in 循环的那点事儿

    大家都知道在JavaScript中提供了两种方式迭代对象: for 循环: for..in循环: 1.for循环 不足: 在于每次循环的时候数组的长度都要去获取: 终止条件要明确: 在for循环中,你 ...

  3. TCP/IP协议——ARP详解

    本文主要讲述了ARP的作用.ARP分组格式.ARP高速缓存.免费ARP和代理ARP. 1.学习ARP前要了解的内容 建立TCP连接与ARP的关系 应用接受用户提交的数据,触发TCP建立连接,TCP的第 ...

  4. RabbitMQ 集群与网络分区(理论知识)

    关于network partition网络设备故障导致的网络分裂.比如,存在A\B\C\D\E五个节点,A\B处于同一子网,B\C\D处于另外一子网,中间通过交换机相连.若两个子网间的交换机故障了即发 ...

  5. Java中存取权限和修饰符public、private、protected和default的区别和联系

    java中有4种存取权限和对应的修饰符(从限制最少的开始列出),主要作用如下: 1.public权限最大,代表任何程序代码都可以存取的公开事物(类.变量.方法.构造函数等).它往往用于对外的情况,也就 ...

  6. MySQL使用一张表的字段更新另一张表的字段

    转自https://blog.csdn.net/anxpp/article/details/73173274 update table1 t1 left join table2 t2 on t1.ke ...

  7. 排序1,2......n的无序数组,时间复杂度为o(n),空间复杂度为o(1)

    #include "stdafx.h" #include <iostream> using namespace std; int _tmain(int argc, _T ...

  8. mac升级后idea提示Can't start git

    试了官网的解决方案,还是不行,然后到Stack Overflow上面,找到了下面这个方法,完美解决. 在命令行中运行: xcode-select --install 安装软件就可以了.

  9. BZOJ_1266_[AHOI2006]上学路线route_最小割

    BZOJ_1266_[AHOI2006]上学路线route_最小割 Description 可可和卡卡家住合肥市的东郊,每天上学他们都要转车多次才能到达市区西端的学校.直到有一天他们两人参加了学校的信 ...

  10. BZOJ_4773_负环_倍增弗洛伊德

    BZOJ_4773_负环 Description 在忘记考虑负环之后,黎瑟的算法又出错了.对于边带权的有向图 G = (V, E),请找出一个点数最小的环,使得 环上的边权和为负数.保证图中不包含重边 ...