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

如何用Twilio、React Native和Node.js实现双人实时语音通话

解决方案说明

你的问题出在重复呼叫同一个号码:当前代码里to参数设为callTo,同时Twiml中又<Dial>这个号码,导致Twilio先拨通callTo,接着又在该通话内再次呼叫callTo,最终形成会议模式。要实现一对一实时通话,可参考以下两种方案:


方案一:后端(Node.js)发起双向呼叫并桥接

此方案适用于后端触发通话,同时呼叫发起方和接收方,接通后自动建立连接。

Node.js后端代码

const twilio = require('twilio');
const express = require('express');
const app = express();

const client = twilio(process.env.TWILIO_ACCOUNT_SID, process.env.TWILIO_AUTH_TOKEN);

// 发起一对一通话的核心函数
async function startDirectCall(callerPhone, receiverPhone) {
  try {
    // 先呼叫发起方
    const call = await client.calls.create({
      to: callerPhone,
      from: process.env.TWILIO_FROM_PHONE,
      url: `https://your-public-domain.com/bridge-call?receiver=${receiverPhone}`
    });
    console.log('通话发起成功,SID:', call.sid);
    return call;
  } catch (err) {
    console.error('发起通话失败:', err);
    throw err;
  }
}

// 桥接通话的Twiml路由
app.get('/bridge-call', (req, res) => {
  const receiverPhone = req.query.receiver;
  const twiml = new twilio.twiml.VoiceResponse();
  // 将发起方与接收方直接桥接
  twiml.dial({ callerId: process.env.TWILIO_FROM_PHONE }, receiverPhone);
  res.type('text/xml');
  res.send(twiml.toString());
});

app.listen(3000, () => console.log('后端服务运行于端口3000'));

方案二:React Native端用Twilio SDK发起呼叫,后端桥接

如果是React Native端用户主动发起呼叫,需集成Twilio Voice SDK,后端提供Token与Twiml桥接支持。

1. React Native端配置与代码

首先安装依赖:

npm install @twilio/voice-react-native-sdk

核心呼叫代码:

import { Voice } from '@twilio/voice-react-native-sdk';

// 从后端获取Twilio Access Token
async function fetchAccessToken() {
  const resp = await fetch('https://your-public-domain.com/get-token', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ identity: 'user-123' }) // 发起方唯一标识
  });
  const data = await resp.json();
  return data.token;
}

// 发起呼叫
async function initiateCall(receiverPhone) {
  const token = await fetchAccessToken();
  await Voice.register(token);

  const call = await Voice.connect({
    params: { To: receiverPhone }
  });

  // 监听通话状态
  call.on('disconnect', () => {
    console.log('通话结束');
    Voice.unregister();
  });
}

2. Node.js后端配套代码

const twilio = require('twilio');
const express = require('express');
const app = express();
app.use(express.json());

// 生成Twilio Access Token的接口
app.post('/get-token', (req, res) => {
  const { identity } = req.body;
  const AccessToken = twilio.jwt.AccessToken;
  const VoiceGrant = AccessToken.VoiceGrant;

  const voiceGrant = new VoiceGrant({
    outgoingApplicationSid: process.env.TWILIO_TWIML_APP_SID, // Twilio控制台创建的Twiml应用SID
    incomingAllow: true
  });

  const token = new AccessToken(
    process.env.TWILIO_ACCOUNT_SID,
    process.env.TWILIO_API_KEY,
    process.env.TWILIO_API_SECRET,
    { identity }
  );
  token.addGrant(voiceGrant);

  res.send({ token: token.toJwt() });
});

// Twiml应用指向的桥接路由
app.post('/voice', (req, res) => {
  const twiml = new twilio.twiml.VoiceResponse();
  const receiverPhone = req.body.To;
  twiml.dial({ callerId: process.env.TWILIO_FROM_PHONE }, receiverPhone);
  res.type('text/xml');
  res.send(twiml.toString());
});

app.listen(3000, () => console.log('后端服务运行于端口3000'));

关键注意事项

  • 确保Twilio号码具备语音功能,试用阶段需验证所有待呼叫的手机号。
  • 后端的Twiml路由必须是公网可访问的HTTPS地址,Twilio无法访问本地服务。
  • React Native端需配置权限:iOS添加NSMicrophoneUsageDescription,Android添加RECORD_AUDIO、MODIFY_AUDIO_SETTINGS权限。

内容的提问来源于stack exchange,提问作者ali

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 13:20:13