From 498a83aa7e6c8a91b976eab59cf9a92fb5dbb1ba Mon Sep 17 00:00:00 2001 From: gaotian Date: Wed, 7 Aug 2024 10:57:53 +0800 Subject: [PATCH] =?UTF-8?q?feat:http=E5=B0=81=E8=A3=85=20websocket?= =?UTF-8?q?=E5=B0=81=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- meeting/online/index.vue | 70 +++++++++++++++-- request/api.js | 20 +++++ request/index.js | 93 ++++++++++++++++++++++ request/websocket.js | 161 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 337 insertions(+), 7 deletions(-) create mode 100644 request/api.js create mode 100644 request/index.js create mode 100644 request/websocket.js diff --git a/meeting/online/index.vue b/meeting/online/index.vue index e6f2f33..a248629 100644 --- a/meeting/online/index.vue +++ b/meeting/online/index.vue @@ -16,10 +16,14 @@ 正在录音中 00:12/02:00:00 - + 开始 + + + 结束 + 结束 @@ -37,6 +41,9 @@ @@ -166,7 +221,8 @@ export default { } } } - .popClass{ + + .popClass { text-align: center; color: #4B5158; font-size: 28rpx; diff --git a/request/api.js b/request/api.js new file mode 100644 index 0000000..f7f11ed --- /dev/null +++ b/request/api.js @@ -0,0 +1,20 @@ +// 引入 request 文件 +import request from './index.js' + +// GET +export const getDemo = (params) => { + return request({ + url: `/getDemo?id=${id}`, + method: 'get', + data: params, + header: {} // 自定义 + }) +} +// POST +export const PostDemo = (data) => { + return request({ + url: `/postDemo`, + method: 'post', + data:data, + }) +} \ No newline at end of file diff --git a/request/index.js b/request/index.js new file mode 100644 index 0000000..8e78f8e --- /dev/null +++ b/request/index.js @@ -0,0 +1,93 @@ +// 全局请求封装 请求地址 +const base_url = 'http://localhost:996' +// 请求超出时间 +const timeout = 5000 + +// 需要修改token,和根据实际修改请求头 +export default (params) => { + let url = params.url; + let method = params.method || "get"; + let data = params.data || {}; + let header = { + 'Token': uni.getStorageSync('token') || '', + // 'Content-Type': 'application/json;charset=UTF-8', + // 'Authorization': 'Basic c2FiZXI6c2FiZXJfc2VjcmV0', + // 'Tenant-Id': uni.getStorageSync('tenantId') || 'xxx', // avue配置相关 + ...params.header + } + if (method == "post") { + header = { + 'Content-Type': 'application/json' + }; + } + return new Promise((resolve, reject) => { + uni.request({ + url: base_url + url, + method: method, + header: header, + data: data, + timeout, + success(response) { + const res = response + // 根据返回的状态码做出对应的操作 + //获取成功 + // console.log(res.statusCode); + if (res.statusCode == 200) { + resolve(res.data); + } else { + uni.clearStorageSync() + switch (res.statusCode) { + case 401: + uni.showModal({ + title: "提示", + content: "请登录", + showCancel: false, + success() { + setTimeout(() => { + uni.navigateTo({ + url: "/pages/login/index", + }) + }, 1000); + }, + }); + break; + case 404: + uni.showToast({ + title: '请求地址不存在...', + duration: 2000, + }) + break; + default: + uni.showToast({ + title: '请重试...', + duration: 2000, + }) + break; + } + } + }, + fail(err) { + console.log(err) + if (err.errMsg.indexOf('request:fail') !== -1) { + uni.showToast({ + title: '网络异常', + icon: "error", + duration: 2000 + }) + } else { + uni.showToast({ + title: '未知异常', + duration: 2000 + }) + } + reject(err); + + }, + complete() { + // 不管成功还是失败都会执行 + uni.hideLoading(); + uni.hideToast(); + } + }); + }).catch(() => { }); +}; \ No newline at end of file diff --git a/request/websocket.js b/request/websocket.js new file mode 100644 index 0000000..6537f3f --- /dev/null +++ b/request/websocket.js @@ -0,0 +1,161 @@ +function pickJsonObj(value) { + try { + return JSON.parse(value) + } catch (e) { + return null; + } +} + +class WebSocketClient { + constructor(url) { + this.url = url; + this.socket = null; + this.isReconnecting = false; + this.reconnectInterval = 3000; // 重连间隔,单位毫秒 + this.heartBeatInterval = 5000; // 心跳间隔,单位毫秒 + this.pingTimeoutDuration = 1000; // 超过这个时间,后端没有返回pong,则判定后端断线了。 + this.heartBeatTimer = null; + this.destroy = false; // 是否销毁 + } + + connect() { + this.socket = uni.connectSocket({ + url: this.url, + complete: () => { } + }); + this.initEventListeners(); + } + + initEventListeners() { + this.socket.onOpen(() => { + // WebSocket连接已打开 + this.onConnected(); + this.startHeartBeat(); + }); + + this.socket.onMessage((res) => { + const obj = pickJsonObj(res.data); + if (obj.type === 'pong') { + // 收到pong消息,心跳正常,无需处理 + this.resetPingTimeout(); // 重置计时 + } else { + // 处理其他消息 + this.onMessage(res.data); + } + }); + + this.socket.onClose((res) => { + // WebSocket连接已关闭 + if (this.destroy) { + this.onClosed() + return; + } + this.stopHeartBeat(); + if (!this.isReconnecting) { + this.reconnect(); + } + }); + } + + sendMessage(message) { + if (this.socket) { + this.socket.send({ + data: message + }); + } + } + + onMessage(message) { + // 处理收到的消息 + console.log('message:', message) + } + + startHeartBeat() { + this.heartBeatTimer = setInterval(() => { + this.sendMessage(JSON.stringify({ + type: 'ping' + })); // 发送ping消息 + this.pingTimeout = setTimeout(() => { + // 未收到pong消息,尝试重连... + this.reconnect(); + }, this.pingTimeoutDuration); + }, this.heartBeatInterval); + } + + stopHeartBeat() { + if (this.heartBeatTimer) { + clearInterval(this.heartBeatTimer); + } + } + + reconnect() { + this.isReconnecting = true; + setTimeout(() => { + this.onReconnect(); + this.connect(); + this.isReconnecting = false; + }, this.reconnectInterval); + } + + resetPingTimeout() { + clearTimeout(this.pingTimeout); // 重置计时 + } + + close() { + this.destroy = true; + this.stopHeartBeat(); + if (this.socket) { + this.socket.close(); + this.socket = null; + } + } + /** + * 重连时触发 + */ + onReconnect() { + console.log('尝试重连...') + } + /** + * 连接成功时触发 + */ + onConnected() { + console.log('WebSocket连接已打开'); + } + /** + * 断开时触发 + */ + onClosed() { + console.log('已断开连接') + } +} + +export default WebSocketClient; + +// websocket 使用 +// import WebSocketClient from '@/utils/websocket.js' +// // 创建WebSocket实例 +// ws.value = new WebSocketClient('ws://这里填写你的服务地址'); +// // 连接WebSocket +// ws.value.connect(); +// // 接收消息时触发 +// ws.value.onMessage = (value) => { +// const obj = JSON.parse(value) +// if (obj.type === 'message') { +// list.value.push({ +// time: new Date().toLocaleString(), +// value: obj.value +// }) +// } +// } +// // 重连时触发 +// ws.value.onReconnect = () => { +// netStatus.value = 2; +// } +// // 连接成功后触发 +// ws.value.onConnected = () => { +// netStatus.value = 1; +// } +// // 关闭后触发(直接销毁了,不会继续重连) +// ws.value.onClosed = () => { +// netStatus.value = 0; +// }