OpenSIPS 注册终端 30s 自动挂断问题

news2024/11/24 14:15:11

文章目录

  • 1. 背景
  • 2. 问题分析
  • 3. 案例解决

1. 背景

在开发呼叫中心应用时,使用 OpenSIPS 作为 SIP 注册服务器,测试发现偶现电话接通后 30s 左右自动挂断的问题。一个正常的 SIP 注册及呼叫流程如下所示,可以看到 OpenSIPS 作为转发层只负责代理转发请求

在这里插入图片描述

2. 问题分析

首先需要明确一点,对于被呼叫的 SIP 终端来说,如果一直收不到 SIP 服务器发送过来的 ACK 则认定会话异常,通常会在 30s 后主动发 BYE 结束会话。问题是确定的,根据以上流程图,具体分析时可以知道可能存在的问题点有两个:

  1. OpenSIPS 未收到 FreeSWITCH 发送过来的 ACK
    这种情况可能存在的问题是 FreeSWITCH 和 OpenSIPS 之间存在网络故障,导致 ACK 丢失。比较大的可能是 NAT 没有处理好,或者是网络协议不匹配等,可通过 sngrep 等工具抓包确认
  2. OpenSIPS 未正确转发 ACK
    OpenSIPS 收到了 FreeSWITCH 发送的 ACK,但是出于自身的问题,未正确将其转发到目标 SIP 终端。这种情况需要检查 OpenSIPS 脚本中处理 ACK 请求的部分,确认脚本逻辑是否存在问题

在这里插入图片描述

3. 案例解决

虽然以上分析的终端 30s 自动挂断问题的根因毫无问题,但在实践过程中导致 ACK 丢失的原因千差万别,非常复杂。在笔者的案例中,开发的应用需要保持坐席侧的会话常驻,当坐席的软电话被挂断时,需要自动的重新拨打坐席分机,以实现常驻的特性。在这个前提下,偶现坐席分机软电话 30s 自动挂断的问题,经过长时间的探索,笔者终于找到了必现步骤

  1. 坐席分机注册在 OpenSIPS 后,FreeSWITCH 呼叫坐席分机,坐席接通并常驻
  2. 此时使坐席分机所在网络 IP 漂移,如切换 WIFI 网络
  3. 挂断坐席软电话,让系统自动重新拨打坐席分机
  4. 坐席分机接通后,必现 30s 自动挂断

重新拨打坐席分机的 SIP 信令流程如下图所示,其中可以看到两个异常点:

  1. OpenSIPS 将 INVITE 信令转发给了两个不同的 IP 地址。这里之所以有两个不同的地址,是因为切网操作导致本地 IP 地址漂移,SIP 终端在当前网络下注册到 OpenSIPS 产生了一个新的 location。而对 OpenSIPS 来说,收到 INVITE 信令后会将请求同时送达被叫分机号的两个 location,一个 location 上的终端接通后取消其他 location 上的会话即可。真正的问题在于,在这个场景中一个分机号的两个 location 并没有真实对应两个 SIP 终端,其中一个 location 实际上并没有终端设备存在,所以发往该 location 的 INVITE 信令没有响应,只能不断重试
  2. SIP 终端接通响应 200 后,FreeSWITCH 将 ACK 发往 OpenSIPS,但 OpenSIPS 并没有将 ACK 转发到 SIP 终端真实所在的 location 上,而是将 ACK 发往了没有终端设备存在的 location,导致真实 location 位置上的 SIP 终端没有收到 ACK,最终造成 30s 自动挂断

基于以上分析,可以得出案例的解决方案:

  1. 将分机注册的 location 限制为 1 个,可以参考 max_contacts 参数
  2. 修改 OpenSIPS 脚本中 ACK 的转发逻辑,将 ACK 转发到正确的 location

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/923181.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spark Standalone环境搭建及测试

