c#异步套接字通过接口

时间:2016-04-24 12:42:49

标签: c# sockets asynchronous event-handling

在这里忍受我,并尝试在不良做法上轻松一下:)

我开始理解接口的概念,我已经在我的程序中实现了一个..所以我会尝试解释..我正在创建一个类库dll,它将与我的报警面板接口。报警面板可以有两种类型的连接,IP和串口..所以我已经实现了一个名为IConnection的接口。

并按如下方式创建连接:

//IConnection connection = new SerialConnection("com1", 9600);
IConnection conn = new TcpConnection(System.Net.IPAddress.Parse("192.168.0.14"), 1234);

AlarmPanel alarm = new AlarmPanel(conn, Pass);
alarm.SetLogger(logger);
alarm.Connect();

在具体的类中(正确的术语?)我实现了一个名为SendMessage的方法,我用它来做运输不可知的工作。

但是我现在想要添加一个异步处理程序来处理发回的adhoc消息,这些消息不是命令/响应样式的消息。

我的主TCPConnection类中有一个eventhandler:

   private static void tcpReceive(Socket client)
    {
        try
        {
            // Create the state object.
            StateObject state = new StateObject {workSocket = client};

            // Begin receiving the data from the remote device.
            client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                new AsyncCallback(receiveCallback), state);
        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
    }

    private static void receiveCallback(IAsyncResult ar)
    {
        try
        {
            StateObject state = (StateObject)ar.AsyncState;
            Socket client = state.workSocket;

            // Read data from the remote device.
            int bytesRead = client.EndReceive(ar);

            if (bytesRead <= 0) return; // No data...

            // Console.WriteLine("Ascii {0}", Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
            Console.WriteLine("Raw: {0}", BitConverter.ToString(state.buffer, 0, bytesRead));

            processMessage(new Response {Data = state.buffer,BytesLength = bytesRead} );

            client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(receiveCallback), state);

        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
    }

    private static void processMessage(Response resp)
    {
       // Do something with the message here.. 
    }

但是我想从处理代码中抽象IP东西并将processMessage移回我使用该接口的类中。(我知道我没有解释这个......所以让我重新尝试)

在我的“class TcpConnection:IConnection”

中设置事件处理程序

启用构造函数的AlarmPanel类的事件处理:

public AlarmPanel(IConnection connection, int Password)
    {
        _connection = connection;
        _Password = Password;
    }

使用该接口(IConnection),并且可以说使用来自alarmPanel类的ProcessMessage方法,这样我就可以调用相同的方法来实现串行事件处理的工作..

1 个答案:

答案 0 :(得分:1)

听起来您想要在IConnection可以订阅的界面AlarmPanel上注册一个事件。通过这种方式,您可以让IConnection实现处理用于检索邮件的逻辑,但让AlarmPanel使用收到的邮件执行所需的操作。

public class AlarmPanel
{
    public AlarmPanel(IConnection connection, int Password)
    {
        _connection = connection;
        _Password = Password;
        // Bind event.
        _connection.MessageReceived += ProcessMessage;
    }

    private void ProcessMessage(object sender, MessageEventArgs e)
    {
        // Do your central processing here with e.Message.
    }
}

public interface IConnection
{
    event Action<object, MessageEventArgs> MessageRecieved;
}

public class TcpConnection : IConnection
{
    // Other code.

    private static void processMessage(Response resp)
    {
       // Do something with the message here..
       var eventArgs = new MessageEventArgs
       {
           Message = response
       };
       OnMessageReceived(eventArgs);
    }

    protected virtual void OnMessageReceived(MessageEventArgs e)
    {
        // Call subscribers.
        var handler = MessageRecieved;
        if (handler != null) handler(this, e);
    }
    public event Action<object, MessageEventArgs> MessageRecieved;
}

// Class for passing Response back to AlarmPanel.
public class MessageEventArgs : System.EventArgs
{
    Response Message { get; set; } // Consider using an interface for Response.
}