import JsSIP from 'jssip' class SipService { constructor() { this.ua = null this.currentSession = null this.onStatusChange = null // 状态变化回调 } // 初始化SIP客户端 init(config) { try { this.updateStatus('connecting', '连接中...') this.ua = new JsSIP.UA({ sockets: [new JsSIP.WebSocketInterface(config.wsUrl)], uri: config.sipUri, password: config.password, display_name: config.displayName, realm: config.realm, register: true, register_expires: 300, // 注册有效期(秒) connection_recovery_min_interval: 2, // 最小重连间隔 connection_recovery_max_interval: 30 // 最大重连间隔 }) this.ua.start() // 注册事件监听 this.ua.on('registered', () => { this.updateStatus('registered', '已注册') }) this.ua.on('registrationFailed', (e) => { this.updateStatus('failed', `注册失败: ${e.cause}`) }) this.ua.on('disconnected', () => { this.updateStatus('disconnected', '连接断开') }) this.ua.on('connected', () => { this.updateStatus('connecting', '重新连接中...') }) // 监听来电 this.ua.on('newRTCSession', (data) => { this.handleIncomingCall(data.session) }) } catch (error) { this.updateStatus('failed', `初始化失败: ${error.message}`) console.error('SIP初始化失败:', error) } } // 更新状态并通知UI updateStatus(type, text) { console.log(`SIP状态更新: ${type} - ${text}`) if (this.onStatusChange) { this.onStatusChange({ type, text }) } } // 一键拨号 - 增加注册状态检查 makeCall(targetNumber) { if (!this.ua) { throw new Error('SIP客户端未初始化') } if (!this.ua.isRegistered()) { throw new Error('SIP未注册,无法呼叫') } const options = { eventHandlers: { progress: (e) => console.log('呼叫中...'), failed: (e) => console.error('呼叫失败:', e), ended: (e) => console.log('通话结束'), confirmed: (e) => console.log('通话已接通') }, mediaConstraints: { audio: true, video: false }, rtcOfferConstraints: { offerToReceiveAudio: 1 } } this.currentSession = this.ua.call(`sip:${targetNumber}`, options) this.setupAudio(this.currentSession) } // 挂断当前通话 endCall() { if (this.currentSession) { this.currentSession.terminate() this.currentSession = null } } // 处理音频流 setupAudio(session) { session.connection.addEventListener('addstream', (e) => { const audioElement = document.getElementById('remoteAudio') if (audioElement) { audioElement.srcObject = e.stream } }) } // 处理来电 handleIncomingCall(session) { if (session.direction === 'incoming') { console.log('来电:', session.remote_identity.uri.toString()) // 这里可以触发UI通知 } } } export default new SipService()