封装一套前端几乎通用的WebSocket代码 您所在的位置:网站首页 微星ms7673参数 封装一套前端几乎通用的WebSocket代码

封装一套前端几乎通用的WebSocket代码

2024-03-19 10:14| 来源: 网络整理| 查看: 265

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

前言

对接过几次WebSocket连接,无论是在纯JavaScript、Vue亦或Uniapp等框架语言中使用,Socket代码流程基本上差不多。无非就是:

发起连接 发送数据(发送心跳等) 接收数据 关闭连接 断线重连 异常处理... 每次都需要重写比较麻烦,故封装一套大致流程的WebSocket代码,哪怕从纯JavaScript项目搬到Vue、Uniapp等框架中,也只需要做小部分修改即可。 具体实现

创建socket.js,代码如下:

// 在Vue中使用,不需要可以去除以下引用 import Vue from 'vue' import storage from 'store' // 导出socket对象 export { socket } // socket主要对象 var socket = { websock: null, // 固定的WebSocket地址:此处是从env文件中读取socket地址,可以自行从其他config文件中读取或直接写死 // 如需使用动态WebSocket地址,请自行作ajax通讯后扩展 ws_url: process.env.VUE_APP_API_SOCKET_URL, // 开启标识 socket_open: false, // 心跳timer hearbeat_timer: null, // 心跳发送频率 hearbeat_interval: 5000, // 是否自动重连 is_reonnect: true, // 重连次数 reconnect_count: 3, // 已发起重连次数 reconnect_current: 1, // 重连timer reconnect_timer: null, // 重连频率 reconnect_interval: 3000, /** * 初始化连接 */ init: () => { if (!("WebSocket" in window)) { console.log('浏览器不支持WebSocket') return null } // 已经创建过连接不再重复创建 if (socket.websock) { return socket.websock } socket.websock = new WebSocket(socket.ws_url) socket.websock.onmessage = function (e) { socket.receive(e) } // 关闭连接 socket.websock.onclose = function (e) { console.log('连接已断开') console.log('connection closed (' + e.code + ')') clearInterval(socket.hearbeat_interval) socket.socket_open = false // 需要重新连接 if (socket.is_reonnect) { socket.reconnect_timer = setTimeout(() => { // 超过重连次数 if (socket.reconnect_current > socket.reconnect_count) { clearTimeout(socket.reconnect_timer) return } // 记录重连次数 socket.reconnect_current++ socket.reconnect() }, socket.reconnect_interval) } } // 连接成功 socket.websock.onopen = function () { console.log('连接成功') socket.socket_open = true socket.is_reonnect = true // 开启心跳 socket.heartbeat() } // 连接发生错误 socket.websock.onerror = function () { console.log('WebSocket连接发生错误') } }, /** * 发送消息 * @param {*} data 发送数据 * @param {*} callback 发送后的自定义回调函数 */ send: (data, callback = null) => { // 开启状态直接发送 if (socket.websock.readyState === socket.websock.OPEN) { socket.websock.send(JSON.stringify(data)) if (callback) { callback() } // 正在开启状态,则等待1s后重新调用 } else if (socket.websock.readyState === socket.websock.CONNECTING) { setTimeout(function () { socket.send(data, callback) }, 1000) // 未开启,则等待1s后重新调用 } else { socket.init() setTimeout(function () { socket.send(data, callback) }, 1000) } }, /** * 接收消息 * @param {*} message 接收到的消息 */ receive: (message) => { var params = JSON.parse(message.data) if (params.kind != 0) { console.log('收到服务器内容:', message.data) } if (params == undefined) { console.log("收到服务器空内容") return false } // 以下是接收消息后的业务处理,仅供参考 // 被服务器强制断开 if (params.kind != undefined && params.kind == 110) { socket.socket_open = false socket.is_reonnect = true // 被服务器踢掉 } else if (params.kind == 99) { socket.socket_open = true socket.is_reonnect = false console.log("被挤下线 不做处理") return false } else if (params.kind == 'order_new') { console.log('有新的订单通知') var time = Date.parse(new Date()) / 1000 params.timestamp = parseInt(params.timestamp) console.log(time - params.timestamp) // 测试环境不限制推送时间 if (process.env.NODE_ENV == 'development') { // 小于半小时push和播放 大于半小时并且小于3天只push 大于3天不处理 if ((time - params.timestamp) > 3600 * 24 * 3) { console.log('超过三天') return false } if ((time - params.timestamp) > 30 * 60 && (time - params.timestamp) < 3600 * 24 * 3) { console.log('超过半小时') return false } } // uniapp中可以使用$on和$emit来实现对应的业务处理 } else if (params.kind == 'refund_created') { console.log('有新的退款订单') } if (params.kind == 'order_new' || params.kind == 'refund_created') { console.log('订单列表刷新') } // 自行扩展其他业务处理... }, /** * 心跳 */ heartbeat: () => { console.log('socket', 'ping') if (socket.hearbeat_timer) { clearInterval(socket.hearbeat_timer) } socket.hearbeat_timer = setInterval(() => { const token = storage.get('Access-Token') var data = { kind: 0, //请求类型 kind 0 心跳包 shop_id: Vue.prototype.$shop_id(false), //如果是商家 传当前店铺ID 否则可不传 'API-Token': token, //用户的token 'API-Source': 'MERCHANT', // MERCHANT 商家 CUSTOMER 顾客 } socket.send(data) }, socket.hearbeat_interval) }, /** * 主动关闭连接 */ close: () => { console.log('主动断开连接') clearInterval(socket.hearbeat_timer) socket.is_reonnect = false socket.websock.close() }, /** * 重新连接 */ reconnect: () => { console.log('发起重新连接', socket.reconnect_current) if (socket.websock && socket.socket_open) { socket.websock.close() } socket.init() }, }

使用时主要修改socket对象中的一些配置、发送数据处理、接收数据业务处理等。

如何使用 // 引入socket.js import { socket } from '@/utils/socket' // 发起连接 socket.init() // 发送数据 socket.send({test:123}, () => {console.log('这是回调函数,发送test 123后执行')}) // 断开连接 socket.close() // 重新连接 socket.reconnect()


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有