2012-07-19 42 views
0

这是我的代码的事件连接到Asterisk的管理接口:我不能从Asterisk管理器界面

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text.RegularExpressions; 
using System.Text; 
using System.Windows.Forms; 
using System.Net.Sockets; 
using System.Net; 
using System.IO; 


namespace WindowsFormsApplication1 
{ 

public partial class Form1 : Form 
{ 

    private Socket clientSocket; 
    private byte[] data = new byte[1024]; 
    private int size = 1024; 
    //------------------------------------------------------------------------------------------ 
    public Form1() 
    { 
     InitializeComponent();    
    } 

    //------------------------------------------------------------------------------------------ 
    [STAThread] 
    private void BtnConnect_Click(object sender, EventArgs e) 
    { 
     try 
     { 
      AddItem("Connecting..."); 
      clientSocket = new Socket(AddressFamily.InterNetwork, 
            SocketType.Stream, ProtocolType.Tcp); 
      IPEndPoint iep = new IPEndPoint(IPAddress.Parse("192.168.1.155"), 5038); 
      clientSocket.BeginConnect(iep, new AsyncCallback(Connected), clientSocket); 
     } 
     catch (Exception exp) 
     { 

      AddItem(exp.Message); 
     } 
    } 

    //------------------------------------------------------------------------------------------ 
    private void BtnDisconnect_Click(object sender, EventArgs e) 
    { 
     clientSocket.Close(); 
    } 

    //------------------------------------------------------------------------------------------ 
    void Connected(IAsyncResult iar) 
    { 
     clientSocket = (Socket)iar.AsyncState; 
     try 
     { 
      clientSocket.EndConnect(iar); 
      AddItem("Connected to: " + clientSocket.RemoteEndPoint.ToString());     
      clientSocket.BeginReceive(data, 0, size, SocketFlags.None, 
          new AsyncCallback(OnDataReceive), clientSocket); 
     } 
     catch (Exception exp) 
     { 
      AddItem("Error connecting: " + exp.Message); 
     } 
    } 
    //------------------------------------------------------------------------------------------ 

    private void OnDataReceive(IAsyncResult result) 
    { 
     Socket remote = (Socket)result.AsyncState; 
     int recv = remote.EndReceive(result); 
     string stringData = Encoding.ASCII.GetString(data, 0, recv); 
     AddItem(stringData); 
    } 

    //------------------------------------------------------------------------------------------ 
    private delegate void stringDelegate(string s); 
    private void AddItem(string s) 
    { 
     if (ListBoxEvents.InvokeRequired) 
     { 
      stringDelegate sd = new stringDelegate(AddItem); 
      this.Invoke(sd, new object[] { s }); 
     } 
     else 
     { 
      ListBoxEvents.Items.Add(s); 
     } 
    } 

    //------------------------------------------------------------------------------------------ 
    private void BtnLogin_Click(object sender, EventArgs e) 
    { 
     clientSocket.Send(Encoding.ASCII.GetBytes("Action: Login\r\nUsername: admin\r\nSecret: lastsecret\r\nActionID: 1\r\n\r\n")); 
    } 

    //------------------------------------------------------------------------------------------ 


} 
} 

的问题是,当我连接到服务器,我收到“Asterisk的呼叫管理器/ 1.1”的字样。连接到服务器后,我登录到服务器,但没有收到任何消息。我想从星号获取事件。使用网络套接字有问题吗?我应该使用一个特殊的命令告诉星号我想接收事件。

回答

2

是的。所以这不是AMI配置的问题。

你开始,当你连接完成一个BeginReceive - 但一旦你收到一次数据,你不启动新的BeginReceive。

你需要在OnDataReceive再次调用BeginReceive,所以,它试图从插座再次读取。

clientSocket.BeginReceive(data, 0, size, SocketFlags.None, 
          new AsyncCallback(OnDataReceive), clientSocket); 

我在下面保留我的原始答案,因为这些信息仍然是您应该检查的内容。我会再次重申我的“供参考” - 除非您为了教育目的而这么做,您应该真的使用现有的AMI库 - 特别是如果您不熟悉TCP。

[原创]

您要发送什么用户名和密码?你确定该帐户已经正确配置发送事件吗?

一旦验证通过登录您与Asterisk连接,你应该开始自动接收事件。但请记住,您需要适当的读取授权类权限才能接收某些类型的事件。从样品manager.conf:

; Authorization for various classes 
; 
; Read authorization permits you to receive asynchronous events, in general. 
; Write authorization permits you to send commands and get back responses. The 
; following classes exist: 
; 
; all  - All event classes below (including any we may have missed). 
; system - General information about the system and ability to run system 
;    management commands, such as Shutdown, Restart, and Reload. 
; call  - Information about channels and ability to set information in a 
;    running channel. 
; log  - Logging information. Read-only. (Defined but not yet used.) 
; verbose - Verbose information. Read-only. (Defined but not yet used.) 
; agent  - Information about queues and agents and ability to add queue 
;    members to a queue. 
; user  - Permission to send and receive UserEvent. 
; config - Ability to read and write configuration files. 
; command - Permission to run CLI commands. Write-only. 
; dtmf  - Receive DTMF events. Read-only. 
; reporting - Ability to get information about the system. 
; cdr  - Output of cdr_manager, if loaded. Read-only. 
; dialplan - Receive NewExten and VarSet events. Read-only. 
; originate - Permission to originate new calls. Write-only. 
; agi  - Output AGI commands executed. Input AGI command to execute. 
; cc  - Call Completion events. Read-only. 
; aoc  - Permission to send Advice Of Charge messages and receive Advice 
;   - Of Charge events. 
; test  - Ability to read TestEvent notifications sent to the Asterisk Test 
;    Suite. Note that this is only enabled when the TEST_FRAMEWORK 
;    compiler flag is defined. 

所以,说我想为用户“富”,密码为“栏”进行身份验证,没有ACL的定义,我想接收所有事件。我也只想执行'system'和'call'类命令。我需要建立我的用户在manager.conf为:

[foo] 
secret = bar 
read = all 
write = system,call 

作为一个供参考 - 你可以在这里的轮上发明了重新。除非您将自己的AMI库创建为练习,否则您可能需要考虑使用Asterisk .NET

+0

谢谢马特。其实我并不熟悉TCP。我不熟悉.NET套接字编程。 – Karadous 2012-07-21 06:55:00