You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyVoIP客户端未响应SIP服务器OPTIONS消息,呼叫异常如何解决?

解决pyVoIP客户端不响应OPTIONS请求导致来电丢失的问题

问题分析

SIP服务器发送OPTIONS请求是心跳检测机制,若客户端未返回200 OK响应,服务器会判定客户端离线,停止转发来电。pyVoIP库默认没有处理OPTIONS请求的逻辑,这就是来电时有时无的核心原因。

解决方案

通过继承VoIPPhone类并重写handle_request方法,手动处理OPTIONS请求并返回200 OK响应。同时修复原代码中的文件写入bug,优化循环逻辑。

修改后的完整代码

from pyVoIP.VoIP import VoIPPhone, CallState, PhoneStatus, InvalidStateError
from pyVoIP.SIP import SIPRequest, SIPResponse
import time
import datetime

class CustomVoIPPhone(VoIPPhone):
    def handle_request(self, request):
        # 处理OPTIONS请求,返回200 OK
        if request.method == "OPTIONS":
            response = SIPResponse(200, "OK", request)
            self.sip.send(response)
            return
        # 其他请求交给父类处理
        super().handle_request(request)

def answer(call):
    try:
        print(call.state)
        anum = call.request.headers["From"]["number"]
        # 构造日志行
        log_line = f',{datetime.datetime.now().strftime("%Y%m%d")}, {datetime.datetime.now().strftime("%X")}, {datetime.datetime.now().strftime("%f")},,,,,,,{anum},0662279775,,,'
        print(log_line)
        # 追加写入日志文件(修复原代码未赋值文件对象的bug)
        with open('tmp.csv', 'a+', encoding='utf-8') as f:
            f.write(log_line + '\n')
        print(anum)
        call.answer()
        call.hangup()
    except InvalidStateError as e:
        print(e)
        pass

if __name__ == "__main__":
    # 使用自定义的电话类
    vp = CustomVoIPPhone('79.98.45.133', 5060, '06xxxxx', 'xxxxxxxx', callCallback=answer)
    print(f'VOIP PHONE INITIALIZED: status = {vp._status}')
    vp.start()
    print(f'VoIP PHONE STARTED: status = {vp._status}')
    # 等待注册完成,添加sleep避免CPU空转
    while vp._status in (PhoneStatus.REGISTERING, PhoneStatus.INACTIVE):
        time.sleep(0.1)
    print(f'WHILE LOOP STATUS ENDED: status = {vp._status}')
    input('Press ENTER to stop')
    time.sleep(5)
    vp.stop()
    print(f'STOPPED VOIP PHONE: status = {vp._status}')
    time.sleep(5)

关键修改说明

  1. OPTIONS请求处理:自定义CustomVoIPPhone类,重写handle_request方法,识别OPTIONS请求后立即返回200 OK响应,让服务器确认客户端在线。
  2. 文件写入修复:原代码中open后未将文件对象赋值给f,导致f.write报错;改用with语句自动管理文件,并使用a+模式追加日志(避免每次清空文件)。
  3. 循环优化:等待注册状态时添加time.sleep(0.1),降低CPU占用。

内容的提问来源于stack exchange,提问作者Giorgio Torassa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 22:34:53