1. 为什么需要websocket
第一次接触 WebSocket 的人,都会有这样的问题:我们已经有了 HTTP 协议,为什么还需要另一个协议?它有什么好处?
因为 HTTP 协议有一个缺陷:通信只能由客户端发起。
举例来说:我们想查看某个网页,只能是客户端向服务器发出请求,服务器返回查询结果。HTTP 协议做不到服务器主动向客户端推送信息。
HTTP特点
- 单向通信
- 请求/响应
这种单向请求的特点,使客户要获得服务器连续的推送消息,非常麻烦。我们只能使用"轮询":使用ajax每隔一段时候,就发出一个询问,了解服务器有没有新的信息(如每隔1秒)。最典型的场景就是聊天室。
然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源,效率低(因为必须不停连接,或者 HTTP 连接始终打开),因此发明了WebSocket。
2. websocket简介
在 WebSocket API中,浏览器和服务器只需要完成一个握手的动作,两者之间就可以创建持久性的连接,并进行双向数据传输。
websocket特点
与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。
建立在 TCP 协议之上,服务器端的实现比较容易(连接建立以后,客户端和服务器端就可以通过 TCP 连接直接交换数据)。
数据格式比较轻量,性能开销小,通信高效。
可以发送文本,也可以发送二进制数据。
没有同源限制,客户端可以与任意服务器通信。
协议标识符是ws(如果加密,则为wss),服务器网址就是 URL。
3. 实例
var socket = new WebSocket(url); //创建一个websocket实例 URL链接的地址
WebSocket 属性
- Socket.readyState 只读属性 readyState 表示连接状态,可以是以下值:
- 0 - 表示连接尚未建立。
- 1 - 表示连接已建立,可以进行通信。
- 2 - 表示连接正在进行关闭。
- 3 - 表示连接已经关闭或者连接不能打开。
- Socket.bufferedAmount 只读属性 bufferedAmount 已被 send() 放入正在队列中等待传输,但是还没有发出的 UTF-8 文本字节数。
一个简单实例
var url = 'wss://demo-url.com';
var params = {
a: 1,
b: 2
}
var str = JSON.stringify(params);
var ws = new WebSocket(url);
//连接建立时触发
ws.onopen = function(evt){
//WebSocket 已连接上,使用 send() 方法发送数据
ws.send(str);
console.log(evt);
console.log("数据发送中...");
};
//客户端接收服务端数据时触发
ws.onmessage = function(evt){
var receivedMsg = evt.data;
console.log(evt);
console.log("数据已接收...");
};
//通信发生错误时触发
ws.onerror = function(evt){
console.log(evt);
};
//连接关闭时触发
ws.onclose = function(){
// 关闭 websocket
console.log("连接已关闭...");
};