feat: reconnecting detect

This commit is contained in:
Tristan Yang
2023-04-03 22:03:31 +08:00
parent 26ac8a5574
commit 6972e15530
4 changed files with 30 additions and 7 deletions
+9 -2
View File
@@ -1,5 +1,6 @@
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
import { KEY_UID } from "../config";
import { ConnectionState } from "agora-rtc-sdk-ng";
export type VoiceBasicInfo = {
context: "channel" | "dm"
@@ -10,7 +11,8 @@ export type VoicingInfo = {
downlinkNetworkQuality?: number,
muted?: boolean,
deafen?: boolean,
joining?: boolean
joining?: boolean,
connectionState?: ConnectionState
} & VoiceBasicInfo
export type VoicingMemberInfo = {
@@ -88,6 +90,11 @@ const voiceSlice = createSlice({
}
}
},
updateConnectionState(state, { payload }: PayloadAction<ConnectionState>) {
if (state.voicing) {
state.voicing.connectionState = payload;
}
},
updateVoicingNetworkQuality(state, { payload }: PayloadAction<number>) {
if (state.voicing) {
state.voicing.downlinkNetworkQuality = payload;
@@ -134,5 +141,5 @@ const voiceSlice = createSlice({
},
});
export const { addVoiceMember, removeVoiceMember, upsertVoiceList, updateVoicingInfo, updateVoicingNetworkQuality, updateMuteStatus, updateVoicingMember, updateDeafenStatus } = voiceSlice.actions;
export const { updateConnectionState, addVoiceMember, removeVoiceMember, upsertVoiceList, updateVoicingInfo, updateVoicingNetworkQuality, updateMuteStatus, updateVoicingMember, updateDeafenStatus } = voiceSlice.actions;
export default voiceSlice.reducer;
+8 -2
View File
@@ -3,7 +3,7 @@ import { memo, useEffect } from 'react';
import { useDispatch } from 'react-redux';
import { useGetAgoraConfigQuery, useGetAgoraVoicingListQuery, useLazyGetAgoraTokenQuery } from '../../app/services/server';
import { updateChannelVisibleAside } from '../../app/slices/channels';
import { addVoiceMember, removeVoiceMember, updateDeafenStatus, updateMuteStatus, updateVoicingInfo, updateVoicingMember, updateVoicingNetworkQuality, upsertVoiceList } from '../../app/slices/voice';
import { addVoiceMember, removeVoiceMember, updateConnectionState, updateDeafenStatus, updateMuteStatus, updateVoicingInfo, updateVoicingMember, updateVoicingNetworkQuality, upsertVoiceList } from '../../app/slices/voice';
import { useAppSelector } from '../../app/store';
import AudioJoin from '../../assets/join.wav';
// type Props = {}
@@ -25,7 +25,7 @@ const Voice = () => {
secret: agoraConfig?.rtm_secret ?? "",
}, {
skip: !isAdmin || !agoraConfig,
skip: !isAdmin || !agoraConfig || !navigator.onLine,
pollingInterval: 5000
});
const dispatch = useDispatch();
@@ -43,6 +43,7 @@ const Voice = () => {
if (mediaType == "audio") {
// 播放远端音频
user.audioTrack?.play();
// const playing= user.audioTrack?.isPlaying;
// const level = user.audioTrack?.getVolumeLevel();
// if (level === 0) {
// // 远端静音
@@ -80,6 +81,11 @@ const Voice = () => {
const { downlinkNetworkQuality } = qlt;
dispatch(updateVoicingNetworkQuality(downlinkNetworkQuality));
});
// 连接状态有变化
agoraEngine.on("connection-state-change", (state, prevState, reason) => {
console.log("connection-state-change", state, prevState, reason);
dispatch(updateConnectionState(state));
});
// 用户状态变化
agoraEngine.on("user-info-updated", (uid, msg) => {
console.log("user-info-updated", uid, msg);
+4 -2
View File
@@ -1,4 +1,6 @@
// import React from 'react';
import { useTranslation } from 'react-i18next';
import clsx from 'clsx';
import { useAppSelector } from '../../app/store';
import User from '../../common/component/User';
import IconMic from '../../assets/icons/mic.on.svg';
@@ -9,7 +11,6 @@ import IconSoundOff from '../../assets/icons/sound.off.svg';
import { useVoice } from '../../common/component/Voice';
import Signal from '../../common/component/Signal';
import Tooltip from '../../common/component/Tooltip';
import { useTranslation } from 'react-i18next';
type Props = {
id: number,
@@ -29,6 +30,7 @@ const RTCWidget = ({ id, context = "channel" }: Props) => {
if (!loginUser || !voicingInfo || joining) return null;
const name = voicingInfo.context == "channel" ? channelData[voicingInfo.id]?.name : userData[voicingInfo.id]?.name;
if (!name) return null;
const isReConnecting = voicingInfo.connectionState == "RECONNECTING";
return (
<div className='bg-gray-100 dark:bg-gray-900 flex flex-col p-2 rounded-3xl m-3 text-sm'>
{/* {voicingInfo && */}
@@ -36,7 +38,7 @@ const RTCWidget = ({ id, context = "channel" }: Props) => {
<div className="flex flex-1 items-center gap-1">
<Signal strength={voicingInfo.downlinkNetworkQuality} />
<div className="flex flex-col">
<span className='text-green-800 font-bold'>Voice Connected</span>
<span className={clsx('text-green-800 font-bold', isReConnecting && `text-red-500`)}>{isReConnecting ? `Voice Reconnecting...` : `Voice Connected`}</span>
<span className='text-gray-600 dark:text-gray-400 text-xs truncate max-w-[170px]' >{voicingInfo.context == "channel" ? "Channel" : "DM"} / {voicingInfo.context == "channel" ? channelData[voicingInfo.id].name : userData[voicingInfo.id].name}</span>
</div>
</div>
@@ -12,7 +12,6 @@ import IconMicOff from '../../../assets/icons/mic.off.svg';
import StyledButton from '../../../common/component/styled/Button';
import IconCallOff from '../../../assets/icons/call.off.svg';
import Tooltip from '../../../common/component/Tooltip';
import SpeakingAnimate from './SpeakingAnimate';
// import User from '../../../common/component/User';
type Props = {
@@ -40,6 +39,14 @@ const VoiceManagement = ({ info, setMute, setDeafen, leave }: Props) => {
Connecting to voice channel...
</div>;
}
if (info.connectionState == "RECONNECTING") {
return <div className='w-full h-full flex-center flex-col gap-1 p-1 '>
<span className='text-red-300'>
Reconnecting...
</span>
<span className='text-xs text-red-500'>Please check network connection!</span>
</div>;
}
return (
<div className='w-full h-full py-2 flex flex-col'>
<ul className='flex grow flex-col'>
@@ -95,6 +102,7 @@ const VoiceManagement = ({ info, setMute, setDeafen, leave }: Props) => {
</Tooltip>
</StyledButton>
</div>
</div>
);
};