后端代码改造
创建 service\web_socket_service.js 文件
- 客户链接成功 转义msg 成对象 判断 msg.action 是不是getData
- 是的话 拼接路径名 使用工具函数 获得 ret 赋值给 payload.data 转成json 返回给客户端
- 不是的话 原封不动的将从某一个客户端发过来的数据转发给每一个处于连接状态
的客户端
const path = require('path')
const fileUtils = require('../utils/file_utils')
const WebSocket = require('ws')
const wss = new WebSocket.Server({
module.exports.listen = () => {
wss.on('connection',client => {
client.on('message',async msg => {
console.log('客户端发送数据给服务端了:' + msg)
let payload = JSON.parse(msg)
const action = payload.action
if (action === 'getData'){
let filePath = '../data/' + payload.chartName + '.json'
filePath = path.join(__dirname,filePath)
const ret = await fileUtils.getFileJsonData(filePath)
client.send(JSON.stringify(payload))
wss.clients.forEach(client => {
在app.js 中引入
在
app.js
中引入
web_socket_service.js
这个文件
,
并调用
listen
方法
const Koa = require('koa')
const resDuration = require('./middleware/response_duration')
const resHeader = require('./middleware/response_header')
const resData = require('./middleware/response_data')
const webSocketService = require('./service/web_socket_service')
webSocketService.listen()
前端代码的改造
定义单例,创建 WebSocket 实例对象
创建
src/utils/socket_service.js
文件
定义单例
- 类只有一个实例
- 全局可访问
- 推迟初始化(与静态类,对象的区别)
- 主动实例化
- 例如Vuex
export default class SocketService {
this.instance = new SocketService()
监听 WebSocket 事件
定义
connect
函数
,
将创建的
WebSocket
赋值给实例属性 并且监听链接事件
export default class SocketService {
return console.log('您的浏览器不支持 WebSocket!')
this.ws = new WebSocket('ws://localhost:9998')
console.log('WebSocket 连接成功')
this.ws.onmessage = msg => {
console.log('WebSocket 接收到数据')
定义注册函数
记录一下当得到数据时
,
应该调用的函数回调
export default class SocketService {
registerCallBack (socketType, callBack) {
this.callBackMapping[socketType] = callBack
unRegisterCallBack (socketType) {
this.callBackMapping[socketType] = null
main.js中连接服务端
在 main.js 中连接服务器端
import SocketService from "@/utils/socket_service";
// 对服务器进行webSocket的链接
SocketService.Instance.connect()
// 原型上挂载 this.$socket
Vue.prototype.$socket = SocketService.Instance
发送数据给服务端
export default class SocketService {
this.ws.send(JSON.stringify(data))
客户端和服务端的连接并不会立马连接成功
,
在处于连接状态下就调用
send
是发送不成功的
,
因此需要修改
service_socket.js
中的
send
方法进行容错处理
新增一些变量 用于标识控制
// 和服务器端链接的socket对象
ws = null
// 储存回调函数
callBackMapping = {}
// 标识是否链接成功
connected = false
// 记录重试的次数
sendRetryCount = 0
// 重新尝试链接的次数
connectRetryCount = 0
断开重连机制
如果初始化连接服务端不成功
,
或者连接成功了
,
后来服务器关闭了
,
这两种情况都会触发
onclose
事件
, 我们需要在这个事件中,
进行重连
this.connectRetryCount = 0
}, 200 * this.connectRetryCount)
socket_service.js完整的代码
export default class SocketService {
this.instance = new SocketService()
return console.log('您的浏览器不支持WebSocket')
this.ws = new WebSocket('ws://localhost:9998')
this.connectRetryCount = 0
this.ws.onclose = () => {
},500 * this.connectRetryCount)
this.ws.onmessage = msg => {
console.log('从服务器获取到了数据')
const recData = JSON.parse(msg.data)
const socketType = recData.socketType
if(this.callBackMapping[socketType]){
const action = recData.action
if (action === 'getData'){
const realData = JSON.parse(recData.data)
this.callBackMapping[socketType].call(this,realData)
}else if (action === 'fullScreen'){
this.callBackMapping[socketType].call(this,recData)
}else if (action === 'themeChange'){
this.callBackMapping[socketType].call(this,recData)
registerCallBack(socketType,callBack){
this.callBackMapping[socketType] = callBack
unRegisterCallBack(socketType){
this.callBackMapping[socketType] = null
this.ws.send(JSON.stringify(data))
},500 * this.sendRetryCount)