一、为什么需要WebSocket
因为HTTP协议有一个缺陷:通信只能由客户端发起,HTTP协议做不到服务器主动向客户端推送消息,只能是客户端向服务器发出请求,服务器返回查询结果。
如果服务器有连续的状态变化,客户端想要获知,我们只能通过轮询(每隔一段时间发出一个请求,了解服务器有没有新的信息),但轮询的效率低,浪费资源(需要不停建立连接或者HTTP连接始终打开,且HTTP请求可能包含较长的头部,但其中真正有效的数据可能只是很小的一部分),由此出现了WebSocket。
二、简介
WebSocket是HTML5开始提供的一种在单个TCP连接上进行全双工通讯的协议。
浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
特点:
- 服务器和客户端间可以进行双向平等的对话
- 建立在TCP协议之上,服务器端的实现比较容易
- 与HTTP协议有良好的兼容性。
- 数据格式比较轻量,性能开销小,通信高效。
- 可以发送文本、二进制数据。
- 没有同源限制,客户端可以与任意服务器通信。
- 协议标识符是ws,如果加密则为wss,服务器网址是URL。
三、API
1.WebSocket构造函数
<!--新建WebSocket实例,执行后客户端就会与服务器进行连接-->
var ws = new WebSocket('ws://localhost:8080')
2.ws.readyState
readyState属性返回实例对象的当前状态
- CONNECTING:0, 表示正在连接
- OPEN:1,表示连接成功,可以进行通信
- CLOSING:2,表示连接正在关闭
- CLOSED:3,表示连接已经关闭,或者打开连接失败
在不同的状态可以进行你的一些处理
3.事件
| 事件 | 回调函数 | 描述 |
|---|---|---|
| open | ws.onopen | 连接建立时触发 |
| message | ws.onmessage | 客户端接收服务端数据时触发 |
| error | ws.onerror | 通信发生错误时触发 |
| close | ws.onclose | 连接关闭时触发 |
4.方法
| 方法 | 描述 |
|---|---|
| ws.send() | 使用连接发送数据 |
| ws.close() | 关闭连接 |
四、应用
以下是WebSocket在Vue中应用的例子
<script>
data () {
return {
lockReconnect: false,
socketUrl: 'ws://yours url:80/something others',
websocket: ''
}
},
created () {
this.initWebSocket()
},
destoryed () {
this.websocketOnclose()
}
methods: {
initWebSocket () {
<!-- 初始化WebSocket连接 -->
this.websocket = new WebSocket(url)
this.websocket.onopen = this.websocketOnopen
this.websocket.onerror = this.websocketOnmessage
this.websocket.onclose = this.websocketOnclose
},
websocketOnopen () {
<!--WebSocket 已连接上,使用 send() 方法发送数据-->
this.websocket.send("发送数据...")
},
websocketOnerror () {
<!--连接出错-->
this.reconnect()
},
websocketOnclose () {
<!--关闭 websocket-->
console.log("连接已关闭...");
this.reconnect()
},
websocketOnmessage (evt) {
let received_msg = JSON.parse(evt.data)
console.log("数据已接收...")
},
reconnect () {
const _this = this
if (_this.lockReconnect) {
return
}
_this.lockReconnect = true
<!--没连接上会一直重连,设置延迟避免请求过多。-->
setTimeout(() => {
_this.initWebSocket()
_this.lockReconnect = false
}, 5000)
},
isJSON(str) {
<!--判断是否为JSON格式-->
if (typeof str === "string") {
try {
const obj = JSON.parse(str)
if (typeof obj === "object" && obj) {
return true
} else {
return false
}
} catch (e) {
return false
}
}
}
}
</script>