diff --git a/pages/meeting/index.scss b/pages/meeting/index.scss index 8172d58..908d0bd 100644 --- a/pages/meeting/index.scss +++ b/pages/meeting/index.scss @@ -74,6 +74,7 @@ height: 100vh; display: flex; flex-direction: column; + overflow: hidden; &-content { flex-grow: 1; diff --git a/pages/meeting/index.ts b/pages/meeting/index.ts index 18c02c3..5c59071 100644 --- a/pages/meeting/index.ts +++ b/pages/meeting/index.ts @@ -1,10 +1,13 @@ -import { GetRoomInfo, GetRoomUser, GetShowUser, GetApplySpeak, PostMuteAll, PostOpenMicr, PostOpenCamera, DeleteRoomManager } from '../../api/meeting/index' +import { GetRoomInfo, GetRoomUser, GetShowUser, GetApplySpeak, PostMuteAll, PostOpenMicr, PostOpenCamera, DeleteRoomManager, PostRoomManager } from '../../api/meeting/index' +import { GetRoomRtcToken } from '../../api/form/index' import { agora } from '../../utils/agora' -import { onInvoke, onSignalr } from '../../utils/singlr' +import { onInvoke, onSignalr, getSignIr, offSignalr } from '../../utils/singlr' import { role, getStorage } from '../../utils/utils' import { Message } from 'tdesign-miniprogram'; +import * as signalR from "signalr-for-wx"; import dayjs from 'dayjs'; const computedBehavior = require('miniprogram-computed').behavior; +let reconnectTime = "" as any; Page({ behaviors: [computedBehavior], data: { @@ -92,7 +95,9 @@ Page({ '听得到', '听不到', '我要发言', - ] + ], + isFirstShow: true, + isCurrePage: false, }, watch: { 'roomUserList.**': function (roomUserList) { @@ -198,11 +203,91 @@ Page({ onReady() { wx.onNetworkStatusChange(this.listener) }, + onShow() { + this.setData({ + isCurrePage: true + }) + if (this.data.isFirstShow) { + this.setData({ + isFirstShow: false, + }) + } else { + const item = this.data.roomUserList.find(row => row.uid === this.data.user.uid) + if (item && !item.isRoomManager) { + wx.showLoading({ + title: '重连中', + }) + agora.destroy(() => { + reconnectTime = setInterval(() => { + if (getSignIr() === signalR.HubConnectionState.Connected) { + this.reconnecFun() + clearInterval(reconnectTime) + reconnectTime = '' + } + }, 2000) + }) + } + } + }, + onHide() { + this.setData({ + isCurrePage: false + }) + if (reconnectTime) { + clearInterval(reconnectTime) + reconnectTime = '' + } + wx.hideLoading() + }, onUnload() { wx.offNetworkStatusChange(this.listener) + if (reconnectTime) { + clearInterval(reconnectTime) + reconnectTime = '' + } + }, + async reconnecFun() { + offSignalr() + await GetRoomRtcToken(this.data.channelId).then(res => { + if (res.code === 200) { + agora.reconnecSetOption(res.data, async () => { + await this.joinChannel() + this.startClientEvent() + this.startSignalr() + await this.getRoomUser() + await this.getShowUser() + wx.hideLoading() + Message.success({ + context: this, + offset: [90, 32], + duration: 3000, + content: '重连成功', + }); + }) + } else { + wx.hideLoading() + Message.error({ + context: this, + offset: [90, 32], + duration: 3000, + content: '重连失败,请退出房间重试!', + }); + } + }).catch(() => { + wx.hideLoading() + Message.error({ + context: this, + offset: [90, 32], + duration: 3000, + content: '重连失败,请退出房间重试!', + }); + }) }, startSignalr() { onSignalr(async (item) => { + if (!this.data.isCurrePage) { + return + } const userInfo: any = await getStorage('user') switch (item.key) { // 聊天 @@ -398,6 +483,13 @@ Page({ }) } }); + }, + tokenRef: () => { + GetRoomRtcToken(this.data.channelId).then(res => { + if (res.code === 200) { + agora.renewToken(res.data) + } + }) } }) }, diff --git a/pages/meeting/index.wxml b/pages/meeting/index.wxml index b1d60a8..06aa04e 100644 --- a/pages/meeting/index.wxml +++ b/pages/meeting/index.wxml @@ -19,7 +19,7 @@ - + @@ -38,8 +38,8 @@ - - + + @@ -96,7 +96,7 @@ 成员 - + {{item.avatarName}} @@ -107,7 +107,7 @@ - + @@ -115,7 +115,7 @@ 聊天 - + ({{item.timestamp}}) {{item.me ? item.message : item.userName}} diff --git a/utils/agora.ts b/utils/agora.ts index 8bf5262..4a8e688 100644 --- a/utils/agora.ts +++ b/utils/agora.ts @@ -10,16 +10,20 @@ const option = { let client: any = ''; export const agora = { // 初始化 - init: async () => { + init: async (callback?) => { client = new AgoraMiniappSDK.Client(); - await client.init(option.appId); + await client.init(option.appId, () => { + callback?.() + }); }, // 销毁 - destroy: async () => { + destroy: async (callback?) => { if (client) { await client.leave() - await client.destroy() - client = ''; + await client.destroy(() => { + callback?.() + client = ''; + }) } }, // 设置角色 @@ -41,14 +45,22 @@ export const agora = { option.screenShareId = data.screenShareId; await agora.init() }, + reconnecSetOption: async (token, callback) => { + option.token = token; + await agora.init(callback) + }, // 加入频道 joinChannel: () => { client.join(option.token, option.channelId, option.uid, () => { agora.setRole(false) }) }, + // 刷新token + renewToken: (token) => { + client.renewToken(token) + }, // 监听 - clientEvent: ({ streamAdded, streamRemoved }) => { + clientEvent: ({ streamAdded, streamRemoved, tokenRef }) => { client.on("stream-added", async e => { await agora.subscribe(e.uid, (url: string, uid: number | string) => { streamAdded(url, uid) @@ -57,6 +69,9 @@ export const agora = { client.on("stream-removed", async e => { streamRemoved(e.uid) }); + client.on("token-privilege-will-expire", async e => { + tokenRef() + }); }, // 订阅远端音视频流 subscribe: async (uid: number | string, callBack: Function) => { diff --git a/utils/request.js b/utils/request.js index ae62c66..1845291 100644 --- a/utils/request.js +++ b/utils/request.js @@ -1,5 +1,5 @@ const apiBase = "https://meeting-api.23544.com/pc" - +import { Message } from 'tdesign-miniprogram'; export const Request = (params) => { return new Promise((resolve, reject) => { wx.getStorage({ @@ -36,6 +36,7 @@ function requestMethods(obj, callback) { wx.request({ ...obj.params, url: apiBase + obj.params.url, + timeout: 500, header: { 'content-type': 'application/json', 'Authorization': `Bearer ${obj.token}` @@ -44,6 +45,22 @@ function requestMethods(obj, callback) { callback('success', res) }, fail: res => { + if (res.errMsg === 'request:fail timeout') { + Message.error({ + context: this, + offset: [20, 32], + duration: 2000, + content: '网络连接超时,请检查网络状态', + }); + } + if (res.errMsg === 'request:fail ') { + Message.error({ + context: this, + offset: [20, 32], + duration: 2000, + content: '网络已断开,请检查网络状态', + }); + } callback('fail', res) }, }) diff --git a/utils/singlr.ts b/utils/singlr.ts index 02e24f0..26e8fc0 100644 --- a/utils/singlr.ts +++ b/utils/singlr.ts @@ -199,7 +199,9 @@ export const onStop = async () => { connection = ''; } } - +export const getSignIr = () => { + return connection ? connection.state : '' +}