首页 > 系统相关 >freeswitch笔记(4)-esl inbound模式的重连及内存泄露问题

freeswitch笔记(4)-esl inbound模式的重连及内存泄露问题

时间:2023-02-07 18:22:23浏览次数:49  
标签:重连及 canSend inbound connect freeswitch close esl 断点 channel

esl inbound client,内部有一个canSend()方法:

1 2 3 public boolean canSend() {     return channel != null && channel.isConnected() && authenticated; }

大多数情况下(之所以说大多数情况是因为最末尾还有一个authenticated),都可以用它来检测网络是否断开,如果断开了,可以自己写代码重连(注:0.9.2版本依赖的netty较老,esl client本身也并没有重连逻辑)。

而且在org.freeswitch.esl.client.inbound.Client#connect()方法里,有一个判断:

如果之前有连着,先close断开,接下来看close方法:

这里又做了1次网络检测,checkConnected实现如下:

看上去很严谨,双重检测,感觉重连时只要再调用1次connect就可以了,但是这里有一个陷阱:如果channel连接正常,但是authenticated=false,canSend()就返回false,这时候再去connect,先前的连接并不会释放,造成连接泄露!

为了重现这个问题,我们先准备一段代码:

+ View Code

代码很简单,先连上,然后用一个循环不停检测canSend(),发现"断开"了,就重连。 

参考上图,在if条件这行打一个断点,然后利用调试工具,在断点处,强制把inboundClient.authenticated改成false(不清楚该调试技巧的同学,可参考之前的旧文idea 高级调试技巧),同时打开一个终端窗口,在程序运行前、断点修改前、断点修改并完成connect后,分别用lsof -i:8021观察下本机的连接情况

如上图:
1) 程序运行前,只有一个freeswitch在监听本机的8021端口
2) 启用成功后,在断点修改前,java进程13516,建立了1个连接(对应的随机端口号为58825)
3) 断点修改后,继续运行到connect后,还是13516进程,又建立了1个连接(对应的随机端口号为58857),而之前的旧连接(58825)并没有释放,哪怕这里我用new Client()生成了一个全新的实例,旧实例关联的连接资源仍然在!
4) 继续这样操作,会发现每次都会创建1个新链接,而原来的链接依然存在。

解决方法:重连先调用channel.close()方法,关闭channel,可以在源码中,加一个方法closeChannel

1 2 3 4 5 6 7 8 9 10 11 /**  * close netty channel  *  * @return  */ public ChannelFuture closeChannel() {     if (channel != null && channel.isOpen()) {         return channel.close();     }     return null; }

然后connect开头那段检测改成:

1 2 3 4 5 6 7 // If already connected, disconnect first if (canSend()) {     close(); else {     //canSend()=false but channel is still opened or connected     closeChannel(); }

这里说点题外话,channel类有isOpen、isConnected 二个方法,另外还有close()及disconnect()方法,有啥区别?

isOpen=true时,该channel可write,但是不能read (即:打开,但是没连网)
isConnected=true,该channel可read/write(即:真正连上了网),换句话说:isOpen=true,未必isConnected=true,但是isConnected=true,isOpen必须为true.

这里我们旨在重连前释放channel的所有资源,所以用close更彻底点。

 

再来看看内存泄露的问题,这个问题其实已经有网友记录过了,大致原因是netty底层大量使用了DirectByteBuffer,这是直接在堆外分配的(即:堆外内存),不会被GC自动回收,如果代码处理不当,多次调用connect()时,就有可能内存泄露。按该网友的建议,改成static静态实例后,保证只有1个实例就可以了。细节不多说,代码最后会给出,这里谈另一个问题:

这里使用的是newCachedThreadPool方法,查看该方法源码可知:

线程池的最大线程数是MAX_VALUE,相当于没有上限,如果异常情况下,线程会一直上涨,直到资源用完, 最好换成明确有上限的写法。

另外,还有1个细节问题,Client只提供了添加事件监控的方法:

1 2 3 4 5 public void addEventListener(IEslEventListener listener) {     if (listener != null) {         eventListeners.add(listener);     } }

但却没有提供移除的方法,如果重连时,无意重复调用了该方法,同样的事件(即:同一个listener重复注册),就会处理多次,可以新增一个清空方法,每次重连前,最好调用一下:

1 2 3 4 5 6 7 8 /**  * remove all eslEventlistener  */ public void removeAllEventListener() {     if (eventListeners != null) {         eventListeners.clear();     } }

以上修改已经提交到github,需要的朋友可参考https://github.com/yjmyzz/esl-client/tree/0.9.x

标签:重连及,canSend,inbound,connect,freeswitch,close,esl,断点,channel
From: https://www.cnblogs.com/kn-zheng/p/17099424.html

相关文章

  • FreeSwitch:send_dtmf/uuid_send_dtmf发送按键注意事项
    很多时候我们打电话到公司前台,会听到类似“欢迎致电XXX,办公电话请直拨分机,咨询XX请按1,咨询YY请按2”这样的语音提示。在一些特定流程中,系统自动发起呼叫打到前台,希望实现自......
  • freeswitch批量添加用户
    默认情况下,freeswitch内置了1000-1019这20个用户,如果需要添加更多用户,可以按如下步骤操作:一、复制用户文件\FreeSWITCH\conf\directory\default 下有1000.xml~1019.xm......
  • freeswitch: 如何指定主叫显示号码
    一、origiante时指定主叫号码正常情况下,如果在freeswitch控制台,输入类似下面 命令:originateuser/1000 &park被叫收到振铃提示时,显示的号码类似下面......
  • freeswitch 编译安装 折腾
      echo"signalwire">/etc/yum/vars/signalwireusernameecho"TOKEN">/etc/yum/vars/signalwiretokenyuminstall-yhttps://$(</etc/yum/vars/signalwireuserna......
  • freeswitch号码黑名单
      概述freeswitch是一款简单好用的的VOIP开源软交换平台。在客户的呼叫过程中,会遇到一些异常的号码,包括高投诉风险号码、敏感号码、特殊号码等。在客户呼叫流程中,......
  • freeswitch的多租户模式
      概述freeswitch是一款简单好用的VOIP开源软交换平台。现在的VOIP服务越来越倾向于云端服务,包括呼叫中心云服务,线路云平台。而云平台对多个客户的服务就需要做好......
  • FreeSWITCH命令大全
    FreeSWITCH启动、查看、及关闭FreeSWITCH一般安装在路径/usr/local/freeswitch,可执行程序位于/usr/local/freeswitch/bin下,配置文件位于/usr/local/freeswitch/conf......
  • C语言中使用ESL连接FreeSwitch
    前言之前在【FreeSwitch开发实践】在nodejs中用ESL连接FreeSwitch一文介绍了在NodeJS下使用ESL连接FreeSwitch,本文则对在C语言下使用ESL连接FreeSwitch作了一个系统介绍......
  • 针对FreeSWITCH的最佳开源GUI解决方案
    为了获得FreeSWITCH的最大利益,您需要能够正确选择GUI解决方案。看看FreeSWITCH的一些开源GUI解决方案,见证了它们的广泛普及和采用率。FreeSWITCHGUI被广泛地描述为FsG......
  • 手把手教你部署验证freeswitch(避免踩坑)
    介绍:freeswitch可集成ASR(语音识别)和TTS(文本转语音)创建智能电话机器人和用户通话,可用于问卷调查,自动催缴等业务,电话咨询服务,支持百度,科大,阿里云,腾讯等ASR系统,可以真人预......