携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第11天,点击查看活动详情
WebSocket
一、什么是websocket
· WebSocket是HTML5下一种新的协议(websocket协议本质上是一个基于tcp的协议)
· 它实现了浏览器与服务器全双工通信,能更好的节省服务器资源和带宽并达到实时通讯的目的
· Websocket是一个持久化的协议
二、websocket的原理
websocket约定了一个通信的规范,通过一个握手的机制,客户端和服务器之间能建立一个类似tcp的连接,从而方便它们之间的通信
在websocket出现之前,web交互一般是基于http协议的短连接或者长连接,
websocket是一种全新的协议,不属于http无状态协议,协议名为"ws"
三、websocket与http的关系
相同点:
1. 都是基于tcp的,都是可靠性传输协议
2. 都是应用层协议
不同点:
1. WebSocket是双向通信协议,模拟Socket协议,可以双向发送或接受信息 。 HTTP是单向的
2. WebSocket是需要浏览器和服务器握手进行建立连接的
3. 而http是浏览器发起向服务器的连接,服务器预先并不知道这个连接
联系:
WebSocket在建立握手时,数据是通过HTTP传输的。但是建立之后,在真正传输时候是不需要HTTP协议的
总结:
首先,客户端发起http请求,经过3次握手后,建立起TCP连接;http请求里存放WebSocket支持的版本号等信息,如:Upgrade、Connection、WebSocket-Version等;
然后,服务器收到客户端的握手请求后,同样采用HTTP协议回馈数据;
最后,客户端收到连接成功的消息后,开始借助于TCP传输信道进行全双工通信。
4、websocket的改进
一旦WebSocket连接建立后,后续数据都以帧序列的形式传输。在客户端断开WebSocket连接或Server端中断连接前,不需要客户端和服务端重新发起连接请求。在海量并发及客户端与服务器交互负载流量大的情况下,极大的节省了网络带宽资源的消耗,有明显的性能优势,且客户端发送和接受消息是在同一个持久连接上发起,实现了“真·长链接”,实时性优势明显。
WebSocket有以下特点:
是真正的全双工方式,建立连接后客户端与服务器端是完全平等的,可以互相主动请求。而HTTP长连接基于HTTP,是传统的客户端对服务器发起请求的模式。
HTTP长连接中,每次数据交换除了真正的数据部分外,服务器和客户端还要大量交换HTTP header,信息交换效率很低。Websocket协议通过第一个request建立了TCP连接之后,之后交换的数据都不需要发送 HTTP header就能交换数据,这显然和原有的HTTP协议有区别所以它需要对服务器和客户端都进行升级才能实现(主流浏览器都已支持HTML5)
5、websocket的功能
(1)通知功能:
保持一个长连接,当服务端游新的消息,能够实时的推送到使用方。像知乎的点赞通知、评论等,都可以使用WebSocket通信。
某些使用H5的客户端,为了简化开发,也会使用WebSocket进行消息的通知,由于它是实时推送的,会有更好的用户体验。
(2)数据收集:
一些次优级别的数据,比如行为日志、trace、异常执栈收集等,都可以开辟专门的WebSocket通道进行传输。这能够增加信息的集中度,并能及时的针对用户的行为进行合适的配置推送。由于大多数浏览器内核都支持,它将使客户端APM编程模型变得简单。
(3)加密 && 认证:
虽然使用Fiddler、Charles等能够抓到很多WebSocket包。但如果同时开启SSL,传输加密后的二进制数据,会大幅增加破解的成本,会安全的多。
(4)反向控制钩子:
由于是双工长连接,服务端完全可以推送一些钩子命令,甚至直接是代码,在客户端进行执行。
6、websocket支持的浏览器
webSocket是基于h5规范的组成部分之一,在2011年的时候正式成为标准,目前chrome、firefox、Opera、safari等主流的浏览器都支持,ie浏览器是从ie10之后也开始支持。我们知道WebSocket是一种在服务器与客户端双向通讯的技术,使用原生的WebSocket可以最小化 服务器资源的使用并且为两者提供了一种统一的通信方式。
7、websocket的事件
一共有 4 个事件:
· open —— 连接已建立
· message —— 接收到数据
· error —— WebSocket 错误
· close —— 连接已关闭
8、websocket数据传输格式
WebSocket 通信由 “frames”(即数据片段)组成,可以从任何一方发送,并且有以下几种类型:
“text frames” —— 包含各方发送给彼此的文本数据。
“binary data frames” —— 包含各方发送给彼此的二进制数据。
“ping/pong frames” 被用于检查从服务器发送的连接,浏览器会自动响应它们。
还有 “connection close frame” 以及其他服务 frames。
在浏览器里,我们仅直接使用文本或二进制 frames
9、websocket在vue中的应用
App.vue中
1.初始化参数
data() {
return {
//服务器的ip
url: "ws://192.168.1.69:8080/websocket/user6",
ws: null,
lockReconnect: false,
websocketTimer: null,
}
},
2. 初始化页面
created() {
//增加时间戳,是每一个用户的都不相同
let time = new Date().getTime()
this.url = this.url + time
this.initWebSocket()
}
3. 初始化方法
// websocket 初始化
initWebSocket() {
if (typeof WebSocket === "undefined") {
this.$message.error("您的浏览器不支持WebSocket")
} else {
this.ws = new WebSocket(this.url)
this.ws.onopen = this.wsOpen
this.ws.onclose = this.wsClose
this.ws.onerror = this.wsError
this.ws.onmessage = this.wsMessage
this.$ws.setWs(this.ws)
}
},
4. 打开websocket
wsOpen(e) {
this.ws.send("websocket开始连接")
console.log(this.$ws)
},
5. 发送消息
wsMessage(e) {
console.log("message", e)
console.log(e.data)
},
6. 报错
wsError(e) {
// console.log("error", e)
console.log("websocket出现错误")
this.reconnect()
},
7. 重新连接
reconnect() {
//重新连接
console.log("开始重连WebSocket")
if (this.lockReconnect) {
return
}
this.lockReconnect = true
//避免没连接上会一直重连
this.websocketTimer && clearTimeout(this.websocketTimer)
this.websocketTimer = setTimeout(() => {
this.initWebSocket()
this.lockReconnect = false
}, 5000)
}
8. 关闭
wsClose(e) {
console.log("websocket已经关闭")
},
在你需要用到的vue页面中
created() {
// 打开webSocKet
this.wsMsg()
},
// methods中
wsMsg() {
let that = this
that.$ws.ws.onmessage = function (e) {
if (!e.data) {
return
}
//判断数据中是否包含task_type这个参数,具体看后台给你传的数据
if (e.data.indexOf("task_type") == -1) {
return
}
// console.log(e.data)
let data = JSON.parse(e.data)
const ExecutorResult = ["releaseType"]
//判断数据是否是自己所需的数据
if (ExecutorResult.includes(data.task_type)) {
console.log(data.data)
}
}
},