webSocket的二三事

2017-04-05  本文已影响338人  忽如寄

传统中网站实现实时推送往往是一件比较难的事情,因为HTTP是无状态的,请求只能是由客户端发送,服务器处理这些请求,服务器是被动的,服务器有变化却没有办法将数据主动传输给客户端,传统中解决这种问题主要以下方法:

1、轮询

设定一个定时器发送Ajax请求,当检测数据是否发生变化,它的代码可能如下:

function query() {
    var xhr = new new XMLHttpRequest();
    xhr.open('GET','/data', true);
    xhr.load = function(e) {
        if(e.status == 200) {
            var ret = JSON.parse(e.response);
            if(ret.changed){
                //........
            } else{
                setTimeout(query, 1000);
            }
        }
    }
    xhr.send();
}

query();

轮询的缺点非常明显,首先客户端需要发送大量请求,而服务端需要处理大量请求,这些资源的消耗其实很大一部分都是没有必要的,而且应用的实时性与轮询设定的时间有关。

2、长轮询

长轮询主要利用的是HTTP协议的长连接,当客户端发送一个ajax请求后,服务器查询数据是否有更改,如果有更改就立即返回,没有就hold住请求不返回,这样客户端就会一直处于pending状态,服务器端保持不断查询数据是否更新,一旦更新就返回,这样就做到了数据的实时传递。
显然长轮询消耗的客户端资源较少,但是服务端要hold一个连接同样要消耗部分资源。

这些解决方案都是基于HTTP协议的,而HTTP协议每次请求都需要带上报文头,这需要消耗一定的资源,对于实时应用来说这部分资源算是不小的开销了,而WebSocket将传统的套接字概念引入web,这样在web建立全双工通信通道成为了可能。

WebSocket客户端
WebSocket是一种新的通信协议,新建一个WebSocket协议时需要制定连接的地址,以ws开头,同样与http类似,安全连接以wss开头,客户端建立一个连接只需要调用WebSocket()构造函数即可,这个函数接受一个url参数和一个可选的子协议参数,子协议参数可以是字符串或者数组:

var socket = new WebSocket('wss://localhost/chat', ['soap', 'xmpp']);

一个WebSocket实例主要有以下属性:

if(socket.readyState === 1) {
        console.log('连接已经打开');
}
// or
if(socket.readyState === WebSocket.OPEN){
        console.log('连接已经打开');
}
socket.onmessage = function(e){
        console.log('server send ' + e.data);
}

一个WebSocket实例主要有以下方法:

socket.close();
socket.send('something from client');
上一篇 下一篇

猜你喜欢

热点阅读