1、web端即时通讯开发总结

web端即时通讯开发总结

浏览器原理: 客户端请求服务器->服务器返回结果

结论:web 通讯必须通过 服务器进行信息转发。


1、 浏览器拉取 服务器数据,服务器推送到浏览器(短轮询、长轮询、还存在一种基于http-stream流的通信方式)

短轮询 :由于每次都要发送一个请求,服务端不管数据是否发生变化都发送数据,请求完成后连接关闭。这中间经过的很多通信是不必要的

长轮询:这种方式是客户端发送一个请求到服务器,服务器查看客户端请求的数据是否发生了变化(是否有最新数据),如果发生变化则立即响应返回,否则保持这个连接并定期检查最新数据,直到发生了数据更新或连接超时。同时客户端连接一旦断开,则再次发出请求,这样在相同时间内大大减少了客户端请求服务器的次数

http-stream流:让客户端在一次请求中保持和服务端连接不断开,然后服务端源源不断传送数据给客户端,就好比数据流一样,并不是一次性将数据全部发给客户端。它与polling方式的区别在于整个通信过程客户端只发送一次请求,然后服务端保持与客户端的长连接,并利用这个连接在回送数据给客户端。

SSE(服务器推送事件(Server-sent Events)

为了解决浏览器只能够单向传输数据到服务端,HTML5提供了一种新的技术叫做服务器推送事件SSE(关于该技术详细介绍请参见《SSE技术详解:一种全新的HTML5服务器推送事件技术》),它能够实现客户端请求服务端,然后服务端利用与客户端建立的这条通信连接push数据给客户端,客户端接收数据并处理的目的。从独立的角度看,SSE技术提供的是从服务器单向推送数据给浏览器的功能,但是配合浏览器主动请求,实际上就实现了客户端和服务器的双向通信。它的原理是在客户端构造一个eventSource对象,该对象具有readySate属性,分别表示如下:

0:正在连接到服务器;

1:打开了连接;

2:关闭了连接。

同时eventSource对象会保持与服务器的长连接,断开后会自动重连,如果要强制连接可以调用它的close方法。可以它的监听onmessage事件,服务端遵循SSE数据传输的格式给客户端,客户端在onmessage事件触发时就能够接收到数据,从而进行某种处理


代码如下:

跨域问题:通常客户端浏览器和服务器都是处于网络的不同位置,浏览器本身不允许通过脚本直接访问不同域名下的服务器,即使IP地址相同域名不同也不行,域名相同端口不同也不行,这方面主要是为了安全考虑。


基于XHR的COSR(跨域资源共享)

CORS(跨域资源共享)是一种允许浏览器脚本向出于不同域名下服务器发送请求的技术,它是在原生XHR请求的基础上,XHR调用open方法时,地址指向一个跨域的地址,在服务端通过设置'Access-Control-Allow-Origin':'*'响应头部告诉浏览器,发送的数据是一个来自于跨域的并且服务器允许响应的数据,浏览器接收到这个header之后就会绕过平常的跨域限制,从而和平时的XHR通信没有区别。该方法的主要好处是在于客户端代码不用修改,服务端只需要添加'Access-Control-Allow-Origin':'*'头部即可。适用于ff,safari,opera,chrome等非IE浏览器。跨域的XHR相比非跨域的XHR有一些限制,这是为了安全所需要的,主要有以下限制:

1、客户端不能使用setRequestHeader设置自定义头部;

2、不能发送和接收cookie;

3、调用getAllResponseHeaders()方法总会返回空字符串。



基于XDR的CORS(IE8-10)

对于IE8-10,它是不支持使用原生的XHR对象请求跨域服务器的,它自己实现了一个XDomainRequest对象,类似于XHR对象,能够发送跨域请求,它主要有以下限制:

1、cookie不会随请求发送,也不会随响应返回;

2、只能设置请求头部信息中的Content-Type字段;

3、不能访问响应头部信息;

4、只支持Get和Post请求;

5、只支持IE8-IE10。


基于JSONP的跨域

这种方式不需要在服务端添加Access-Control-Allow-Origin头信息,其原理是利用HTML页面上script标签对跨域没有限制的特点,让它的src属性指向服务端请求的地址,其实是通过script标签发送了一个http请求,服务器接收到这个请求之后,返回的数据是自己的数据加上对客户端JS函数的调用,其原理类似于我们上面所说的iframe流的方式,客户端浏览器接收到返回的脚本调用会解析执行,从而达到更新界面的目的。



注意这里服务端输出的数据content-type首部要设定为application/javascript,否则某些浏览器会将其当做文本解析。

WebSocket

在上面的这些解决方案中,都是利用浏览器单向请求服务器或者服务器单向推送数据到浏览器这些技术组合在一起而形成的hack技术,在HTML5中,为了加强web的功能,提供了websocket技术,它不仅是一种web通信方式,也是一种应用层协议。它提供了浏览器和服务器之间原生的双全工跨域通信,通过浏览器和服务器之间建立websocket连接(实际上是TCP连接),在同一时刻能够实现客户端到服务器和服务器到客户端的数据发送。关于该技术的原理,请参见:《WebSocket详解(一):初步认识WebSocket技术》、《WebSocket详解(二):技术原理、代码演示和应用案例》、《WebSocket详解(三):深入WebSocket通信协议细节》,此处就不在赘述了,直接给出代码。在看代码之前,需要先了解websocket整个工作过程。

首先是客户端new 一个websocket对象,该对象会发送一个http请求到服务端,服务端发现这是个webscoket请求,会同意协议转换,发送回客户端一个101状态码的response,以上过程称之为一次握手,经过这次握手之后,客户端就和服务端建立了一条TCP连接,在该连接上,服务端和客户端就可以进行双向通信了。这时的双向通信在应用层走的就是ws或者wss协议了,和http就没有关系了。所谓的ws协议,就是要求客户端和服务端遵循某种格式发送数据报文(帧),然后对方才能够理解。


关于ws协议要求的数据格式官网指定如下:

其中比较重要的是FIN字段,它占用1位,表示这是一个数据帧的结束标志,同时也下一个数据帧的开始标志。opcode字段,它占用4位,当为1时,表示传递的是text帧,2表示二进制数据帧,8表示需要结束此次通信(就是客户端或者服务端哪个发送给对方这个字段,就表示对方要关闭连接了)。9表示发送的是一个ping数据。mask占用1位,为1表示masking-key字段可用,masking-key字段是用来对客户端发送来的数据做unmask操作的。它占用0到4个字节。Payload字段表示实际发送的数据,可以是字符数据也可以是二进制数据。

所以不管是客户端和服务端向对方发送消息,都必须将数据组装成上面的帧格式来发送。


服务端通过监听data事件来获取客户端发送来的数据,如果是握手请求,则发送http 101响应,否则解析得到的数据并打印出来,然后判断是不是断开连接的请求(Opcode为8),如果是则断开连接,否则将接收到的数据组装成帧再发送给客户端。


客户端创建一个websocket对象,在onopen时间触发之后(握手成功后),给页面上的button指定一个事件,用来发送页面input当中的信息,服务端接收到信息打印出来,并组装成帧返回给日客户端,客户端再append到页面上。

效果


从上面可以看出,WebSocket在支持它的浏览器上确实提供了一种全双工跨域的通信方案,所以在各以上各种方案中,我们的首选无疑是WebSocket。



上面论述了这么多对于IM应用开发所涉及到的通信方式,在实际开发中,我们通常使用的是一些别人写好的实时通讯的库,比如socket.iosockjs,他们的原理就是将上面(还有一些其他的如基于Flash的push)的一些技术进行了在客户端和服务端的封装,然后给开发者一个统一调用的接口。这个接口在支持websocket的环境下使用websocket,在不支持它的时候启用上面所讲的一些hack技术。



sockjs在不同浏览器下面采取的不同组合方式:

从图上可以看出,对于现代浏览器(IE10+,chrome14+,Firefox10+,Safari5+以及Opera12+)都是能够很好的支持WebSocket的,其余低版本浏览器通常使用基于XHR(XDR)的polling(streaming)或者是基于iframe的的polling(streaming),对于IE6\7来讲,它不仅不支持XDR跨域,也不支持XHR跨域,所以只能够采取jsonp-polling的方式。

本文引用与即时通讯网

更多文章:socket.io 详情

返回 🔙文章论题首页

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 151,511评论 1 330
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 64,495评论 1 273
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 101,595评论 0 225
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 42,558评论 0 190
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 50,715评论 3 270
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 39,672评论 1 192
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,112评论 2 291
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 29,837评论 0 181
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,417评论 0 228
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 29,928评论 2 232
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,316评论 1 242
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 27,773评论 2 234
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,253评论 3 220
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,827评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,440评论 0 180
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 34,523评论 2 249
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 34,583评论 2 249