examples of zeromq pub/sub with C# winform

前端 未结 1 1511
盖世英雄少女心
盖世英雄少女心 2021-01-02 08:27

I\'m trying to create a C# Winform application that uses ZeroMQ (clrzmq .net bindings (x86) via nuget) in a pub/sub model.

After much searching, I can only find stan

相关标签:
1条回答
  • 2021-01-02 08:52

    I am assuming you are using the clrzmq ZeroMq wrapper in your project. As far as I know it is not possible to receive message non-blocking in a simple loop using clrzmq, it will block either indefinitely, for a specific amount of time (by supplying a timeout to the receive method) or until you receive a message.

    However, it is fairly trivial to set up a thread to poll the socket periodically and push incoming messages to onto a Queue. You may then use for example a simple WinForms Timer to periodically dequeue any pending messages from that (shared) Queue. Here is a working example of a threaded subscriber:

    public class ZeroMqSubscriber
    {
        private readonly ZmqContext _zmqContext;
        private readonly ZmqSocket _zmqSocket;
        private readonly Thread _workerThread;
        private readonly ManualResetEvent _stopEvent = new ManualResetEvent(false);
        private readonly object _locker = new object();
        private readonly Queue<string> _queue = new Queue<string>();
    
        public ZeroMqSubscriber(string endPoint)
        {
            _zmqContext = ZmqContext.Create();
            _zmqSocket = _zmqContext.CreateSocket(SocketType.SUB);
            _zmqSocket.Connect(endPoint);
            _zmqSocket.SubscribeAll();
    
            _workerThread = new Thread(ReceiveData);
            _workerThread.Start();
        }
    
        public string[] GetMessages()
        {
            lock (_locker)
            {
                var messages = _queue.ToArray();
                _queue.Clear();
                return messages;
            }
        }
    
        public void Stop()
        {
            _stopEvent.Set();
            _workerThread.Join();
        }
    
        private void ReceiveData()
        {
             try
             {
                 while (!_stopEvent.WaitOne(0))
                 {
                     var message = _zmqSocket.Receive(Encoding.UTF8, 
                                   new TimeSpan(0, 0, 0, 1));
                     if (string.IsNullOrEmpty(message))
                         continue;
    
                     lock (_locker)
                         _queue.Enqueue(message);
                 }
             }
             finally
             {
                 _zmqSocket.Dispose();
                 _zmqContext.Dispose();
             }
        }
    }
    

    From the Form you simply poll the Queue periodically (this example uses a Forms Timer and simply appends the message data to a Textbox):

    private readonly ZeroMqSubscriber _zeroMqSubscriber = 
            new ZeroMqSubscriber("tcp://127.0.0.1:5000");
    
    void ReceiveTimerTick(object sender, EventArgs e)
    {
        var messages = _zeroMqSubscriber.GetMessages();
        foreach (var message in messages)
            _textbox.AppendText(message + Environment.NewLine);
    }
    
    0 讨论(0)
提交回复
热议问题