shsany-jssip-sdk
v0.0.4
Published
WebRTC SIP SDK based on JsSIP with multi-call and call-waiting support.
Maintainers
Readme
ShsanyCall(shsany-jssip-sdk)用户手册
基于 JsSIP 的 WebRTC SIP 语音/视频通话 SDK,适用于座机、呼叫中心等在浏览器中收发 SIP 呼叫。
功能概览
- SIP 注册与 WebSocket 信令(WSS)
- 呼入 / 外呼、视频可选
- 多路会话与呼叫等待:多路振铃、保持一路接听另一路、按路拒接
- 保持 / 静音 / 转接
- 实时网络统计(延迟、丢包率等)
- 麦克风检测、即时消息(
sendMessage) - TypeScript 类型定义
运行环境
| 要求 | 说明 |
|------|------|
| 浏览器 | 支持 WebRTC、getUserMedia 的现代浏览器 |
| 页面 | HTTPS(或 localhost),否则麦克风/媒体可能受限 |
| 网络 | 能访问 FreeSWITCH/Asterisk 等提供的 WSS 端口(实现中默认 wss://{fsHost}:7443,与贵司网关一致时需自行核对) |
| 音频 | 视频关闭时使用内部 <audio autoplay> 播放远端音频;需在合适时机处理浏览器自动播放策略 |
安装
npm install shsany-jssip-sdk
# 或
yarn add shsany-jssip-sdk构建产物:dist 下 ESM / UMD 与类型声明(见 package.json 的 exports)。
快速开始
new ShsanyCall(config) 会立即完成 UA 配置、连接 WSS 并 start(),无需再调用 init()。
import ShsanyCall, { State } from "shsany-jssip-sdk";
const sdk = new ShsanyCall({
host: "192.168.1.10", // contact / 设备侧 SIP 相关(deviceIP)
port: 5060,
fsHost: "192.168.1.10", // FreeSWITCH 等地址,用于 WSS 与注册域
extNo: "1001",
extPwd: "your-password",
checkMic: true,
stateEventListener: (event, data) => {
switch (event) {
case State.REGISTERED:
console.log("注册成功");
break;
case State.INCOMING_CALL:
console.log("振铃", data);
break;
case State.CALL_END:
console.log("通话结束", data);
break;
case State.SESSIONS_SYNC:
// 多路列表刷新,见下文「多路通话」
console.log("会话列表", data);
break;
default:
break;
}
},
});
// 注册异常时可手动补注册(一般自动注册已成功则不必)
// sdk.register();外呼示例(第二个参数为是否视频):
sdk.call("1009", false);初始化参数 InitConfig
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| host | string | 是 | 本机/终端在 SIP 侧的地址,写入 contact_uri 中的 device IP |
| port | number | 是 | SIP 端口,用于构造注册 URI 等 |
| fsHost | string | 是 | 信令服务器主机名或 IP(与 WSS 目标一致) |
| fsPort | string \| number | 否 | 预留,当前实现以 WSS 固定端口为准时请与运维确认 |
| viaTransport | string | 否 | 预留 |
| extNo | string | 是 | 分机号 / SIP 用户名 |
| extPwd | string | 是 | 注册密码 |
| stun | StunConfig | 否 | STUN/TURN(若后续版本接入 ICE) |
| checkMic | boolean | 是 | 为 true 时构造实例会触发一次麦克风检测 |
| stateEventListener | function | 是 | 全局状态与通话事件回调,见下文 |
公开属性:sdk.localIp 与构造时传入的 host 一致(用于外呼 URI 等)。
典型业务流程
- 创建实例:可选麦克风检测;自动连接 WSS、发起注册。
- 等待
State.CONNECTED:WebSocket 已连接。 - 等待
State.REGISTERED:可向sipInit同一套参数对应的网关注册成功,此时可call()。 - 呼入:收到
INCOMING_CALL/OUTGOING_CALL(振铃阶段),data中带callId/sessionId、otherLegNumber、isCallWaiting等。 - 接通:
State.IN_CALL;保持为HOLD;结束为CALL_END。 - 退出:
unregister()取消注册;内部在注销流程中会清理本地会话相关状态。
API 一览
| 方法 | 说明 |
|------|------|
| sipInit(regInfo) | 使用新的注册信息重建 UA(注意避免重复泄漏旧连接,生产环境建议封装「先停后建」) |
| register() / unregister() | 手动注册 / 注销 |
| call(phone, isVideo) | 外呼;phone 为号码字符串;isVideo 是否视频 |
| answer(sessionId?) | 接听;多路呼入时建议传 sessionId,否则接听最近一路呼入 |
| answerWithHoldOthers(sessionId) | 呼叫等待:将其它已接通线路 hold,再接听指定呼入 |
| rejectCall(sessionId) | 拒接指定振铃会话(603 Decline) |
| hangup(sessionId?) | 挂断;省略 sessionId 时挂断当前焦点线路 |
| hangupAll() | 尝试终止当前管理的所有会话 |
| hold(sessionId?) / unhold(sessionId?) | 保持 / 恢复;省略时对焦点线路操作 |
| mute(sessionId?) / unmute(sessionId?) | 静音 / 取消静音 |
| transfer(phone, sessionId?) | 转接;phone 为号码;可选指定线路 |
| focusCall(sessionId) | 切换焦点线路(默认收听/控制的会话;影响内置音频元素的绑定) |
| getSessions() | 返回多路快照数组,用于自定义通话卡片 UI |
| sendMessage(target, content) | SIP MESSAGE(文本) |
| micCheck() | 再次检测麦克风,失败回调 MIC_ERROR |
当前版本未封装 sendDtmf;若需二次拨号,需在 JsSIP RTCSession 层扩展或由网关侧支持。
多路通话与呼叫等待
JsSIP 为每通会话创建一个 RTCSession。本 SDK 用内部 sessionMap 管理多路,并通过 sessionId(与事件里的 callId 一致) 区分线路。
getSessions()返回CallSessionSnapshot[],字段包括:sessionId、remoteUser、direction、lineState(ringing|outbound_ringing|in_call|hold)、isEstablished、isInProgress、isOnHold、isVideo、isFocused。State.SESSIONS_SYNC:data为SessionsSyncPayload,含sessions与focusedSessionId,适合一次性刷新列表 UI。- 焦点线路:外呼会聚焦新外呼;新呼入不会自动抢焦点(正在通话的 A 仍为焦点);接听成功后焦点切到刚接通的那一路。用户点击「主听哪一路」时可调用
focusCall(id)。 - 呼叫等待提示:第二路呼入时,
INCOMING_CALL的data.isCallWaiting === true表示已有其它已接通会话,UI 可提示「保持当前通话并接听 / 拒接」。 - 推荐操作:保持 A 接 B →
answerWithHoldOthers(bSessionId);仅拒接 B →rejectCall(bSessionId)。
状态回调 stateEventListener(event, data)
第一个参数 event 为 State 枚举字符串;第二个参数随事件变化,类型见下表。
| State | data 说明 |
|---------|-------------|
| MIC_ERROR | { msg: string } |
| ERROR | { msg: string } |
| CONNECTED | null |
| DISCONNECTED | 实现中仅在 WSS 出错时额外回调 ERROR;见源码 disconnected 处理 |
| REGISTERED | { localAgent: string } |
| UNREGISTERED | { localAgent: string } |
| REGISTER_FAILED | { msg: string } |
| INCOMING_CALL / OUTGOING_CALL | direction、otherLegNumber、callId、sessionId、可选 isTransfer、isCallWaiting |
| IN_CALL | 含 callId / sessionId、direction、otherLegNumber 等 |
| HOLD / MUTE / UNMUTE | 含对应 callId / sessionId 等 |
| CALL_END | CallEndEvent(含可选 callId) |
| LATENCY_STAT | LatencyStat(含可选 callId,多路时按路区分) |
| MESSAGE_INCOMING | 消息正文 string |
| REMOTE_STREAM_READY | 视频远端流:{ stream?: MediaStream, callId?, sessionId? } |
| SESSIONS_SYNC | SessionsSyncPayload |
类型参考
CallEndEvent
| 字段 | 类型 | 说明 |
|------|------|------|
| answered | boolean | 是否曾接通(以会话结果为准) |
| originator | string | 挂断发起方:local / remote |
| cause | string | 原因短语 |
| code | number | SIP 响应码等,无则可为 0 |
| callId | string(可选) | 结束的会话 id |
LatencyStat
| 字段 | 说明 |
|------|------|
| latencyTime | 估算 RTT(ms) |
| upLossRate / downLossRate | 上下行丢包率比例 |
| upAudioLevel / downAudioLevel | 音量相关 |
| callId | 可选,标识统计所属会话 |
CallSessionSnapshot / SessionsSyncPayload
见 src/index.d.ts;用于多通话卡片与列表同步。
与 README 旧版的差异说明
- 无需调用
init();构造函数内已初始化并启动 UA。 - 包名为
shsany-jssip-sdk(以package.json为准),示例 import 请与发布名一致。 - 文档中曾出现的
cleanSdk()/cleanSDK()不是当前公开 API;注销后本地会话由内部逻辑清理。 - 多路场景请使用
sessionId/getSessions()/SESSIONS_SYNC,勿再假设全局只有一路通话。
构建与本地开发
npm install
npm run build开发调试可使用 npm run dev(见 vite.config.ts)。
许可证
ISC(见 package.json)。
