HTTP
HTTP是不支持持久连接的,HTTP的生命周期通过Request来界定,也就是一个Request 一个Response,在HTTP1.0中,每个http请求响应后都会关闭tcp连接。在HTTP1.1中进行了改进,可以在请求头和响应头中增加字段connection: keep-alive ,多个http 请求共用同一个 tcp 连接,这样可以减少相邻多次 http请求导致的 tcp连接建立和关闭的资源消耗。Response都是被动的,不能主动发起。这意味着在浏览器发起新请求前,服务器不能发送新信息给客户端浏览器。
这种机制对于信息变化不是特别频繁的应用可以良好支撑,但对于实时要求高、海量并发的应用来说显得捉襟见肘,尤其在当前业界移动互联网蓬勃发展的趋势下,高并发与用户实时响应是Web应用经常面临的问题,比如金融证券的实时信息、Web导航应用中的地理位置获取、社交网络的实时消息推送等。
传统的请求-响应模式的Web开发在处理此类业务场景时,通常采用实时通讯方案。比如常见的轮询方案和Comet技术。Comet是轮询的改进又可细分为两种实现方式,一种是长轮询机制,一种称为HTTP流技术,
轮询(polling)
轮询的原理非常简单,让浏览器隔个几秒就发送一次请求,询问服务器是否有新信息。(服务器不管是否有数据到达都直接响应http 请求)
缺点是消息交互的实时性较低,当客户端按固定频率向服务器发起请求,数据可能并没有更新,浪费服务器资源。
长轮询(long polling)
long polling指的是客户端发起连接后,如果有数据,立刻响应请求;如果没有数据 客户端像传统轮询一样从服务端请求数据,服务端会阻塞请求不会立刻返回,直到有数据或超时才返回给客户端,然后关闭连接,客户端处理完响应信息后再向服务器发送新的请求。
server 没有数据到达时,http连接会停留一段时间,这会造成服务器资源浪费。(因为连接的时间长,增大了并发压力)。
从上面可以看出其实这两种方式,都是在不断地建立HTTP连接,然后等待服务端处理,可以体现HTTP协议的一个特点,被动性。不管是长轮询还是短轮询,都不太适用于客户端数量太多的情况,因为每个服务器所能承载的TCP连接数是有上限的,这种轮询很容易把连接数顶满。
iframe流
iframe流方式是在页面中插入一个隐藏的iframe,利用其src属性在服务器和客户端之间创建一条长连接,服务器向iframe传输数据(通常是HTML,内有负责插入信息的javascript),来实时更新页面。
前端实现步骤如下:
- iframe设置为不显示。
- src设为请求的数据地址。
- 定义个父级函数用户让iframe子页面调用传数据给父页面。
- 定义onload事件,服务器timeout后再次重新加载iframe。
WebSocket
WebSocket是基于HTTP协议的,或者说借用了HTTP的协议来完成一部分握手。
只需要经过一次HTTP请求,就可以做到源源不断的信息传送了。(在程序设计中,这种设计叫做回调)。WebSocket只需要一次HTTP握手,所以说整个通讯过程是建立在一次连接/状态中,也就避免了HTTP的非状态性,服务端会一直知道你的信息,直到你关闭请求。
//注意这里的协议变成了ws://
var socket = new WebSocket('ws://www.example.com/server.php');
socket.send('hello');
WebSocket只能发送纯文本信息,所以对于复杂的数据结构,在发送之前必须进行序列化。
var message = {
name: 'sysuzhyupeng',
age: 24
}
socket.send(JSON.stringify(message));
当服务器向客户端发来消息时,WebSocket对象就会触发message事件。这个message事件与其他传递消息的协议类似,也是把返回的数据保存在event.data中
socket.onmessage = function(event){
var data = event.data;
}
WebSocket的支持程度是IE 10+ Edge Firefox 4+ Chrome 4+ Safari 5+ Opera 11.5+