React Native集成Voximplant无法收来电,报错Call Failed: Not Found
React Native集成Voximplant无法接收来电问题排查与修复
核心问题分析
- 登录逻辑冗余且状态处理不全:未判断
LOGGED_IN状态,存在重复登录操作;CONNECTED状态下直接触发登录,忽略已登录场景,可能引发无效请求或错误 - 异步操作未等待:调用
login()时未加await,导致来电监听可能在登录完成前就绑定,时机错误 - 来电监听时机不合理:未确保登录成功后再绑定
IncomingCall事件,若登录失败,监听逻辑无效 - 错误处理不细致:仅打印错误信息,未针对登录失败等关键场景做针对性提示或状态处理,无法及时定位登录失败问题
- 主叫方提示"Not Found",本质是被叫方未成功登录Voximplant平台,导致平台无法找到在线用户
修复后的代码
import { Voximplant } from 'react-native-voximplant'; import calls from './store'; import { VOXIMPLANT_APP, VOXIMPLANT_ACCOUNT } from '../Constants/voximplant'; import AsyncStorage from '@react-native-async-storage/async-storage'; import { Platform } from 'react-native'; export const initVoximplant = (navigation) => { const voximplant = Voximplant.getInstance(); let cleanupListener = null; const login = async () => { try { const userDataString = await AsyncStorage.getItem('user'); if (!userDataString) { console.log('用户数据不存在'); return; } const e = JSON.parse(userDataString); const clientState = await voximplant.getClientState(); // 已登录则直接绑定监听 if (clientState === Voximplant.ClientState.LOGGED_IN) { console.log('用户已处于登录状态'); setupIncomingCallListener(); return; } // 未连接则先建立连接 if (clientState === Voximplant.ClientState.DISCONNECTED) { await voximplant.connect(); } // 连接成功后执行登录 const username = `${e.user._id}@${VOXIMPLANT_APP}.${VOXIMPLANT_ACCOUNT}.voximplant.com`; await voximplant.login(username, e.user._id); console.log('登录成功'); setupIncomingCallListener(); } catch (e) { console.log('登录错误:', e); let message = '未知错误,请重试'; if (e.name === Voximplant.ClientEvents.ConnectionFailed) { message = '连接失败,请检查网络'; } else if (e.name === Voximplant.ClientEvents.LoginFailed) { message = '登录失败,请检查账号信息'; } // 可在此添加弹窗提示等用户反馈逻辑 } }; // 单独抽离来电监听逻辑,确保登录成功后绑定 const setupIncomingCallListener = () => { // 先清理旧监听,避免重复绑定 if (cleanupListener) { cleanupListener(); } const listener = voximplant.on(Voximplant.ClientEvents.IncomingCall, (incomingCallEvent) => { calls.set(incomingCallEvent.call.callId, incomingCallEvent.call); console.log('收到来电:', incomingCallEvent.call.callId, incomingCallEvent.call); navigation.navigate('IncomingCall', { callId: incomingCallEvent.call.callId, }); }); cleanupListener = () => { voximplant.off(Voximplant.ClientEvents.IncomingCall, listener); }; }; const checkUserNotifee = async () => { try { const userDataString = await AsyncStorage.getItem('user'); if (!userDataString) { console.log('用户数据不存在'); return; } const e = JSON.parse(userDataString); const baseUrl = Platform.OS === 'ios' ? 'http://localhost:3000' : 'http://10.0.2.2:3000'; const response = await fetch(`${baseUrl}/notifeeuser`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ user: e.user._id }), }); const data = await response.json(); if (data.message === 'Ok') { await login(); // 等待登录操作完成 } } catch (error) { console.log('检查用户通知错误:', error); } }; checkUserNotifee(); // 返回清理函数,用于组件卸载时移除监听 return () => { if (cleanupListener) { cleanupListener(); } }; };
额外验证步骤
- 确认Voximplant控制面板中用户的JID格式,与代码中拼接的
${e.user._id}@${VOXIMPLANT_APP}.${VOXIMPLANT_ACCOUNT}.voximplant.com完全一致 - 检查登录用的用户名、密码,与Voximplant平台创建的用户信息匹配
- 登录成功后打印
voximplant.getClientState(),确认状态为LOGGED_IN - 主叫方发起呼叫时,确保使用的被叫方JID无拼写错误
内容的提问来源于stack exchange,提问作者cwecae
相关产品推荐
相关产品推荐

