tw-sip
v1.1.1
Published
SDK 现在支持重复登录检查,防止在已登录状态下重复登录导致的资源泄漏和状态混乱。
Readme
TW-SIP SDK
重复登录防护
SDK 现在支持重复登录检查,防止在已登录状态下重复登录导致的资源泄漏和状态混乱。
重连策略优化
SDK 现在采用双层重连机制:
1. WebSocket 层重连
- 触发条件:
onDisconnect事件 + WebSocket 未连接状态 - 处理场景:网络断开、服务器重启等导致的 WebSocket 连接断开
- 判断条件:
this.userAgent && !this.userAgent.isConnected()
2. 注册层重连
- 触发条件:注册状态变为
Unregistered或Terminated - 处理场景:注册会话过期、认证失败等导致的注册断开
- 判断条件:
state === RegistererState.Unregistered || state === RegistererState.Terminated
竞态条件修复
修复了快速登出再登录时的竞态条件问题:
// 🔧 问题场景:
// 1. 用户调用 loginOut()
// 2. 立即调用 login() 重新登录成功
// 3. 几秒后旧的 unregister() 超时,误触发重连
// 4. WebSocket 正常关闭(code: 1000)也会误触发重连
// 5. 旧注册器的状态回调仍然在运行,影响新登录
// ✅ 修复方案:
1. loginOut() 立即清空所有状态,防止异步回调影响
2. 重连逻辑增加精确判断,避免误触发
3. 账号一致性检查,防止旧注册器影响新注册器
4. 新增主动登出标志,防止主动登出时的正常断开触发重连
5. 新增登录会话ID,防止旧登录会话的回调影响新登录重连逻辑说明
// ❌ 修复前:注册成功时错误地触发重连
if (this.registererState === RegistererState.Registered) {
sipReConnect(...) // 错误!注册成功为什么要重连?
}
// ✅ 修复后:只在注册失败或断开时重连,且增加精确判断
if (state === RegistererState.Unregistered || state === RegistererState.Terminated) {
const shouldReconnect =
this?.loginInfo?.ip &&
this?.loginInfo?.authorizationUsername &&
this?.loginInfo?.authorizationUsername === account.authorizationUsername && // 账号一致性检查
this.registerer &&
!this.isLoggedIn(); // 确实未登录
if (shouldReconnect) {
sipReConnect(...) // 精确重连
}
}使用示例
const twSip = new TwSip();
// 检查登录状态
console.log('当前登录状态:', twSip.isLoggedIn());
console.log('详细状态信息:', twSip.getLoginStatus());
// 登录
const loginResult = await twSip.login({
ip: '192.168.1.100',
server: 'wss://192.168.1.100:7443',
aor: 'sip:[email protected]',
authorizationUsername: '1004',
authorizationPassword: 'password123'
});
if (loginResult.code === 200) {
console.log('登录成功');
} else if (loginResult.code === 1002) {
console.log('已处于登录状态,请先退出登录');
// 可以选择先退出再登录
twSip.loginOut();
// 然后重新登录
}
// 重复登录会被阻止
const duplicateLoginResult = await twSip.login(loginInfo);
console.log(duplicateLoginResult.msg); // "当前已处于登录状态,请先退出登录再重新登录"
// ✅ 快速登出再登录现在是安全的
twSip.loginOut();
// 可以立即重新登录,不会有竞态条件问题
const reLoginResult = await twSip.login(loginInfo);返回码说明
200: 登录成功1000: WebSocket 连接失败1001: 坐席注册失败1002: 重复登录(新增)
API
isLoggedIn(): boolean
检查当前是否已登录
getLoginStatus(): object
获取详细的登录状态信息,包括:
isLoggedIn: 是否已登录registererState: 注册器状态hasUserAgent: 是否有用户代理hasRegisterer: 是否有注册器hasLoginInfo: 是否有登录信息loginInfo: 登录信息(仅在已登录时返回)
