Comet
Ajax是一种从页面向服务器请求数据的技术,而Comet则是一种服务器向页面推送数据的技术。Comet能够让信息近乎实时地被推送到页面上
有两种实现Comet的方式:长轮询和流
1、轮询
1)短轮询:浏览器定时向服务器发送请求,看有没有更新数据 2)长轮询:页面发送一个到服务器的请求,然后服务器一直保持打开状态,直到有数据可发送。发送完数据之后,浏览器关闭连接,随即又发起一个到服务器的请求
无论是短轮询还是长轮询,浏览器都要在接收数据之前,先发起浏览器向服务器的连接,轮询的优势是所有浏览器都支持,因为使用xhr对象和settimeout()就能实现。
而你要做的是决定什么时候发送请求
2、流
流不同于上述两种轮询,因为它在页面的整个生命周期内只使用一个http连接。具体来说,就是浏览器向服务器发送一个请求,而服务器保持连接打开,
然后周期性地向浏览器发送数据。
通过侦听readystatechange事件及检测readyState的值是否为3,就可以利用xhr对象实现http流
function createStreamingClient(url,progress,finished){
var xhr = new XMLHttpRequest(),
received = 0;
xhr.open('get',url,true);
xhr.onreadystatechange = function(){
var result;
if(xhr.readyState == 3){
// 只取得最新数据并调整计数器
result = xhr.responseText.substring(received);
received +=result.length;
//调用progress回调
progress(result)
}else if(xhr.readyState == 4){
finished(xhr.responseText)
}
};
xhr.send(null);
return xhr
}
var client = createStreamingClient('localhost/index.php',
function(data){
console.log('Received' + data)
},
function(data){
console.log('Done!');
}
)
这个createStreamingClient()函数接收三个参数:要链接的url、在接收到数据时调用到函数以及关闭这个连接时调用的函数
SSE
SSE(Server-SentEvent,服务器发送事件)。SSE API用于创建到服务器的单向连接,服务器通过这个连接可以发送任意数量的数据。
服务器响应的MIME类型必须是text/event-stream,而且是浏览器中的Javascript API能解析格式输出。SSE支持短轮询、长轮询和HTTP流,
而且能在断开连接时自动确定何时重新连接。
1)SSE API
创建一个新的EventSource对象
eg
var source = new EventSource('myevets.php');
*:传入的URL必须与创建对象的页面同源。EventSource实例有一个readyState属性,值为0表示正连接到服务器,值为1表示打开了连接,值为2表示关闭了连接。
另外,还有以下三个事件
open: 在建立连接时触发。 message: 在从服务器接收到新事件时触发。 error: 在无法建立连接时触发。
source.onmessage = function(event){
var data = event.data;
//处理数据
}
服务器发回的数据以字符串形式保存在event.data中。
默认情况下,EventSource对象会保持与服务器的活动连接。如果连接断开,还会重新连接。这意味着SSE适合长轮询和HTTP流。如果想强制立即断开连接并且不再
重新连接,可以调用close()方法
source.close();
Web Sockets
Web Sockets的目标是在一个单独的持久连接上提供全双工、双向通信。标准的http服务器无法实现web sockes。只有支持这种协议的专门服务器才能正常工作。
由于Web Sockets使用了自定义的协议,所以url模式也略有不同。未加密的连接不再是http://,而是ws://;加密的连接也不是https://,而是wss://。SSE
使用自定义协议的好处是,能够在客户端和服务器之间发送非常少量的数据,而不必担心http那样字节级的开销。
1)Web Sockets API
//创建一个Web Sockets实例
var socket = new WebSocket('ws://www.example.com/server.php');
*:必须给WebSocket构造函数传入绝对url。同源策略对Web Sockets不适用,因此可以通过它打开到人和站点到连接。
与xhr类似,WebSocket也有一个表示当前状态到readyState属性。不过,与xhr并不相同。
WebSocket.OPENING(0):正在建立连接。 WebSocket.OPEN(1):已经建立连接。 WebSocket.CLOSING(2):正在关闭连接。 WebSocket.CLOSE(3):已经关闭连接。
WebSocket没有readystatechange事件;不过,它有其他事件,对应不同到状态。readyState到值永远从0开始。
要关闭Web Socket,可以在任何时候调用close()方法
socket.close();
调用colse()之后,readyState的值立即变为2(正在关闭),而在关闭连接后就会变成3.
2)发送和接收数据
var socket = new WebSocket('ws://www.example.com/server.php');
socket.send('Hello world');
因为Web Sockets只能通过连接发送纯文本数据,对于复杂的数据结构,在通过连接发送之前,必须进行序列化
var message = {
time: new Date(),
text: 'Hello world!',
clientId:'9527'
};
socket.send(JSON.stringify(message));
当服务器向客户端发来消息时,WebSocket对象就会触发message事件。返回数据保存在event.data属性中
socket.onmessage = function(event){
var data = event.data;
//处理数据
}
3)其他事件
open:在成功建立连接时触发 error:在发生错误时触发。连接不能持续。 close:在连接关闭时触发
var socket = new WebSocket('ws://www.example.com/server.php');
socket.onopen = function(){
alert('connection established.');
}
socket.onerror = function(){
alert('connection error.');
}
socket.onclose = function(){
alert('connection closed.');
}
在这三个事件中,只有close事件的event对象you额外的信息。这个事件的事件对象you是三个额外的属性:
wasClean:是一个布尔值,表示连接是否已经明确地关闭; code:服务器返回的数值状态码; reason:一个字符串,包含服务器发回的消息
socket.onclose = function(event){
console.log('Was clean?' + event.wasClean + ' code=' + event.code + ' reason=' + event.reason);
}
使用sse还是web Sockets
1、是否有自由度建立和维护web sockets服务器?
WebSocket协议不同于http,所有现有浏览器不能用于web socket,sse倒是通过常规的http通信,因此现有浏览器都满足需求
2、到底需不需要双向通信
如果只需读取服务器数据,如比赛成绩,那么sse比较容易实现。如果必须双向通信,比如聊天室,那么web sockets显然更好
在不能使用web sockets的情况下,组合xhr和sse也能实现双向通信的
来源:https://www.cnblogs.com/wzndkj/p/8628233.html