使用sip.js+React-Native-WebRTC发起呼叫报错:logger.debug未定义
问题:React Native中sip.js调用Inviter.invite()时出现logger.debug未定义错误
在React Native应用中使用sip.js结合react-native-webrtc开发语音通话功能,调用Inviter.invite()发起外呼时遇到错误:
ERROR Failed to make a call: logger.debug is not a function (it is undefined)
简化代码
import { RTCPeerConnection, mediaDevices } from 'react-native-webrtc'; import { UserAgent, Registerer, URI, Inviter } from 'sip.js'; import SipKeys from '../utils/SipKeys'; import customSessionDescriptionHandlerFactory from './customSessionDescriptionHandlerFactory'; import InCallManager from 'react-native-incall-manager'; import { logger } from './logger' const configuration = { iceServers: [ { urls: SipKeys.stunUri, username: SipKeys.username, credential: SipKeys.password }, { urls: SipKeys.turnUri, username: SipKeys.username, credential: SipKeys.password }, { urls: SipKeys.gStunUri, username: SipKeys.username, credential: SipKeys.password } ], iceTransportPolicy: 'all', bundlePolicy: 'balanced', rtcpMuxPolicy: 'require', }; const createMockMediaStream = async () => { try { const stream = await mediaDevices.getUserMedia({ audio: true, video: false }); console.debug('Stream created'); return stream; } catch (error) { console.error('Error creating media stream', error); throw error; } }; const createPeerConnection = async () => { console.debug('Initializing PeerConnection...'); const peerConnection = new RTCPeerConnection(configuration); console.debug('PeerConnection initialized'); peerConnection.onicecandidate = (iceEvent) => { if (iceEvent.candidate) { console.debug('ICE Candidate found'); } }; peerConnection.onsignalingstatechange = () => { console.debug(`Signaling State: ${peerConnection.signalingState}`); }; peerConnection.onnegotiationneeded = async () => { console.debug('Negotiation needed'); }; peerConnection.ontrack = (event) => { console.debug('Track event'); }; peerConnection.onremovetrack = (event) => { console.debug('Remove track event'); }; const localStream = await createMockMediaStream(); console.debug('Local stream obtained'); localStream.getTracks().forEach(track => { console.debug('Adding track'); peerConnection.addTrack(track, localStream); }); const offer = await peerConnection.createOffer(); await peerConnection.setLocalDescription(offer); console.debug('Offer created'); return peerConnection; }; const connectToSIP = async () => { try { const uri = new URI('sip', SipKeys.username, SipKeys.uri); const userAgentOptions = { uri, transportOptions: { server: SipKeys.wsServers }, authorizationUsername: SipKeys.username, authorizationPassword: SipKeys.password, sessionDescriptionHandlerFactoryOptions: { peerConnectionOptions: { rtcConfiguration: configuration } }, sessionDescriptionHandlerFactory: customSessionDescriptionHandlerFactory, sipExtension100rel: 'REQUIRED', viaHost: SipKeys.uri, autostart: true, // Autostart the UserAgent }; const loggerObj = { logBuiltinEnabled: true, // Disable built-in logging if needed logLevel: 'debug', // Set desired log level logConnector: logger, // Use the custom logger } // Log the configuration to ensure logger is correctly passed console.log('UserAgent configuration:', userAgentOptions); const userAgent = new UserAgent(userAgentOptions, loggerObj); userAgent.delegate = { onConnect: () => console.debug('SIP Connected'), onDisconnect: () => console.debug('SIP Disconnected'), }; userAgent.transport.onConnect = () => console.debug('Transport Connected'); userAgent.transport.onDisconnect = (error) => console.error('Transport Disconnected', error); const registerer = new Registerer(userAgent); registerer.stateChange = (newState) => { if (newState === 'Unregistered' || newState === 'Terminated') { console.error('SIP Registration state changed:', newState); } }; await userAgent.start(); const registererOptions = { requestDelegate: { onAccept: (response) => console.debug('SIP Registered successfully!', response), onReject: (response) => console.error('SIP Registration failed', response), } }; registerer.register(registererOptions); InCallManager.start({ media: 'audio' }); setTimeout(() => { initiateOutgoingCall(userAgent); }, 1500); return { userAgent, registerer, configuration }; } catch (error) { console.error('Failed to connect to SIP', error); } }; const initiateOutgoingCall = async (userAgent) => { try { const target = new URI('sip', SipKeys.targetUri, SipKeys.uri); const inviter = new Inviter(userAgent, target, { earlyMedia: true, allowEarlyMedia: true, inviteWithoutSdp: false, sessionDescriptionHandlerOptions: { constraints: { audio: true, video: false }, peerConnectionOptions: { rtcConfiguration: configuration }, iceGatheringTimeout: 200, }, }); inviter.delegate = { onInvite: () => console.debug('Invite event triggered'), onAccepted: () => console.debug('Call accepted'), onProgress: response => console.debug('Call in progress', response), onTerminated: (message, cause) => console.error(`Call terminated: ${cause}`) }; console.debug('Inviting...'); await inviter.invite(); } catch (error) { console.error(`Failed to make a call: ${error.message}`); } };
解决方案
问题根源:sip.js的Logger对象要求
logConnector必须实现对应日志级别的方法(debug、info、warn、error等),你的自定义logger对象缺少debug方法,或者导入的logger未正确定义这些方法。修复步骤:
- 检查并完善自定义
logger的实现,确保包含所有sip.js所需的日志方法:// logger.js 示例实现 export const logger = { debug: (message) => console.debug(message), info: (message) => console.info(message), warn: (message) => console.warn(message), error: (message) => console.error(message) }; - 确认
logger对象被正确导入,检查导入路径是否正确、是否已正确导出。 - 若不需要自定义日志,可直接移除
loggerObj参数,使用sip.js内置日志:// 移除loggerObj参数 const userAgent = new UserAgent(userAgentOptions); - 额外检查:确保sip.js版本与react-native-webrtc版本兼容,避免版本不匹配导致的隐性问题。
- 检查并完善自定义
内容的提问来源于stack exchange,提问作者Gurpreet Singh
相关产品推荐
相关产品推荐

