介绍
正常情况下,浏览器访问 Web 页面时,一般会向页面所在的 Web 服务器发送一个 HTTP 请求。Web 服务器识别请求,然后返回响应。大多数情况下,如股票价格、新闻报道、余票查询、交通状况数据等,当内容呈现在浏览器页面上时,可能已经没有时效性。如果用户想要获取最新的实时信息,就需要不断地手动刷新页面,这显然不是一个明智的做法。
使用轮询的方式,浏览器会定期发送 HTTP 请求,并接收响应。这种方式不可避免会产生一些不必要的请求,低消息率情况下会有很多无用的连接不断打开和关闭。
WebSocket 对象提供了一组 API,用于创建和管理 WebSocket 连接,以及通过连接发送和接收数据。
实现
// index.js
const WebSocketServer = require('websocket').server
const server = require('http').createServer()
const ws = new WebSocketServer({
httpServer: server
})
let ind = 1
ws.on('request', function(req) {
const connection = req.accept(null, req.origin)
setInterval(() => {
// 定时向客户端发送数据
connection.sendUTF(ind)
ind = ind + Math.random() * 3
}, 1000 * 5)
// 当有数据推送到 ws 时,就发送到客户端去
// 例如:A和B通话时,当A一发消息给 ws,ws 就发送给B
connection.on('message', function(msg) {
connection.sendUTF(msg.utf8Data)
})
connection.on('close', (resCode, desc) => {
console.log('连接关闭', resCode, desc)
})
})
server.listen(3333, () => {
console.log('服务开启成功在 localhost: 3333')
})
nodemon index.js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<div id="app">
<form onsubmit="return false;">
<input type="text" v-model="msg_a" /><button @click="sendHandle('a')">SendA</button>
<input type="text" v-model="msg_b" /><button @click="sendHandle('b')">SendB</button>
</form>
<ul>
<li v-for="item in list" :key="item">{
{item.type}}:{
{item.ctn}}</li>
</ul>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script>
const {
createApp } = Vue
createApp({
data() {
return {
msg_a: '',
msg_b: '',
ws: null,
list: []
}
},
mounted() {
this.ws = new WebSocket('ws://localhost:3333')
this.ws.onopen = () => {
console.log('连接成功...')
}
this.ws.onmessage = e => {
if(isNaN(e.data)) {
this.list.push(JSON.parse(e.data))
} else {
this.list.push({
type: '定时数据',
ctn: e.data
})
}
}
},
methods: {
sendHandle(type) {
let ctn = this[`msg_${
type}`]
const params = {
type, ctn
}
this.ws.send(JSON.stringify(params))
this[`msg_${
type}`] = ''
}
}
}).mount('#app')
</script>
</body>
</html>
index.js
搭建服务端nodemon index.js
启动服务器localhost:3333
- 直接打开页面
index.html
页面加载完成就会建立ws://localhost:3333
的连接 - 如果不发送数据
index.html
页面会接收到定时数据 - 如果发送数据,点击按钮会通过
ws
发送数据到 ws 服务器,通过 ws 服务器接收到数据会向客户端发送出去
注意:
ws.send()
发送数据时,不可直接传入对象参数,它能接受的参数可以参考官网给出的说明,这里需要保证传入的参数是字符串形式。