asterisk有一个很好的东东,就是Event,会主动通知客户端服务器发生了什么……不过前提是你得先连上服务器。
好,不废话了,下面开工。
首先声明下环境:CentOS 6
一、安装并配置asterisk
1、下载asterisk
wget
2、解压并安装
tar zxvf asterisk-1.8.7.1.tar.gz
cd asterisk-1.8.7.1
./configure && make && make install && make samples
涉及的命令:
yum install libxml2-devel
yum install ncurses-devel
3、开启AMI管理
编辑manager.conf文件,将general中的enabled置为yes
添加管理员:
[admin]
secret = 123456
read = system,call,log,verbose,agent,user,config,dtmf,reporting,cdr,dialplan
write = system,call,agent,user,config,command,reporting,originate
二、编写Asterisk事件监控程序
原理:通过login action连上Asterisk的5038端口,监听此端口并把消息输出。
下面是C++实现的代码:
1 /* 2 File : asteriskEventCat.cpp 3 Author : Mike 4 E-Mail : Mike_Zhang@live.com 5 */ 6 7 #include8 #include 9 #include 10 #include 11 #define BLOCK_SIZE 10*1024 12 13 using namespace std; 14 using namespace boost::asio; 15 16 string strLogin(string userName,string pswwd) 17 { 18 string msg=""; 19 msg = "Action: login\r\n"; 20 msg += "UserName: " + userName + "\r\n"; 21 msg += "Secret: " + pswwd + "\r\n"; 22 msg += "\r\n"; 23 return msg; 24 } 25 26 int main() 27 { 28 io_service iosv; 29 ip::tcp::socket s(iosv); 30 string svrIp = ""; 31 cout<<"Input server ip : "; 32 cin>>svrIp; 33 ip::tcp::endpoint ep(ip::address_v4::from_string(svrIp.c_str()),5038); 34 35 boost::system::error_code ec; 36 s.connect(ep,ec); 37 if(ec) 38 { 39 cout << boost::system::system_error(ec).what() << endl; 40 return -1; 41 } 42 else 43 { 44 cout<<"Connect success!"< >userName; 52 cout<<"Password : "; 53 cin>>password; 54 55 msg += strLogin(userName.c_str(),password.c_str()); 56 // msg += strLogin("admin","admin"); 57 size_t len = s.write_some(buffer(msg.c_str()), ec); 58 if(len <= 0) 59 { 60 cout<<"Send message fail!"<
三、进行事件监控
首先要保证你的防火墙让你过5038端口,嫌配置麻烦的话把防火墙关闭就行了,下面是运行效果:
我这人比较懒,虽是所谓的C/C++程序员,可是总嫌C++写的代码多,经常用python做模型,
下面是我之前写的,这里也顺便粘出来一起总结,仅供参考,欢迎拍砖。
Python代码:
''' File : asteriskEventCat.py Author : Mike E-Mail : Mike_Zhang@live.com'''import socketbufLen = 1024 * 10def strLogin(userName,passwd): msg = 'Action: login\r\n' msg += 'UserName: '+userName+'\r\n' msg += 'Secret: '+passwd+'\r\n' msg += '\r\n' return msgdef main(): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((raw_input("Input ip : "), 5038)) ifnot s : print"Connect fail!" return s.send(strLogin(raw_input("Input user name :"),raw_input("Input password :"))) whileTrue: data = s.recv(bufLen) iflen(data) <=0 : continue print dataif __name__ == '__main__': main() raw_input("Press Enter to continue")
现在在学习go语言,捎带下,也方便我以后Ctrl + C:
/* File : asteriskEventCat.go Author : Mike E-Mail : Mike_Zhang@live.com*/package mainimport ( "net" "bufio" "os")var bufLen = 1024 * 10var lineLen = 2 // windows : "\r\n" 2 ; linux : "\n" 1func main() { reader := bufio.NewReader(os.Stdin) print("Input ip : ") ; svrIp, _ := reader.ReadBytes('\n') print("Input userName : ") ; usrName, _ := reader.ReadBytes('\n') print("Input passwd : ") ; pwd, _ := reader.ReadBytes('\n') conn,err := net.Dial("tcp",string(svrIp[0:len(svrIp)-lineLen])+":5038") defer conn.Close() if err != nil { println("Error : ",err.Error()) //In go 1 , use err.Error() ,not err.String() } conn.Write([]byte("Action: login\r\nUserName: "+ string(usrName[0:len(usrName)-lineLen])+"\r\nSecret: "+ string(pwd[0:len(pwd)-lineLen])+"\r\n\r\n")) for { p := make([]byte,bufLen) sz, _ := bufio.NewReader(conn).Read(p) println(string(p[0:sz])) }}
好,就这些了,希望对你有帮助。