愿天下所有的情侣,都是失散多年的兄妹
——好妹妹
webScoket是html5提出的一个协议,咱们用的http是无状态的,且只能由客户端向服务端发起,并且服务端返回结果之后就宣告此次连接结束。为了解决这种问题,出现了轮询(polling)和comet技术。
轮询:
客户端设置一个间隔时间不断的去向服务端发起请求,频繁的查询数据有没有改动,这样增加了请求次数,浪费流量和服务器资源。
comet:
又可以分为长轮询和流技术,长轮询就是指为需要更新的数据设置一个过期时间,过期了才去发起请求,这样就不会很频繁的去发起求情,但服务器仍然是被动的。流技术就是指客户端使用一个隐藏的窗口(iframe)与服务器建立一个http长连接,服务器会不断的更新状态,保持连接的存活,这样做的弊端是在高并发的情况下比较考验服务器的性能。
而webScoket很不一样,基于TCP协议,与http协议兼容、却不会融入http协议,仅仅作为html5的一部分。与http协议不同的请求/响应模式不同,Websocket在建立连接之前有一个Handshake(Opening Handshake)【握手】过程,在关闭连接前也有一个Handshake(Closing Handshake)过程,
建立连接之后,双方即可双向通信。
以上参考自很多博客,这里就不一一贴出了。
webScoket的使用方法
在客户端使用webScoket是非常简单的一件事情。
先看看兼容性:
创建连接
var ws = new WebSocket('ws://localhost:3333');
构造函数接收两个参数:
url: 这里的url不能是http://或者https:// 而是对应的ws://或者wss:// ws和wss是webScoket定义的两种url方案,ws类似于http wss类似于https
protocols:协议名称,是可选的。服务端和客户端的协议名称必须一致。协议有三种:注册协议,开放协议,自定义协议。
webScoket的属性
webScoket就仨属性:
readyState
代表连接的状态有以下四种: 0 表示未连接 1 连接已经建立 2 连接即将关闭 3 连接关闭或不可用bufferedAmount
有时候需要检查传输数据的大小,尤其是客户端传输大量数据的时候。虽然send()方法会马上执行,但数据并不是马上传输。浏览器会缓存应用流出的数据,你可以使用bufferedAmount属性检查已经进入队列但还未被传输的数据大小。这个值不包含协议框架、操作系统缓存和网络软件的开销。
var THRESHOLD = 10240; //限制10k以内
if (ws.bufferedAmount < THRESHOLD) {
ws.send('heheheheeheh');
}
3.protocol: 就是在构造函数中选传的参数。
webScoket的事件
这里的事件,指的是webScoket的状态open、message、error、close。
open
在握手完成是触发,对应的回调函数是onopen,当打开后要做的操作在onopen中添加
ws.onopen = function () {
console.log('连接成功');
}
message
当消息被接收时就会触发此事件,对应的回调是onmessage,webScoket消息机制只支持字符串和二进制(blob和ArrayBuffer)
ws.onmessage = function(res) { // res为接收到的数据
console.log(res)
}
error:
如果发生意外的失败会触发error事件,相应的函数称为onerror,错误会导致连接关闭,同时触发关闭事件。
ws.onerror = function(e) { // e为错误信息
console.log("WebSocket Error: " , e);
};
4.close
close:当连接关闭的时候触发的时间,对用一个onclose方法。
ws.onclose = function(e) { // e为关闭的原因
console.log("Connection closed", e);
};
webScoket的方法
就俩方法send和close。
send
用于向服务端发送一条消息,需要注意的是,此方法应该在onopen事件的回调中执行,因为连接打开之后才能进行数据的传输。只接收一个参数,就是你要传输的数据。
ws.send('你是狗吧?'); // 记得放在onopen方法里面
close
关闭连接,如果连接已经关闭了 那就什么都不会做。接收两个参数code、reason
code: 状态码,如果不传默认就是1000 表示正常关闭 状态码参考https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent
reason: 关闭的原因
ws.close(1000,'没事关一下');
以上客户端的webScoket就介绍完了。真正复杂的是服务端的webScoket,这个还在研究中。下一节再说。