实现Asterisk外接的管理程序
Asterisk是一个语音软交换软件,它支持VOIP等协议能够灵活地和手机网、电信固网电话相互对接进行语音交换。Asterisk这个软件的功能也很强大什么多方通话、会议和视频等等都一一集成,除此以为外它还是一个开源的系统,对它有兴趣的朋友不防了解一下。由于项目正在使用它,所以在这里介绍一下如何通过Socket tcp对Asterisk进行管理。(对于如何开如Asterisk的Socket Tcp管理功能,查看Manager.conf配置文件)。下面通过Smark.Net扩展Manager功能。
首先我们要对Asterisk Manger Api有个了解,详细查看:
http://www.voip-info.org/wiki/view/Asterisk+manager+API
协议包的大概格式是:
Action: <action type><CRLF>
<Key 1>: <Value 1><CRLF>
<Key 2>: <Value 2><CRLF>
每一行分别是以/r/n结束,消息结束符也是/r/n;简单的说只要包的某段内容是/r/n/r/n就表明该消息结束。根据这情况我实现一个分包功能:
public class DataAnalyes:Smark.Net.IDataAnalyse
{
#region IDataAnalyse 成员
public bool Eof(byte[] data,int index,int count,Smark.Net.IClient client)
{
if (index >= 3)
{
if (data[index] == 10 && data[index - 1] == 13 && data[index - 2] == 10 && data[index - 3] == 13)
{
return true;
}
}
return false;
}
#endregion
}
为了把Client区分开来,所以也实现一个ManagerClient:
public class ManagerClient:Smark.Net.Client<DataAnalyes>
{
public ManagerClient(System.Net.Sockets.Socket socket) : base(socket) { }
}
Socket tcp连接处理核心就扩展完成,下面就是对指令消息的封装。首先封装一个指令的基础类:
public abstract class APIBase:Smark.Net.IMessage
{
public APIBase()
{
ActionID = Guid.NewGuid().ToString("N");
}
public string ActionID
{
get;
set;
}
public virtual byte[] SaveData(Encoding coding)
{
StringBuilder sb = new StringBuilder();
sb.Append("Action: " + GetType().Name);
sb.Append("\r\n");
List<PropertyAttribute> properies = new List<PropertyAttribute>();
foreach (PropertyInfo pi in GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance))
{
PropertyAttribute[] pa = (PropertyAttribute[])pi.GetCustomAttributes(typeof(PropertyAttribute), false);
if (pa.Length > 0)
{
pa[0].Handler = pi;
properies.Add(pa[0]);
}
}
properies.Sort();
//根据每个属性值合拼参数值
foreach (PropertyAttribute p in properies)
{
sb.Append((p.Name==null?p.Handler.Name:p.Name) + ": " + p.Handler.GetValue(this, null));
sb.Append("\r\n");
}
sb.Append("ActionID: " + ActionID);
sb.Append("\r\n");
sb.Append("\r\n");
return coding.GetBytes(sb.ToString());
}
public void LoadData(byte[] data, Encoding coding)
{
throw new NotImplementedException();
}
public void Send(Smark.Net.IClient Client)
{
Client.Send(this);
}
}
实现Login命令
public class Login : APIBase
{
[PropertyAttribute(0)]
public string Username
{
get;
set;
}
[PropertyAttribute(1)]
public string Secret
{
get;
set;
}
}
实现Asterisk Manager的COMMAND命令。
public class Command : APIBase
{
[PropertyAttribute(0)]
public string command
{
get;
set;
}
}
到这里一个简单的基于Command指令的管理就完成,看上去是不是很简单。
接下来看下这东西到底可不可行了:)连接到Asterisk登陆一下看。
ManagerClient mc = Server<ManagerClient>.CreateClient("192.168.1.149", 5038);
mc.DataReceive += (o, e) => {
Console.WriteLine(Encoding.ASCII.GetString(e.Data));
};
mc.Receive();
Login login = new Login();
login.Username = "test";
login.Secret = "123456";
login.Send(mc);

:)提示登陆成功了。接下来执行一个Command指命.
Command cmd = new Command();
cmd.command = "core show applications";
cmd.Send(mc);

完整代码可以到Smark Google Code下载。
浙公网安备 33010602011771号