使用sip.js库连接Linphone SIP服务器失败,求解决方案
问题
使用onsip.com的sip.js作为Web SIP客户端,尝试连接Linphone SIP服务,运行代码后出现WebSocket连接失败错误。
相关代码
/* eslint-disable @typescript-eslint/no-explicit-any */ // eslint-disable-next-line @typescript-eslint/no-unused-vars import { UserAgentOptions, Web } from "sip.js"; import { SimpleUserDelegate } from "sip.js/lib/platform/web/simple-user/simple-user-delegate"; import { getButton, getE, getVideo } from "./scripts/demo-utils"; const domainOnSip = "sipjs.onsip.com"; export let webSocketServer="wss://edge.sip.onsip.com"; // eslint-disable-next-line @typescript-eslint/no-unused-vars const domainLinphone = 'sip.linphone.org'; const webSocketServerLinphone="wss://sip.linphone.org"; const iamUser = "nidza"; webSocketServer = webSocketServerLinphone; console.info('Hackey running...', Web); const delegate: SimpleUserDelegate={ onCallReceived: async () => { console.log('Incoming Call!'); await simpleUser2.answer(); } }; const userAgentOptions = { sessionDescriptionHandlerFactoryOptions: { peerConnectionConfiguration: { iceServers: [{ urls: "stun:stun.l.google.com:19302" }, { username: "nidza", credential: "***********" }] }, } }; // Options for SimpleUser const options: Web.SimpleUserOptions={ userAgentOptions: userAgentOptions, aor: `sip:${iamUser}@${domainLinphone}`, media: { constraints: { audio: false, video: true }, local: { video: getVideo("videoLocalAlice") }, remote: { video: getVideo("videoRemoteAlice") } } }; const options2: Web.SimpleUserOptions={ aor: `sip:zlatnaspirala@${domainLinphone}`, media: { constraints: { audio: false, video: true }, local: { video: getVideo("videoLocalBob") }, remote: { video: getVideo("videoRemoteBob") } }, delegate: delegate }; // Construct a SimpleUser instance const simpleUser=new Web.SimpleUser(webSocketServer, options); const simpleUser2=new Web.SimpleUser(webSocketServer, options2); simpleUser.connect() .then(() => { console.info("status: sip server connected."); (getE('callIdList') as HTMLInputElement).disabled=false; (getButton('connectUser')).disabled=true; (getButton('registerUser')).disabled=false; simpleUser.register().then(() => { console.info("status: registered."); getButton('registerUser').disabled=true; getButton('callBtn').disabled=false; getButton('callBtn').classList.add('cooliano'); getButton('callBtn').addEventListener('click', (e) => { console.log(">>>"+(getE('callIdList') as HTMLSelectElement).selectedOptions[0].innerText) console.log(">>>"+(getE('callIdList') as HTMLSelectElement).selectedIndex) const emailLocal=(getE('callIdList') as HTMLSelectElement).selectedOptions[0].innerText; const curAddress=`sip:${emailLocal}`; // const curAddress = `sip:bob@${domain}`; simpleUser.call(curAddress, undefined, { requestDelegate: { onAccept: (e) => { console.info(`status: ${(e as any).message.from.uri.normal.user} INVITE accepted from ${(e as any).message.to.uri.normal.user}`); getButton('hangupBtn').disabled=false; (getButton('hangupBtn')).addEventListener('click', () => { // simpleUser.hangup().then(() => { console.log("just test hangup") }) }) }, onReject: (response) => { console.info(`status: INVITE rejected`); let message=`Session invitation to rejected.\n`; message+=`Reason: ${response.message.reasonPhrase}\n`; alert(message); } }, withoutSdp: false }) .catch((error: Error) => { console.error(`error: failed to begin session`, error); alert(` Failed to begin session.\n`+error); }); }) }).catch((error: Error) => { console.error("error in registration:", error); }); }).catch((error: Error) => { console.error("error in connection:", error); }); simpleUser2.connect() .then(() => { simpleUser2.register().then(() => { console.log("Nice reg bob"); }).catch((error: Error) => { console.log("Error in registration:", error); }); }).catch((error: Error) => { console.log("Error:", error); });
运行错误
transport.js:197 WebSocket connection to 'wss://sip.linphone.org/' failed: _connect @ transport.js:197 logger-factory.js:85 Sat Jan 07 2023 21:23:45 GMT+0100 (Central European Standard Time) | sip.Transport | WebSocket error occurred. print @ logger-factory.js:85 hackeyWeb.ts:108 error in connection: Error: WebSocket closed wss://sip.linphone.org (code: 1006) at Transport.onWebSocketClose (transport.js:337:1) at WebSocket.<anonymous> (transport.js:199:1)
解决建议
- 确认Linphone的WebSocket服务端点:Linphone的WebSocket服务可能不是直接使用
wss://sip.linphone.org,建议尝试带端口或路径的常见配置,比如wss://sip.linphone.org:443/ws或wss://sip.linphone.org:8089。 - 修复ICE服务器配置:当前ICE服务器配置中第二个条目缺少
urls字段,这会导致配置无效。如果使用TURN服务器,补充urls字段;如果不需要TURN,暂时移除第二个条目,仅保留STUN服务器测试。 - 检查跨域限制:若网页在本地或其他域名下运行,Linphone服务器可能未配置CORS允许你的域名访问。通过浏览器开发者工具Network面板查看请求的CORS响应头,确认是否存在访问限制。
- 验证TLS证书:浏览器会校验WebSocket服务器的TLS证书,直接在浏览器访问
https://sip.linphone.org,查看证书是否有效、是否被信任。 - 简化连接逻辑:暂时移除
simpleUser2的连接代码,先测试单个用户连接成功后,再添加第二个用户的逻辑,避免资源冲突或服务器限制。
内容的提问来源于stack exchange,提问作者Nikola Lukic
相关产品推荐
相关产品推荐

