目录
2.1.3?监听前端连接websocket(ws.on的connection事件)
2.1.4?服务器接收数据(ws.on的message事件)
3.1.5?前端接收服务器的数据(ws.onmessage)
在 Web 开发领域,我们最常用的协议是 HTTP,HTTP 协议和 WS 协议都是基于 TCP 所做的封装,但是 HTTP 协议它是从一开始便被设计成请求 -> 响应的模式,所以在很长一段时间内 HTTP 都是只能从客户端发向服务端,并不具备从服务端主动推送消息的功能,这也导致在浏览器端想要做到服务器主动推送的效果只能用一些轮询和长轮询的方案来做,但因为它们并不是真正的全双工,所以在消耗资源多的同时,实时性也没理想中那么好。
npm install ws
const WebSocket = require('ws')
// 创建WebSocket服务端的对象,绑定的端口号是9998
// 相当于为ws创建了个接口,这个就是连接websocket的链接,后续前端会用到
const wss = new WebSocket.Server({
port: 9998
})
const WebSocket = require('ws')
// 创建WebSocket服务端的对象,绑定的端口号是9998
const wss = new WebSocket.Server({
port: 9998
})
module.exports.listener = () => {
// 对客户端连接事件进行监听,只要有WebSocket连接到该服务器,就会触发'connection'事件
// ws代表的是客户端的连接的socket对象;req对象可以用来获取客户端的信息,如ip、端口号
wss.on('connection', (ws, req) => {
console.log('有客户端连接成功了', ws, req)
})
}
// 若要获取所有已连接的客户端信息,则可以使用server.clients数据集
const WebSocket = require('ws')
// 创建WebSocket服务端的对象,绑定的端口号是9998
const wss = new WebSocket.Server({
port: 9998
})
module.exports.listener = () => {
wss.on('connection', (ws, req) => {
console.log('有客户端连接成功了', ws, req)
// 对客户端的连接对象进行message事件的监听
// 当客户端有消息发送给服务器时,服务器就能够触发该消息
// msg:由客户端发给服务端的数据
ws.on('message', msg => {
console.log('客户端发送给服务器端', msg)
// 当接收到客户端传的参数之后服务器端可以执行某些操作(具体看需求)
// 小编这里是做了一个数据返回给客户端
// 是当客户端连接成功之后会发送一条信息告诉服务器,服务器监听到信息之后再返回数据给客户端
const data = [
[80, 110, 150, 60, 30, 130, 110],
[80, 120, 150, 80, 40, 120, 112],
[80, 130, 150, 40, 70, 133, 115],
[80, 140, 150, 30, 80, 110, 110],
[80, 130, 150, 70, 100, 140, 115],
[80, 120, 180, 90, 90, 150, 120],
[80, 100, 120, 90, 80, 120, 160]
]
let i = 0
setInterval(() => {
if (i === data.length) {
i = 0
}
// 发送数据给客户端
ws.send(JSON.stringify(data[i]))
i++
}, 1000)
// 由服务端往客户端发送数据
})
})
}
/* send(data [,options][,callback])
data:发送的数据
options对象(可选):
(1)compress:指定数据是否需要压缩。默认为true
(2)binary:指定数据是否通过二进制传送。默认是自动检测
(3)mask:指定是否应遮罩数据。
(4)fin:指定数据是否为消息的最后一个片段。默认为true
*/
const WebSocket = require('ws')
// 创建WebSocket服务端的对象,绑定的端口号是9998
const wss = new WebSocket.Server({
port: 9998
})
const WebSocket = require('ws')
// 创建WebSocket服务端的对象,绑定的端口号是9998
const wss = new WebSocket.Server({
port: 9998
})
module.exports.listener = () => {
wss.on('connection', (ws, req) => {
console.log('有客户端连接成功了', ws, req)
// 对客户端的连接对象进行message事件的监听
// 当客户端有消息发送给服务器时,服务器就能够触发该消息
// msg:由客户端发给服务端的数据
ws.on('message', msg => {
console.log('客户端发送给服务器端', msg)
// 当接收到客户端传的参数之后服务器端可以执行某些操作(具体看需求)
// 小编这里是做了一个数据返回给客户端
// 是当客户端连接成功之后会发送一条信息告诉服务器,服务器监听到信息之后再返回数据给客户端
const data = [
[80, 110, 150, 60, 30, 130, 110],
[80, 120, 150, 80, 40, 120, 112],
[80, 130, 150, 40, 70, 133, 115],
[80, 140, 150, 30, 80, 110, 110],
[80, 130, 150, 70, 100, 140, 115],
[80, 120, 180, 90, 90, 150, 120],
[80, 100, 120, 90, 80, 120, 160]
]
let i = 0
setInterval(() => {
if (i === data.length) {
i = 0
}
// ========发送数据给客户端========
ws.send(JSON.stringify(data[i]))
i++
}, 1000)
// 由服务端往客户端发送数据
})
})
}
const WebSocket = require('ws')
// 创建WebSocket服务端的对象,绑定的端口号是9998
const wss = new WebSocket.Server({
port: 9998
})
module.exports.listener = () => {
wss.on('connection', (ws, req) => {
ws.on('message', msg => {
console.log('客户端发送给服务器端', msg.toString('utf8'))
const data = [
[80, 110, 150, 60, 30, 130, 110],
[80, 120, 150, 80, 40, 120, 112],
[80, 130, 150, 40, 70, 133, 115],
[80, 140, 150, 30, 80, 110, 110],
[80, 130, 150, 70, 100, 140, 115],
[80, 120, 180, 90, 90, 150, 120],
[80, 100, 120, 90, 80, 120, 160]
]
let i = 0
// 模拟了由服务端往客户端发送数据
setInterval(() => {
if (i === data.length) {
i = 0
}
// 服务器向前端发送数据
ws.send(JSON.stringify(data[i]))
i++
}, 1000)
})
// 监听要关闭连接的函数
ws.on('close', function close () {
// 这里面关闭的逻辑
console.log('WebSocket连接已关闭')
})
})
}
—— 至此,后端的websocket逻辑其实已经完结了
// express具体使用看我提供个文章中有
const express = require('express')
const app = express()
const port = 3001
// app.get('/', (req, res) => res.send('hello express'))
// express提供了一个非常好用的函数,叫做express.static(),能快速托管静态资源的内置中间件
// 如下配置是将public目录下的图片、css文件、JavaScript文件对外开放访问
app.use('/', express.static('public'))
// 解析 JSON 格式的请求体数据
app.use(express.json())
// 监听设置的端口
app.listen(port, () => { console.log('server is running,port is' + port) })
// 监听开启的websocket服务器
const websocketservice = require('./web_socket_service')
websocketservice.listener()
(注意:小编这里使用的是一个echarts可视化的动态展示,也方便以后大家使用可视化大屏时有一定的参考价值)
<template>
<div>
<div id='main' style="width:800px;height:600px"></div>
</div>
</template>
<script>
import * as echarts from 'echarts'
// 引入ws,路径是后端配置好给前端的
const ws = new WebSocket('ws://localhost:9998')
export default {
data () {
return {
}
},
mounted () {
// 要想展示实时效果,需要对series配置下的data数据进行实时的监听
const options = {
title: {
text: '数量统计'
},
xAxis: {
data: ['衣服', '牛奶', '巧克力', '矿泉水', '方便面', '面包', '花生']
},
yAxis: {},
series: [
{
name: '销量',
type: 'line',
data: [100, 150, 120, 90, 30, 130, 110]
}
]
}
const mychart = echarts.init(document.getElementById('main'))
ws.onopen = () => {
console.log('连接服务器端成功')
ws.send('Hello websocket')
}
ws.onerror = () => {
console.log('连接服务器失败')
}
ws.onmessage = (msg) => {
console.log('接收到服务端发送的数据')
console.log('msg', msg)
console.log(JSON.parse(msg.data))
options.series[0].data = JSON.parse(msg.data)
mychart.setOption(options)
// ws.send('Hello websocket to message')
}
},
beforeDestroy () {
ws.onclose = () => {
console.log('websocket已关闭')
}
},
components: {
}
}
</script>
<template>
<div>
<div id='main' style="width:800px;height:600px"></div>
</div>
</template>
<script>
import * as echarts from 'echarts'
// 引入ws,路径是后端配置好给前端的
// 小编在这里引入的目的是除了要展示连接成功,还需要执行关闭连接的逻辑,两者不在相同的生命周期钩子中执行
const ws = new WebSocket('ws://localhost:9998')
export default {
data () {
return {
}
},
mounted () {
},
beforeDestroy () {
},
components: {
}
}
</script>
// 打开连接
ws.onopen = () => {
console.log('连接服务器端成功')
// 如果与ws连接成功,我们发送消息跟服务器说一下已经连接
ws.send('Hello websocket')
}
ws.onerror = () => {
console.log('连接服务器失败')
}
// 接收服务器传的数据,msg,每当数据发生变化,后端都会返回数据到前端
// 该方法会一直都在监听ws返回的数据,然后不断的更新我的的图表,从而模拟实现了一个websocket的demo
ws.onmessage = (msg) => {
console.log('接收到服务端发送的数据')
console.log('msg', msg)
// 这里面就可以处理数据的逻辑了
console.log(JSON.parse(msg.data))
options.series[0].data = JSON.parse(msg.data)
mychart.setOption(options)
}
beforeDestroy () {
ws.onclose = () => {
console.log('websocket已关闭')
}
},
-- 至此,前端代码结束
看到最后了,提示一下,如果还是前后端分开开发时,前端处理其实并没有那么复杂,只需要了解第三章的结构即可。?