简体   繁体   English

如何正确使用NetMq Poller接收数据

[英]How to correctly use NetMq Poller for Receiving data

I have been given the task to create a interface where I receive data through socket from the sender, for this purpose I am using NetMQ PushSocket for the sender side and then I receive the data at client side sung PullSocket and I have to update the UI (WPF app) when data is received so I receive data using poller in ReceiveReady event of the PullSocket when I do this in a seperate service class and call that class in UI ViewModel the UI thread hangs, so I use Poller.Run in a task, now the problem is that when I stop the poller and then restart it again it doesn't call the ReceiveReady event 我已经被赋予了创建一个接口的任务,我通过套接字从发送方接收数据,为此我使用NetMQ PushSocket作为发送方,然后我在客户端接收数据sung PullSocket,我必须更新UI (WPF应用程序)当收到数据时所以我在PullSocket的ReceiveReady事件中使用poller接收数据,当我在单独的服务类中执行此操作并在UI ViewModel中调用UI线程挂起的类时,所以我在任务中使用Poller.Run ,现在问题是,当我停止轮询然后再次重新启动它时,它不会调用ReceiveReady事件

Here is the ReceiverService for receiving the data. 这是用于接收数据的ReceiverService。

public class ReceiverService
{
    string msg;
    string _address;
    int _port;
    PullSocket receiver;
    NetMQPoller poller;
    private MapViewModel ViewModel { get; set; }
    public ReceiverService(MapViewModel mapViewModel, int port = 5555)
    {
        _address = GetComputerLanIP();
        _port = port;
        receiver = new PullSocket($"tcp://{_address}:{_port}");
        receiver.Options.Linger = TimeSpan.Zero;             
        this.ViewModel = mapViewModel;
        poller = new NetMQPoller { receiver };
        receiver.ReceiveReady += receiver_ReceiveReady;
    }
    public void Start()
    {
        receiver.Connect($"tcp://{_address}:{_port}");
        poller.Run();
    }
    public void Stop()
    {
        receiver.Disconnect($"tcp://{_address}:{_port}");
        poller.Stop();
    }

    private void receiver_ReceiveReady(object sender, NetMQSocketEventArgs e)
    {
        // receive won't block as a message is ready
        msg = e.Socket.ReceiveFrameString();
        // send a response
        if (!string.IsNullOrEmpty(msg))
        {
            try
            {
              //Updaing the ViewModel here
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.Message);
            }
        }
    }
    private string GetComputerLanIP()
    {
        string strHostName = Dns.GetHostName();
        IPHostEntry ipEntry = Dns.GetHostEntry(strHostName);

        foreach (var ipAddress in ipEntry.AddressList)
        {
            if (ipAddress.AddressFamily == AddressFamily.InterNetwork)
            {
                return ipAddress.ToString();
            }
        }
        return "";
    }
    private string GetValueFromMessage(string identifier)
    {
        msg.Replace("{", "");
        msg.Replace("}", "");
        identifier = /*" " + */identifier + " = ";
        try
        {
            int index = msg.IndexOf(identifier) + identifier.Length;

            if (index != -1)
            {
                int index2 = msg.IndexOf(";", index);
                if (index2 == -1)
                {
                    index2 = msg.Length;
                }
                return msg.Substring(index, index2 - index);
            }
        }
        catch (IndexOutOfRangeException ex)
        {
            return null;
        }
        return null;
    }
}

and in my ViewModel I have set commands for these 在我的ViewModel中,我为这些设置了命令

private void StartReceiver()
    {
     Task.Run(() => ReceiverService.Start());           
    }
private void StopReceiver()
    {           
     Task.Run(() => ReceiverService.Stop());                         
    }

What am I doing wrong? 我究竟做错了什么? I am new to NetMQ and WPF. 我是NetMQ和WPF的新手。 TIA TIA

  1. at first it would be good to make a task inside ReceiverService, kind of an ActorModel, because in the end if You would like to reuse it anywhere You need to remember that You should creat a Task first. 首先,最好在ReceiverService中创建一个任务,一种ActorModel,因为最后如果你想在任何地方重用它你需要记住你应该首先创建一个任务。
  2. always it would be good to have socket in using statement, because You should always close socket if You are not using it 总是最好在using语句中使用socket,因为如果你不使用它,你应该总是关闭socket
 public async Task StartAsync()        {
     await Task.Run(() => ThreadBody())
 }
 public void Stop()
 {
     _poller.Stop();
 }
     private void ThreadBody()
 {
     using (PullSocket receiverSocket = new PullSocket())
     using (_poller = new NetMQPoller())
     {
         receiverSocket.Connect($"tcp://{_address}:{_port}");
         receiverSocket.ReceiveReady += receiver_ReceiveReady;
         _poller.Add(receiverSocket);
         _poller.Run();
     }
 }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 你是否需要在netMQ中使用inproc来保留一个线程来接收消息,还是有更好的方法? - Do you need to use inproc in netMQ to keep one thread for receiving messages or is there a better way? 当我尝试处理轮询器时,NetMQ 卡住了(请求-回复模式) - NetMQ gets stuck when I try to dispose the Poller (Request-Reply pattern) 使用StreamSocket正确接收数据挂起 - Correctly receiving data using StreamSocket hangs 使用 NetMQ 在 C# 应用程序中接收数据 - Using NetMQ to receive data in a C# application 如何识别NetMQ中传入连接的物理地址? - How to identify the physical address of incoming connections in NetMQ? 如何关闭客户端连接并返回 NETMQ 中的调用? - how to close the Client Connection and return the Call in NETMQ? 如何使用ZeroMQ解析'NetMQ.AddressAlreadyInUseException' - How to resolve 'NetMQ.AddressAlreadyInUseException' using ZeroMQ 为什么我的DeflateStream无法通过TCP正确接收数据? - Why is my DeflateStream not receiving data correctly over TCP? 为了避免在每个帧/消息上创建新的字节数组,在自定义缓冲区中接收的NetMQ API是什么? - What is the NetMQ API for receiving in a custom buffer in order to avoid creating a new byte array on each frame/message? 如何使用NetMQ从服务器向客户端发送ACK消息 - How to send ACK message to client from server using NetMQ
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM