在通话过程中,如果碰到「无法发起通话」,「通话发起后异常退出」,「接听方一接听就挂断」,「通话异常退出」等问题,可以参考本文进行排查。
一次通话有 「拨打方」(或「来电方」、「主叫」) 和 「接听方」(或「被叫」) 两个角色。通常,我们可以将一次硬件和微信小程序之间的 VoIP 通话分为 「发起」、「加入」、「等待」和「通话」 四个阶段。不同阶段可能会有不同类型的问题,在排查时,应首先根据表现确定是哪个阶段出现异常,在按照具体阶段的指引进行进一步分析。
建议使用插件 2.3.2 及以上版本。
1. 发起阶段
发起阶段是指调用插件 initByCaller 接口或 Linux SDK wx_voip_session_call 创建 VoIP 房间的阶段。在此阶段中,微信后台会进行一系列通话前置的检查操作,包括但不限于:
- voipToken 的有效性。
- 用户和设备之间是否存在授权关系。
- 微信小程序流量包是否有余量,或设备是否已绑定有效的 license。
校验通话后,微信后台会向接听方推送通话提醒。
在发起阶段如果失败,接口会返回 errCode,开发者可以根据插件文档的说明来排查问题原因,比较常见的错误有以下几类。
(1) 用户未授权设备 (errCode: 9)
设备要和微信用户通话,必须先进行授权,具体过程请参考《用户授权设备》文档。
出现此错误,常见的有以下情况:
- 未使用
wx.requestDeviceVoIP向用户请求过授权,或请求后用户拒接授权; - 用户曾经授权过,但是后续取消了授权;
- 用户从最近使用中删除了微信小程序。此时会清空该用户和微信小程序间的所有授权记录;
- 传入的 openId 不是要拨打给用户的,例如:授权的是家长,这里传入了孩子的 openId。
在使用设备组的情况下,常见还有以下情况:
- 用户授权了设备组 A,但设备未被添加到设备组 A 中或已被
removeIotGroupDevice接口移除; - 用户授权了设备组 A,但设备被使用
addIotGroupDevice(force_add=true) 强制转移到了另一设备组 B,也会导致设备从设备组 A 里移除。
优化建议
建议使用授权状态查询 接口,判断用户和设备/设备组直接是否存在授权关系。
- 手机微信内发起通话前,建议提前调用
wx.getDeviceVoIPList查询用户已授权设备的列表,判断设备已被授权再发起通话,否则应请求用户重新授权; - 设备发起通话前,建议提前调用插件
getIotBindContactList接口判断设备和用户间是否存在授权关系,存在时再发起通话,否则应提示用户重新授权;
对于设备组,可以使用 getIotGroupInfo 查询设备组中的设备列表。
(2) 设备呼叫手机微信 voipToken 错误 (errCode: 13)
对于使用设备认证 SDK 注册的设备(此时 voipToken 传入 SDK 获取到的 deviceToken),常见有以下情况:
deviceToken过期。deviceToken是有一定有效期的,需要定时进行更新,如果获取时间过久会失效。- 未传入
voipToken字段或传入空字符串。此方式仅适用于使用 WMPF registerMiniProgramDevice 接口注册的设备。
对于使用 WMPF 注册的设备,可能有以下情况:
- 设备之前是使用设备认证 SDK 的,未使用 WMPF 的 registerMiniProgramDevice 接口重新注册过。
- WMPF 低于 1.2.0,或插件版本低于 2.3.0。
2. 「拨打方」加入阶段
创建 VoIP 房间成功后,「拨打方」会直接加入该房间,界面上会显示「连接中…」。加入的时长一般与当前网络状态有关。
加入成功后,拨打方会触发 joinedRoomByCaller 事件。
(1) 设备之前可以拨打成功,突然开始持续失败,需重启 WMPF 才能恢复
大概率是安卓 WMPF 低版本的 bug,请升级到 >= 2.0 版本解决。如新版本仍发现类似问题,请参考第 8 节反馈。
这种情况下开发者可能会收到 joinFailCaller 事件,errMsg 包含 Already in room or joining,此时可以尝试重启 WMPF。
(2) 一直显示「连接中」(卡在本阶段),无法加入房间,通话被突然结束
可能是网络状况较差导致加入过慢,此时通话可能会因接听方等待超时而结束,触发 abortVoip 和 endVoip 事件。
(3) 未加入房间就直接退出通话
常见原因有:
- 微信小程序错误调用插件
forceHangUpVoip接口挂断通话,触发cancelVoip事件和endVoip事件(Toast 提示 「通话已被微信小程序结束」)。- 之前排查遇到部分微信小程序会设置定时器来设置通话的最大时长,通话结束后,某些情况下计时器没有清理导致在后续某次通话时随机挂断通话。
- 我们建议通过监听
calling事件,并判断 keepTime 来限制通话时长,不建议使用定时器。
- 因网络超时或其他异常导致加入房间失败,这种情况下拨打方会收到
joinFailCaller事件,可以通过 data 字段拿到 errMsg 和 message 来分析错误原因。