定义
1、websocket是html5的的一个重要组件;
2、WebSocket 是一种基于ws协议的技术。使用它可以在客户端与服务器之间建立一段连续的、全双工的连接。它弥补了http不适合实时通信的重大缺陷。
特点
(1)服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种。
(2)建立在 TCP 协议之上,服务器端的实现比较容易。
(3)与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。
(4)数据格式比较轻量,性能开销小,通信高效。
(5)可以发送文本,也可以发送二进制数据。
(6)没有同源限制,客户端可以与任意服务器通信。
(7)协议标识符是ws(如果加密,则为wss),服务器网址就是 URL。
协议的握手过程
在客户端和服务端一开始握手的期间,http协议升级到WebSocket协议就建立了连接,底层都是TCP协议。一旦建立连接,通过WebSocket接口可以反复的发送消息。
为了建立WebSocket连接,客户端发送WebSocket握手请求,服务器返回一个WebSocket握手响应;
客户端请求:
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com
服务端响应:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat
websocket API
创建websocket实例
首先,我们需要通过调用WebSocket构造函数来创建一个WebSocket连接,构造函数会返回一个WebSocket实例,可以用来监听事件。这些事件会告诉你什么时候连接建立,什么时候消息到达,什么时候连接关闭了,以及什么时候发生了错误。WebSocket协议定义了两种URL方案,WS和WSS分别代表了客户端和服务端之间未加密和加密的通信。WS(WebSocket)类似于Http URL,而WSS(WebSocket Security)URL 表示连接是基于安全传输层(TLS/SSL)和https的连接是同样的安全机制。
WebSocket的构造函数需要一个URL参数和一个可选的协议参数(一个或者多个协议的名字),协议的参数例如XMPP(Extensible Messaging and Presence Protocol)、SOAP(Simple Object Access Protocol)或者自定义协议,服务端和客服端使用的协议必须一致,这样收发消息彼此才能理解。而URL参数需要以WS://或者WSS://开头,例如:ws://www.websocket.org,如果URL有语法错误,构造函数会抛出异常。
// WebSocket 对象作为一个构造函数,用于新建 WebSocket 实例
const ws = new WebSocket('ws://localhost:8282');
websocket事件
WebSocket API是纯事件驱动,通过监听事件可以处理到来的数据和改变的链接状态。客户端不需要为了更新数据而轮训服务器。服务端发送数据后,消息和事件会异步到达。WebSocket编程遵循一个异步编程模型,只需要对WebSocket对象增加回调函数就可以监听事件。你也可以使用addEventListener()方法来监听。
Open
一旦服务端响应WebSocket连接请求,就会触发open事件。响应的回调函数称为onopen。
ws.onopen=function(){
console.log('connection is opened!');
}
// 指定多个回调函数
ws.addEventListener('open', function (event) {
console.log(‘connection is open!’);
});
open事件触发的时候,意味着协议握手结束,WebSocket已经准备好收发数据。如果你的应用收到open事件,就可以确定服务端已经处理了建立连接的请求,且同意和你的应用通信。
Message
当消息被接受会触发消息事件,响应的回调函数叫做onmessage。接收的消息类型有文本信息、二进制数据(blob和ArrayBuffer两种类型)。
ws.onmessage = function(e) {
const data = e.data;
}
Error
如果发生意外的失败会触发error事件,相应的函数称为onerror,错误会导致连接关闭。如果你收到一个错误事件,那么你很快会收到一个关闭事件,在关闭事件中也许会告诉你错误的原因。
ws.onerror = function(e){
console.log('websocket error', e);
handleErrors(e);
}
Close
当连接关闭的时候回触发这个事件,对应onclose方法,连接关闭之后,服务端和客户端就不能再收发消息。
ws.onclose=function(e){
console.log('websocket closed', e);
console.log(e.code);
console.log(e.reason);
console.log(e.wasClean);
}
关闭事件有三个属性可以用来做异常处理和重获: wasClean,code和reason。wasClean是一个bool值,代表连接是否干净的关闭。 如果是响应服务端的close事件,这个值为true,如果是别的原因,比如因为是底层TCP连接关闭,wasClean为false。code和reason代表关闭连接时服务端发送的状态;
websocket方法
ws.send()
一旦建立了连接,实例对象的send()方法可用于向服务器发送数据。(文本、blob对象、ArrayBuffer对象:类型化数组)
ws.send('message');
ws.close()
使用close方法来关闭连接,如果连接已经关闭,这方法将什么也不做。调用close方法之后,将不能发送数据。
websocket属性
WebSocket对象有三个属性,readyState,bufferedAmount和Protocol。
readyState 常量
返回实例对象的当前状态,共有四种
CONNECTING:值为0,表示正在连接。
OPEN:值为1,表示连接成功,可以通信了。
CLOSING:值为2,表示连接正在关闭。
CLOSED:值为3,表示连接已经关闭,或者打开连接失败。
bufferedAmount
有时候需要检查传输数据的大小,尤其是客户端传输大量数据的时候。虽然send()方法会马上执行,但数据并不是马上传输。浏览器会缓存应用流出的数据,你可以使用bufferedAmount属性检查已经进入队列但还未被传输的数据大小。
protocol
在构造函数中,protocol参数让服务端知道客户端使用的WebSocket协议。而WebSocket对象的这个属性就是指的最终服务端确定下来的协议名称,当服务端没有选择客户端提供的协议或者在连接握手结束之前,这个属性都是空的。
ws.onopen=function(){
console.log(ws.protocol);
}