You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 13:53:12