http://www.ruanyifeng.com/blog/2017/05/websocket.html

https://github.com/theturtle32/WebSocket-Node

前端服务:方法1

npm install websocket // "websocket": "^1.0.32",
  1. 新建 websocket.js 文件
import WebSocketClient from 'websocket'

/*心跳检测*/
class heartCheck {
  constructor(e) {
    this.timeout = 60000 //60秒
    this.timeoutObj = null
    this.serverTimeoutObj = null
  }

  reset() {
    clearTimeout(this.timeoutObj)
    clearTimeout(this.serverTimeoutObj)
    return this
  }

  start(websock) {
    this.timeoutObj = setTimeout(function () {
      //这里发送一个心跳,后端收到后,返回一个心跳消息,
      //onmessage拿到返回的心跳就说明连接正常
      websock.send("HeartBeat")
      this.serverTimeoutObj = setTimeout(function () {//如果超过一定时间还没重置,说明后端主动断开了
        websock.close()//如果onclose会执行reconnect,我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
      }, this.timeout)
    }, this.timeout)
  }
}

export default class websocket {
  constructor(wsurl, callback) {
    if(callback && typeof callback === 'function'){
      this.global_callback = callback
    }else{
      this.global_callback = null
    }
    this.lockReconnect = false;//避免重复连接
    this.initWebSocket(wsurl, callback)
  }

  initWebSocket(wsurl, callback) {
    this.websock = new WebSocketClient.w3cwebsocket(wsurl, 'echo-protocol')
    /*初始化weosocket*/
    this.websock.onopen = () => {
      // 连接成功
      console.log('连接成功')
    };
    this.websock.onerror = () => {
      // 初始化失败,继续连接
      if (this.lockReconnect) return;
      this.lockReconnect = true;
      setTimeout(() => {
        new websocket(wsurl, callback)
        this.lockReconnect = false;
      }, 2000);
    };
    this.websock.onmessage = (e) => {
      // 接收数据
      new heartCheck().reset().start(this.websock)
      this.websocketOnMessage(e);
    };
    this.websock.onclose = (e) => {
      // 关闭
      this.websock.close();
      this.global_callback = null;
    };
  }

  /*实际调用的方法
  * 1.若是ws开启状态
  * 2.若是 正在开启状态,则等待1s后重新调用
  * 3.若未开启 ,则等待1s后重新调用
  * */
  sendSock(agentData, callback) {
    if (callback) {
      if (typeof callback === 'function') {
        this.global_callback = callback
      } else {
        this.global_callback = data => {
        }
        alert('sendSock,传参没有回调')
      }
    }
    if (this.websock.readyState === this.websock.OPEN) {
      this.websock.send(agentData)
    } else {
      setTimeout(() => {
        this.sendSock(agentData)
      }, 1000)
    }
  }


  // 关闭
  websocketclose(e) {
    // console.log("WebSocket关闭成功");
    this.websock.close()
    this.global_callback = null
  }

  // 接收数据
  websocketOnMessage(e) {
    try {
      this.global_callback(e.data)
    } catch (err) {
    }
  }
}

  1. vue组件中使用
  import websocket from '../assets/js/websocket'
    created() {
      // 初始化 这里的回调:在不发送数据时,其他链接发送了数据,通过这个回调接收数据
      this.socketServe = new websocket('ws://localhost:3001', data => {})
      //页面销毁时关闭长连接
      window.addEventListener("beforeunload ", () => {
        this.socketServe.websocketclose();
      });
    },
    beforeDestroy() {
      //页面销毁时关闭长连接
      this.socketServe.websocketclose();
    },
  1. 发送数据
		// 这里的回调,会覆盖掉 init 时的回调
        this.socketServe.sendSock(JSON.stringify({
          id: this.$store.state.userInfo.id,
          type: this.type
        }), data => {
          console.log(data)
        })

前端服务:方法2

  1. 新建 websocket.js 文档

export default class SocketService {
  // 单例
  static instance = null
  static get Instance() {
    if (!this.instance) {
      this.instance = new SocketService()
    }
    return this.instance
  }

  // 和服务端连接的socket对象
  ws = null

  // 存储回调函数
  callBackMapping = {}

  // 标识是否连接成功
  connected = false

  // 记录重试的次数
  sendRetryCount = 0

  // 重新连接尝试的次数
  connectRetryCount = 0

  //  定义连接服务器的方法
  connect() {
    // 连接服务器
    if (!window.WebSocket) {
      return console.log('您的浏览器不支持WebSocket')
    }
    this.ws = new WebSocket('ws://localhost:3001', 'echo-protocol')

    // 连接成功的事件
    this.ws.onopen = () => {
      console.log('连接服务端成功了')
      this.connected = true
      // 重置重新连接的次数
      this.connectRetryCount = 0
    }
    // 1.连接服务端失败
    // 2.当连接成功之后, 服务器关闭的情况
    this.ws.onclose = () => {
      console.log('连接服务端失败')
      this.connected = false
      this.connectRetryCount++
      setTimeout(() => {
        this.connect()
      }, 500 * this.connectRetryCount)
    }
    // 得到服务端发送过来的数据
    this.ws.onmessage = msg => {
      console.log(msg.data, '从服务端获取到了数据')
    }
  }

  // 回调函数的注册
  registerCallBack (socketType, callBack) {
    this.callBackMapping[socketType] = callBack
  }

  // 取消某一个回调函数
  unRegisterCallBack (socketType) {
    this.callBackMapping[socketType] = null
  }

  // 发送数据的方法
  send (data) {
    // 判断此时此刻有没有连接成功
    if (this.connected) {
      this.sendRetryCount = 0
      try {
        this.ws.send(JSON.stringify(data))
      }catch (e) {
        this.ws.send(data)
      }
    } else {
      this.sendRetryCount++
      setTimeout(() => {
        this.send(data)
      }, this.sendRetryCount * 500)
    }
  }
}
  1. vue 组件中 init
  import SocketService from '../assets/js/websocket'

    data() {
      return {
        socketServe: null
      }
    },
    methods: {
      sendData() {
        this.socketServe.send('这里是HTML发送的数据', data => {
        console.log(data)
      })
      },
    },
    created() {
      SocketService.Instance.connect()
      this.socketServe= SocketService.Instance
      // 注册接收到数据的回调函数
      this.socketServe.registerCallBack('callback1', data => {
        console.log(data)
      })
    },
    beforeDestroy() {
      // 销毁某一个回调函数
      this.socketServe.registerCallBack('callback1')
    },

node 代码

  1. 安装 ws
npm install ws //     "ws": "^7.3.0",
  1. web_socket_service.js 文件
const WebSocket = require('ws')
// 创建WebSocket服务端的对象, 绑定的端口号是3001
const wss = new WebSocket.Server({
  port: 3001
})
// 服务端开启了监听
module.exports.listen = () => {
  // 对客户端的连接事件进行监听
  // client:代表的是客户端的连接socket对象
  wss.on('connection', client => {
    console.log('有客户端连接成功了...')
    // 对客户端的连接对象进行message事件的监听
    // msg: 由客户端发给服务端的数据
    client.on('message',async msg => {
      console.log('客户端发送数据给服务端了: ' + msg)
      // client.send('hello socket from backend')
      wss.clients.forEach(client => {
        client.send(msg)
      })
    })
  })
}

  1. 然后 app.js 中添加
const webSocketService = require('./websocket/web_socket_service')
// 开启服务端的监听, 监听客户端的连接
// 当某一个客户端连接成功之后, 就会对这个客户端进行message事件的监听
webSocketService.listen()
Logo

前往低代码交流专区

更多推荐