🥇🥇【大数据学习记录篇】-持续更新中~🥇🥇 篇一:Linux系统下配置java环境 篇二:hadoop伪分布式搭建(超详细) 篇三:hadoop完全分布式集群搭建(超详细&#xf…

Unity 之 GameObject.Find()在场景中查找指定名称的游戏对象

文章目录 GameObject.Find 是 Unity 中的一个函数,用于在场景中查找指定名称的游戏对象。这个函数的主要作用是根据游戏对象的名称来查找并返回一个引用,使您能够在代码中操作该对象。以下是有关 GameObject.Find 的详细介绍: 函数签名&…

rust actix-web定义中间件(middleware)记录接口耗时(接口耗时中间件和鉴权中间件)

文章目录 Actix-web定义中间件(middleware)记录接口耗时中间件简介中间件添加的两种方式(接口耗时中间件)使用wrap_fn 闭包实现使用warp struct实现中间件调用顺序actix自带的接口耗时中间件 鉴权中间件 Actix-web定义中间件(middleware)记录接口耗时 …

一文全懂!带你了解芯片“流片”!

一、流片是什么? 流片(tape-out)是指通过一系列工艺步骤在流水线上制造芯片,是集成电路设计的最后环节,也就是送交制造。 流片即为"试生产",简单来说就是设计完电路以后,先生产几片几十片,供测试…

Packet_Tracer的使用

一、实验目的: 通过该实验了解Packet Tracer的使用方法,能够用Packet Tracer建立和模拟网络模型。 二、主要任务: 1.熟悉PT的界面,了解按键用途。 2.尝试自己建立一个小型网络,并测试连通性。 3.学习P…

STM32--USART串口

文章目录 通信接口串口通信硬件电路电平标准参数时序 USART主要特性框图 数据帧发送器 波特率发生器SWART串口发送与接收工程串口收发数据包 通信接口 通信接口是指连接中央处理器(CPU)和标准通信子系统之间的接口,用于实现数据和控制信息在不…

【JVM 内存结构 | 程序计数器】

内存结构 前言简介程序计数器定义作用特点示例应用场景 主页传送门:📀 传送 前言 Java 虚拟机的内存空间由 堆、栈、方法区、程序计数器和本地方法栈五部分组成。 简介 JVM(Java Virtual Machine)内存结构包括以下几个部分&#…

关于CC2652的看门狗和系统时钟的我呢

看门狗 可以在CCS的syscfg的ui中配置&#xff0c;如下图 如果想看相关例程&#xff0c;可以电极最顶部watchdog旁边的问号 相关问题&#xff1a; 例程中没有添加hw_wdt的头文件&#xff0c;需要#include <ti/devices/cc13x2_cc26x2/inc/hw_wdt.h>&#xff0c;否则在获…

全面介绍ERP采购审批管理

在现代企业中&#xff0c;采购管理对于保障企业正常运营和维护供应链的稳定性至关重要。然而&#xff0c;传统的手动采购审批流程常常存在效率低下、易出错和缺乏可追溯性等问题。为了解决这些问题&#xff0c;越来越多的企业选择采用ERP采购审批管理方法&#xff0c;以实现更高…

CentOS7 TAR安装 EMQX(MQTT)

1、软件下载 官网 --> 右上角[免费试用] --> EMQX 下载 --> EMQX 开源版 --> 选择版本 系统 --> [免费下载] 选择 tar.gz amd64 --> [立即下载] 选择对应下载方式 上传到 /usr/local/ 目录下。 2、安装 #进入操作目录 cd /usr/local#创建安装目录 mk…

javascript常用的东西

JavaScript 是一门强大的编程语言&#xff0c;用于为网页添加交互性和动态性。也可以锻炼人们的逻辑思维&#xff0c;是一个非常好的东西。 一、变量和数据类型&#xff1a; 变量&#xff1a; 变量是用于存储数据值的容器。在 JavaScript 中&#xff0c;你可以使用 var、let…

ELK之LogStash介绍及安装配置

一、logstash简介 集中、转换和存储数据 Logstash 是免费且开放的服务器端数据处理管道&#xff0c;能够从多个来源采集数据&#xff0c;转换数据&#xff0c;然后将数据发送到您最喜欢的“存储库”中。 Logstash 能够动态地采集、转换和传输数据&#xff0c;不受格式或复杂度的…

2023.8 - java - Java 方法

什么是方法呢&#xff1f; Java方法是语句的集合&#xff0c;它们在一起执行一个功能。 方法是解决一类问题的步骤的有序组合方法包含于类或对象中方法在程序中被创建&#xff0c;在其他地方被引用 方法的命名规则 1.方法的名字的第一个单词应以小写字母作为开头&#xff0…

铁威马教程丨铁威马NAS如何使用安全顾问工具

在使用NAS的过程中&#xff0c;我们时常可能忽略了一些小细节&#xff0c;久而久之可能造成一定的风险&#xff0c;影响着我们NAS的健康。而使用铁威马NAS的安全顾问工具&#xff0c;可以快速地帮我们扫描系统设置是否安全&#xff0c;让我们更放心更安心地使用NAS。 安全顾问…

【Antd】Cascader 级联组件添加顶部栏(解决低版 antd 无 dropdownRender 属性方案)

文章目录 背景实现 背景 表单级联菜单需要添加表头&#xff0c;用于表示各级含义。 如果你的antd版本大于等于4.4.0&#xff0c;则直接可以使用dropdownRender 属性自定义&#xff0c;本篇文章可以直接跳过。 参数说明类型默认值版本dropdownRender自定义下拉框内容(menus: R…

LabVIEW利用线性压缩弹簧开发重量测量系统

LabVIEW利用线性压缩弹簧开发重量测量系统 柔性传感器的曲率半径相对于指定重量的变化特性可用作力测量方法。在许多应用中&#xff0c;例如&#xff1a;汽车和工业控制&#xff0c;计算机外围设备&#xff0c;操纵杆和测量设备&#xff0c;带有压缩弹簧和柔性传感器的重量测量…

【第三阶段】kotlin语言的takeUnless内置函数

1.takeUnless和takeif功能是相反的 username.takeif{true/false} true:返回username本身 false:返回null username.takeUnless{true/false} false:返回username本身 true:返回nullpackage Stage3 class Manager{private var info:String?nullfun getInfo()infofun setI…

ROS系统API接口

文章目录 一、 节点1. 节点初始化 ros API官网链接 一、 节点 1. 节点初始化 API名称&#xff1a;ros::init() ROS程序调用的第一个函数&#xff0c;用于对ROS程序的初始化。API常用形式&#xff1a; ros::init()函数最常见的使用方式为 ros::init(argc, argv, "my_n…

C++位域

Bit field 是什么&#xff1f; “ 位域 “ 或 “ 位段 “(Bit field)为一种数据结构&#xff0c;可以把数据以位的形式紧凑的储存&#xff0c;并允许程序员对此结构的位进行操作。这种数据结构的一个好处是它可以使数据单元节省储存空间&#xff0c;当程序需要成千上万个数据单…

Mybatis分页查询及特殊字符的处理

一. Mybatis分页查询 分页是我们在开发中绕不过去的一个坎&#xff01;当你的数据量大了的时候&#xff0c;一次性将所有数据查出来不现实&#xff0c;所以我们一般都是分页查询的&#xff0c;减轻服务端的压力&#xff0c;提升了速度和效率&#xff01;也减轻了前端渲染的压力…