• asterisk事件监控


    asterisk有一个很好的东东,就是Event,会主动通知客户端服务器发生了什么……不过前提是你得先连上服务器。

    好,不废话了,下面开工。

    首先声明下环境:CentOS 6

    一、安装并配置asterisk

    1、下载asterisk

    wget http://downloads.asterisk.org/pub/telephony/asterisk/releases/asterisk-1.8.7.1.tar.gz

    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连上Asterisk5038端口,监听此端口并把消息输出。 

    下面是C++实现的代码: 

     1 /*
    2 File : asteriskEventCat.cpp
    3 Author : Mike
    4 E-Mail : Mike_Zhang@live.com
    5 */
    6
    7 #include <iostream>
    8 #include <string>
    9 #include <fstream>
    10 #include <boost/asio.hpp>
    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!"<<endl;
    45 }
    46
    47 string msg="";
    48
    49 string userName,password;
    50 cout<<"User : ";
    51 cin>>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!"<<endl;
    61 return -1;
    62 }
    63
    64 std::ofstream fout("EventCat.txt");
    65 while(true)
    66 {
    67 char buf[BLOCK_SIZE] = {0};
    68 len=s.read_some(buffer(buf), ec);
    69 if(len<=0)
    70 break;
    71 cout.write(buf, len);
    72 fout<<buf;
    73 fout.flush();
    74 }
    75
    76 return 0;
    77 }

     

    三、进行事件监控 

    首先要保证你的防火墙让你过5038端口,嫌配置麻烦的话把防火墙关闭就行了,下面是运行效果:

     我这人比较懒,虽是所谓的C/C++程序员,可是总嫌C++写的代码多,经常用python做模型,

    下面是我之前写的,这里也顺便粘出来一起总结,仅供参考,欢迎拍砖。 

    Python代码: 

    '''
            File      : asteriskEventCat.py
            Author    : Mike
            E-Mail    : Mike_Zhang@live.com
    '''
    import socket
    
    bufLen = 1024 * 10
    def strLogin(userName,passwd):
            msg = 'Action: login\r\n'
            msg += 'UserName: '+userName+'\r\n'
            msg += 'Secret: '+passwd+'\r\n'
            msg += '\r\n'
            return msg
    def 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 data
    if __name__ == '__main__':
            main()
            raw_input("Press Enter to continue")

    现在在学习go语言,捎带下,也方便我以后Ctrl + C: 

    /*
            File      : asteriskEventCat.go
            Author    : Mike
            E-Mail    : Mike_Zhang@live.com
    */
    package main
    
    import (
            "net"
            "bufio"
            "os"
    )
    
    var bufLen = 1024 * 10
    var lineLen = 2 // windows : "\r\n" 2 ; linux : "\n" 1
    
    func 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]))
            }
    }

    好,就这些了,希望对你有帮助。

  • E-Mail : Mike_Zhang@live.com
  • 转载请注明出处,谢谢!
  • 相关阅读:
    输入任意十进制数字,转换为任意进制表示
    Integer 原码解读
    Java 中位移运算符 >>,>>>,<<
    解读源码中的问题
    HashMap 源码解读
    js:插入节点appendChild insertBefore使用方法
    冒泡排序实例
    nodejs学习笔记(2)--Express下安装模版引擎ejs
    nodejs学习笔记(1)--express安装问题:express不是内部也或者外部的命令解决方案
    Jquery取得iframe中元素的几种方法
  • 原文地址:https://www.cnblogs.com/MikeZhang/p/asteriskEventCatch.html
  • Copyright © 2020-2023  润新知