1

これは、AsteriskManagerインターフェイスに接続するための私のコードです。

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"));
    }

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


}
}

問題は、サーバーに接続すると、「AsteriskCallManager/1.1」メッセージが表示されることです。サーバーに接続した後、サーバーにログインしましたが、メッセージが表示されません。アスタリスクからイベントを取得したい。ネットワークソケットの使用に問題はありますか?特別なコマンドを使用して、イベントを受信することをアスタリスクに通知する必要があります。

4

1 に答える 1

3

[編集]

うん。したがって、これはAMI構成の問題ではありません。

接続が終了したときにBeginReceiveを開始しますが、一度データを受信すると、新しいBeginReceiveを開始しません。

OnDataReceiveでBeginReceiveを再度呼び出して、ソケットからの読み取りを再試行する必要があります。

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

その情報はまだあなたがチェックすべきものなので、私は以下に私の元の答えを保持しています。私の「FYI」をもう一度繰り返します。教育目的でこれを行う場合を除いて、特にTCPに精通していない場合は、既存のAMIライブラリを実際に使用する必要があります。

[オリジナル]

送信するユーザー名とパスワードは何ですか?アカウントがイベントを送信するように適切に構成されていることを確認しますか?

ログインして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が定義されていない、パスワード「bar」を使用してユーザー「foo」として認証し、すべてのイベントを受信したいとします。また、「system」および「call」クラスコマンドのみを実行できるようにしたい。manager.confでユーザーを次のように設定する必要があります。

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

参考までに、ここで車輪の再発明をしているかもしれません。演習として独自のAMIライブラリを作成する場合を除いて、Asterisk.NETの使用を検討することをお勧めします。

于 2012-07-19T13:28:12.420 に答える