一、webSocket原理
1.为什么有HTTP,还要用websocket?
-
因为 HTTP 协议有一个缺陷:通信只能由客户端发起,不具备服务器推送能力。
-
举例来说,我们想了解查询今天的实时数据,只能是客户端向服务器发出请求,服务器返回查询结果。HTTP 协议做不到服务器主动向客户端推送信息。
在 WebSocket 协议出现以前,创建一个和服务端进双通道通信的 web 应用,需要依赖HTTP协议,进行不停的轮询,这会导致一些问题:
-
服务端被迫维持来自每个客户端的大量不同的连接
-
大量的轮询请求会造成高开销,比如会带上多余的header,造成了无用的数据传输。
2.HTTP和WebSocket的区别
-
相同点: 都是一样基于TCP的,都是可靠性传输协议。都是应用层协议。
联系: WebSocket在建立握手时,数据是通过HTTP传输的。但是建立之后,在真正传输时候是不需要HTTP协议的。
-
不同点:
1、 WebSocket 是双向通信协议,模拟 Socket 协议,可以双向发送或接受信息,而 HTTP 是单向的;
2、 WebSocket 是需要浏览器和服务器握手进行建立连接的,而 http 是浏览器发起向服务器的连接。
3、 虽然 HTTP/2 也具备服务器推送功能,但 HTTP/2 只能推送静态资源,无法推送指定的信息。
3.WebSocket协议优缺点
优点:
-
WebSocket协议一旦建议后,互相沟通所消耗的请求头是很小的
-
服务器可以向客户端推送消息了
缺点:
-
少部分浏览器不支持,浏览器支持的程度与方式有区别(IE10)
二、websocket的使用
websocket对象提供了用于创建和管理的websocket连接,以及可以通过该连接发送和接收数据API
webSocket事件
websocket方法
创建连接
-
websocket构造函数,创建websocket对象
-
参数url:指定连接的 URL,接口地址。
-
参数 protocol 是可选的,指定了可接受的子协议。
一个协议字符串或者一个包含协议字符串的数组,这些字符串用于指定子协议,这样单个服务器可以实现多个WebSocket子协议(可以通过一台服务器根据指定的协议(protocols处理不同类型的交互),如果不指定协议字符串,则假定为空字符串)
//websocket构造函数,创建websocket对象
var ws = new WebSocket(url,protocols)
连接成功后的回调函数ws.onopen()
连接成功后的回调函数,当websocket的连接状态readyState变为1时调用这意味着准备好发送和接受数据
var ws = new WebSocket('url')
ws.onopen = function(params){
console.log('连接成功')
//向服务器发送消息
ws.send('hello')
}
或者
var ws = new WebSocket('url')
ws.addEventListener('open',function(event){
ws.send('连接成功')
})
从服务器接收信息时的回调函数ws.onmessage()
var sw = new WebSocket('url')
ws.onmessage = function(event){
console.log('收到服务器响应',event.data)
var data = event.data
}
或者
var ws = new WebSocket('url')
ws.addEventListener('message',function(event){
var data = event.data
})
连接完毕后的回调函数ws.onclose()
var ws = new WebSocket('url')
ws.onclose = function(event){
console.log('关闭客户端连接')
var code = event.code;//表示服务端发送的关闭码
var reason = event.reason;//表示服务器关闭连接的原因
var wasClean = event.wasClean//表示连接是否完全关闭
}
或者
var ws = new WebSocket('url')
ws.addEventListener('close',function(event){
console.log('关闭客户端连接')
var code = event.code;//表示服务端发送的关闭码
var reason = event.reason;//表示服务器关闭连接的原因
var wasClean = event.wasClean//表示连接是否完全关闭
})
连接失败后的回调函数ws.onerror()
var ws = new WebSocket('url')
ws.onerror = function(event){
console.log('连接失败',event)
ws.send('连接失败')
}
或者
var ws = new WebSocket('url')
ws.addEventListener('error',function(event){
console.log('连接失败',event)
ws.send('连接失败')
})
三、心跳
心跳 是 websocket 中的一个概念,就是在 websocket 中用定时器,定时向服务器发送一个消息内容,我们约定,如果后端收到这个消息内容,就要向前端回一个消息内容。如果前端没有收到消息回复,则有可能 websocket 断掉了,那么就要进行重连操作,来保证我们的 websocket 处于连接状态。
let url = `${process.env['VUE_APP_WEBSOCKET']}/websocket`
let ws = new WebSocket(url)
ws.addEventListener('open', e => {
console.log('长连接连接成功')
// 执行心跳方法
dispatch('wsHeartStart')
})
readyState返回实例对象的当前状态
switch (ws.readyState) {
case WebSocket.CONNECTING://可以用0,CONNECTING值为0,表示正在连接
//dosomething
break;
case WebSocket.OPEN://值为1,OPEN值为1,表示连接成功可以通信
//dosomething
break;
case WebSocket.CLOSING://CLOSING值为2,表示连接正在关闭
//dosomething
break;
case WebSocket.CLOSED://CLOSED值为3,表示打开连接失败或连接已经关闭
//dosomething
break;
default:
//this never happens
break;
}