diff --git a/src/App.tsx b/src/App.tsx index 00d10a5..ffb48d8 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -57,8 +57,6 @@ const App: React.FC = () => { toSrc('/login') } window.addEventListener('resize', handleResize); - window.addEventListener('online', handleNetworkChange); - window.addEventListener('offline', handleNetworkChange); const originalSetItem = window.localStorage.setItem; window.localStorage.setItem = function (key, value) { originalSetItem.call(this, key, value); @@ -71,8 +69,6 @@ const App: React.FC = () => { return () => { window.removeEventListener('resize', handleResize); window.removeEventListener('customStorageChange', handleCustomStorageChange); - window.removeEventListener('online', handleNetworkChange); - window.removeEventListener('offline', handleNetworkChange); }; }, []); useEffect(() => { @@ -238,19 +234,6 @@ const App: React.FC = () => { } } }; - - const handleNetworkChange = (): void => { - if (location.hash.indexOf('/meeting') === -1) { - if (navigator.onLine) { - message.success('网络已恢复。') - setTimeout(async () => { - await onStart() - }, 1000) - } else { - message.error('网络已断开!') - } - } - } return ( <> diff --git a/src/page/Meeting/index.tsx b/src/page/Meeting/index.tsx index 29925d7..1073263 100644 --- a/src/page/Meeting/index.tsx +++ b/src/page/Meeting/index.tsx @@ -11,10 +11,10 @@ import { storage } from '@/utils'; import { GetRoomUser, PostOpenMicr, PostOpenCamera, GetLeaveAll, PostRoomManager, DeleteRoomManager, GetRoomKickout, GetShowUser, PostShowUser, PostMuteAll, GetRoomUserItem, GetApplySpeak } from '@/api/Meeting'; import ImageUrl from '@/utils/package/imageUrl' import { agora } from '@/utils/package/agora' -import { onInvoke, onSignalr, offSignalr, onStart } from '@/utils/package/signalr'; +import { onInvoke, onSignalr, offSignalr } from '@/utils/package/signalr'; import dayjs from 'dayjs'; import durationPlugin from 'dayjs/plugin/duration'; -import { AudioVolumeInfo, QualityType, RtcConnection, RtcStats, UserOfflineReasonType, VideoSourceType, VideoStreamType } from 'agora-electron-sdk'; +import { AudioVolumeInfo, ConnectionChangedReasonType, ConnectionStateType, QualityType, RtcConnection, RtcStats, UserOfflineReasonType, VideoSourceType, VideoStreamType } from 'agora-electron-sdk'; import Avatar from '@/components/Avatar'; import SharedFilesModel from '@/components/SharedFilesModel'; import StupWizard from '@/components/StupWizard'; @@ -147,13 +147,11 @@ const Meeting: React.FC = () => { const [currentVideoId, setCurrentVideoId] = useState('') let [currentSeconds, setCurrentSeconds] = useState(0) const [currentEffective, setCurrentEffective] = useState(4) - const [currentNetworkInfo, setCurrentNetworkInfo] = useState({ - networkQuality: { - level: '佳', - text: '网络质量极好。' - }, - networkOther: {} as RtcStats + const [networkQuality, setNetworkQuality] = useState({ + level: '佳', + text: '网络质量极好。' }) + const [networkOther, setNetworkOther] = useState({}) const [isComputerAudio, setIsComputerAudio] = useState(true) const [isFluencyPriority, setIsFluencyPriority] = useState(false) const [open, setOpen] = useState(false) @@ -203,8 +201,6 @@ const Meeting: React.FC = () => { agoraInit() storage.setItem('noViewChatList', 0) window.addEventListener('customStorageChange', handleCustomStorageChange); - window.addEventListener('online', handleNetworkChange); - window.addEventListener('offline', handleNetworkChange); const container = document.getElementById('videoView') as HTMLElement; container.addEventListener('wheel', handleWheelChange); time = setInterval(() => { @@ -229,8 +225,6 @@ const Meeting: React.FC = () => { // }, 3000) return () => { window.removeEventListener('customStorageChange', handleCustomStorageChange); - window.removeEventListener('online', handleNetworkChange); - window.removeEventListener('offline', handleNetworkChange); window.removeEventListener('wheel', handleWheelChange); clearInterval(time) // clearInterval(getDesktopCapturerVideoTime) @@ -240,48 +234,33 @@ const Meeting: React.FC = () => { useEffect(() => { switch (currentEffective) { case 0: - setCurrentNetworkInfo({ - ...currentNetworkInfo, - networkQuality: { - level: '断开连接', - text: '网络连接断开。' - } + setNetworkQuality({ + level: '断开连接', + text: '网络连接断开。' }) break; case 1: - setCurrentNetworkInfo({ - ...currentNetworkInfo, - networkQuality: { - level: '非常差', - text: '完全无法沟通。' - } + setNetworkQuality({ + level: '非常差', + text: '完全无法沟通。' }) break; case 2: - setCurrentNetworkInfo({ - ...currentNetworkInfo, - networkQuality: { - level: '差', - text: '勉强能沟通但不顺畅,网络质量非常差,基本不能沟通。' - } + setNetworkQuality({ + level: '差', + text: '勉强能沟通但不顺畅,网络质量非常差,基本不能沟通。' }) break; case 3: - setCurrentNetworkInfo({ - ...currentNetworkInfo, - networkQuality: { - level: '良好', - text: ' 用户主观感受有瑕疵但不影响沟通。' - } + setNetworkQuality({ + level: '良好', + text: ' 用户主观感受有瑕疵但不影响沟通。' }) break; case 4: - setCurrentNetworkInfo({ - ...currentNetworkInfo, - networkQuality: { - level: '佳', - text: '网络质量极好。' - } + setNetworkQuality({ + level: '佳', + text: '网络质量极好。' }) break; } @@ -764,24 +743,30 @@ const Meeting: React.FC = () => { setCurrentEffective(3) break; case 4: - case 5: setCurrentEffective(2) break; - case 6: + case 5: setCurrentEffective(1) break; + case 6: + setCurrentEffective(0) + break; default: - setCurrentEffective(navigator.onLine ? 4 : 0) + setCurrentEffective(storage.getItem('reconnect') ? 4 : 0) break; } } }, onRtcStats: async (stats: RtcStats) => { - setCurrentNetworkInfo({ - ...currentNetworkInfo, - networkOther: stats - }) - } + setNetworkOther(stats) + }, + onConnectionStateChanged: async (_connection: RtcConnection, stateNumber: ConnectionStateType, reason: ConnectionChangedReasonType) => { + const reconnectingCode = [2, 16, 11, 13, 14, 12] + if (stateNumber === 4 && reconnectingCode.indexOf(reason) >= 0) { + storage.setItem('reconnect', false) + message.error('网络断开,请检查网络') + } + }, }) if (state.enableCamera) { await agora.startCameraCapture() @@ -935,23 +920,6 @@ const Meeting: React.FC = () => { } changeAgoraDevice() } - // 网络 - const handleNetworkChange = (): void => { - if (navigator.onLine) { - message.success('网络已恢复。') - setTimeout(async () => { - await onStart(async () => { - await onInvoke('joinChannel', { - roomNum: state.channelId, - enableMicr: !footerList[0][0].active, - enableCamera: !footerList[0][1].active - }) - }) - }, 1000) - } else { - message.error('网络已断开!') - } - } // 滚动 const handleWheelChange = (e: any): void => { const container = document.getElementById('videoView') as HTMLElement; @@ -1327,12 +1295,24 @@ const Meeting: React.FC = () => { break; case 'reconnect': if (e.value == true) { - storage.setItem('reconnect', false) await onInvoke('joinChannel', { roomNum: state.channelId, enableMicr: !footerList[0][0].active, enableCamera: !footerList[0][1].active }) + message.success('网络已连接。') + setRoomUserList((res: any) => { + let userItem = res.find((item: any) => item.uid === userInfo.uid) + if (userItem.isRoomManager) { + DeleteRoomManager({ + roomId: state.roomId, + roomNum: state.channelId, + userId: userInfo.uid + }) + } + return res + }) + } break; } @@ -1631,13 +1611,13 @@ const Meeting: React.FC = () => {
网络质量: - {currentNetworkInfo.networkQuality.level} + {networkQuality.level} - {currentNetworkInfo.networkQuality.text} + {networkQuality.text} } title="" @@ -1651,15 +1631,15 @@ const Meeting: React.FC = () => {
带宽占用: - ↑{currentNetworkInfo.networkOther.txKBitRate}kbps ↓{currentNetworkInfo.networkOther.rxKBitRate}kbps + ↑{networkOther.txKBitRate}kbps ↓{networkOther.rxKBitRate}kbps
丢包率: - ↑{currentNetworkInfo.networkOther.txPacketLossRate}% ↓{currentNetworkInfo.networkOther.rxPacketLossRate}% + ↑{networkOther.txPacketLossRate}% ↓{networkOther.rxPacketLossRate}%
延迟: - {currentNetworkInfo.networkOther.lastmileDelay}ms + {networkOther.lastmileDelay}ms
} @@ -2457,7 +2437,7 @@ const meetingContentError = (item: any) => { const networkIcon = (network: number) => { switch (network) { case 0: - return + return @@ -2469,14 +2449,14 @@ const networkIcon = (network: number) => { case 1: - return + return case 2: - return + return diff --git a/src/utils/package/agora.ts b/src/utils/package/agora.ts index 8fdd786..9926355 100644 --- a/src/utils/package/agora.ts +++ b/src/utils/package/agora.ts @@ -13,7 +13,9 @@ import { RtcConnection, RtcStats, AudioVolumeInfo, - UserOfflineReasonType + UserOfflineReasonType, + ConnectionStateType, + ConnectionChangedReasonType } from "agora-electron-sdk"; import { GetRoomRtcToken, GetAgoraConf } from "@/api/Home/Index"; import { storage } from '@/utils'; @@ -109,7 +111,7 @@ export const agora = { }, 1000); }, // 事件回调 - registerEventHandler: ({ onJoinChannelSuccess, onUserJoined, onUserOffline, onAudioVolumeIndication, onNetworkQuality, onRtcStats }: any) => { + registerEventHandler: ({ onJoinChannelSuccess, onUserJoined, onUserOffline, onAudioVolumeIndication, onNetworkQuality, onRtcStats, onConnectionStateChanged }: any) => { rtcEngine.registerEventHandler({ // 监听本地用户加入频道事件 onJoinChannelSuccess: async (connection: RtcConnection, elapsed: number) => { @@ -147,6 +149,10 @@ export const agora = { onRtcStats: async (_connection: RtcConnection, stats: RtcStats) => { await onRtcStats(stats) }, + // 网络连接状态已改变回调。 + onConnectionStateChanged: async (connection: RtcConnection, state: ConnectionStateType, reason: ConnectionChangedReasonType) => { + await onConnectionStateChanged(connection, state, reason) + }, }); }, // 获取视图模式 diff --git a/vite.config.ts b/vite.config.ts index 325229a..8d788dd 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -68,7 +68,9 @@ export default defineConfig({ RtcConnection, RtcStats, AudioVolumeInfo, - UserOfflineReasonType + UserOfflineReasonType, + ConnectionStateType, + ConnectionChangedReasonType } = require("agora-electron-sdk") export { createAgoraRtcEngine, @@ -85,7 +87,9 @@ export default defineConfig({ RtcConnection, RtcStats, AudioVolumeInfo, - UserOfflineReasonType + UserOfflineReasonType, + ConnectionStateType, + ConnectionChangedReasonType } `, })