iad_simulator项目设计介绍
一、源码路径
https://github.com/weiganyi/iad_simulator
二、背景
我在工作中有时会要拿我们的IAD产品去对接一些异常SIP报文,通常是用一些UDP发包工具(如UDP Test Tool)来模拟给IAD发SIP异常报文。这种方法一方面没办法把SIP信令流程串起来,因为SIP发送和接收消息的一些字段有依赖关系,另一方面定制过的消息没法保存下来供下次使用。
我想写一个工具来为这种工作提供便利,这里面主要的工作是进行字符串的替换和匹配,在这方面解释脚本语言比编译语言有优势,所以我选择了Python语言,而不是C或C++。另外我们通常在Window操作系统上工作,需要有图形界面来方便操作,因为命令行会降低使用者的接受度,Python语言的Window图形库主要是wxPython,所以我使用这个库来做GUI。在做图形界面时如果都是自己编码的话会比较累,有一些拖拉式的开发工具可以帮助我,我选择的是Boa Constructor。
三、功能实现
工具主要完成如下功能:
1、能够通过GUI界面定制SIP信令发送和接收流程,按照流程完成与实际SIP终端或者SIP服务器之间的通信。
2、能够对用例脚本进行管理,并提供了一些常用的SIP消息模板,也可以基于消息模板通过GUI界面来定制特殊的SIP消息报文内容。
3、由于SIP发送和接收消息的一些字段有依赖关系,所以构造消息时要能够引用之前发送或者接收消息的某些字段,从而完成完整的信令流程。
四、总体设计思路
1、在图形界面方面,Boa Constructor可以通过拖拉的方式完成主框架界面,自动生成相应的代码。而树和表格的内容取决于文件读取的结果,所以需要在读取相应文件后,调用wxPython接口来动态创建。
2、界面线程和用例运行线程要分开,避免界面卡死,另外收发包线程负荷较重也要独立,所以定义如下线程:主界面、脚本运行、SIP包接收、SIP包发送、RTP包发送、RTP包接收。
3、由于工具逻辑较简单,代码规模整体不大,线程间交互也比较少,所以放弃消息串行的actor模式,采用轻量级锁作为线程间同步方式。
4、定义了如下全局对象:communicator、runner、codec、rtp。
5、设备配置信息和消息模板都不太复杂,采用ini格式文件来存储,Python可以通过相应的configobj库来读写,并且被解析成字典结构。
6、用例运行主要执行流如下:界面框架传递用例文件名给runner对象,runner对象起线程读取文件内容并执行,communicator对象编码消息后入socket队列,socket发送线程等待socket队列消息然后发送,或者communicator对象等待socket队列,socke接收线程接收消息后入socket队列。
五、文件及类的设计
module.py:定义了项目需要载入的模块,供其他文件调用,减少冗余代码。
iad_simulater.py:定义应用程序对象类BoaApp,由Boa Constructor生成。
frame_window.py:定义了主框架窗口类frame_window,这个类运行在主界面进程。包含三个树的显示和操作,用例树中每个用例节点有三个数据结构对应:py文件、树节点、节点子窗口。还包含了菜单命令和工具栏命令的主要实现,通过观察者模式反映当鼠标选择GUI界面不同控件时,相应的菜单和工具栏的调整变化。
case_window.py:定义了用例子窗口类case_window,包含用例表格的显示和编辑,用例表格中每一步骤行都有一个字符串记录这行发生改变的消息。
msg_window.py:定义了消息子窗口类msg_window,包含模板消息窗口的显示和编辑。
device_window.py:定义了消息子窗口类device_window,包含设备参数配置窗口的显示和编辑。
msg_dialog.py: 定义了消息编辑对话框msg_dialog,可以对消息进行编辑。
com.py:自定义通信对象类communicator,定义了通信对象的系列方法,在用例脚本里面通过一系列的通信对象方法调用来作为执行步骤。启动socket和消息队列,从消息队列接收sip或rtp消息,然后通过socket发送出去,同时在socket监听接收消息,然后通过消息队列返回。
runner.py:自定义的脚本运行类runner,启动独立的运行进程来运行脚本,并显示运行结果。
codec.py:自定义SIP消息编解码类codec,从消息字典读取消息,并对消息中的关键字进行替换,生成实际发送的SIP消息。或者把实际接收的消息与预期消息模板进行匹配,返回匹配结果。
util.py:包括各种辅助函数,如日志输出、设备参数读写、消息模板读写、字符串处理等。还包括观察者模式对象类observer的实现。