Example #1
0
        void IShimHandler.Run(PairSocket shim)
        {
            _poller = new NetMQPoller();

            // Listen to actor dispose
            _ = Observable.FromEventPattern <NetMQSocketEventArgs>(e => shim.ReceiveReady += e, e => shim.ReceiveReady -= e)
                .Select(e => e.EventArgs)
                .ObserveOn(Scheduler.CurrentThread)
                .Subscribe(OnShimReady);

            _poller.Add(shim);

            _subscriberSocket = new SubscriberSocket();
            _subscriberSocket.Options.ReceiveHighWatermark = 1000;
            _subscriberSocket.Options.Linger               = TimeSpan.FromSeconds(2);
            _subscriberSocket.Options.TcpKeepalive         = true;
            _subscriberSocket.Options.TcpKeepaliveIdle     = TimeSpan.FromSeconds(5);
            _subscriberSocket.Options.TcpKeepaliveInterval = TimeSpan.FromSeconds(1);

#if MONITOR
            var monitor = new NetMQMonitor(_subscriberSocket, "inproc://#monitor", SocketEvents.All);
            _ =
                Observable.FromEventPattern <NetMQMonitorSocketEventArgs>(monitor, "Connected")
                .Select(e => new { Event = "Connected", e })
                .Merge(Observable.FromEventPattern <NetMQMonitorSocketEventArgs>(monitor, nameof(monitor.Listening)).Select(e => new { Event = "Listening", e }))
                .Merge(Observable.FromEventPattern <NetMQMonitorSocketEventArgs>(monitor, nameof(monitor.Accepted)).Select(e => new { Event = "Accepted", e }))
                .Merge(Observable.FromEventPattern <NetMQMonitorSocketEventArgs>(monitor, nameof(monitor.Closed)).Select(e => new { Event = "Closed", e }))
                .Merge(Observable.FromEventPattern <NetMQMonitorSocketEventArgs>(monitor, nameof(monitor.Disconnected)).Select(e => new { Event = "Disconnected", e }))
                .Do(e => _logger.Info("Monitor socket: {0}, {1}", e.Event, e.e.EventArgs.Address))
                .Subscribe();
            _ = Observable.FromEventPattern <NetMQMonitorErrorEventArgs>(monitor, nameof(monitor.AcceptFailed))
                .Merge(Observable.FromEventPattern <NetMQMonitorErrorEventArgs>(monitor, nameof(monitor.ConnectDelayed)))
                .Merge(Observable.FromEventPattern <NetMQMonitorErrorEventArgs>(monitor, nameof(monitor.CloseFailed)))
                .Merge(Observable.FromEventPattern <NetMQMonitorErrorEventArgs>(monitor, nameof(monitor.BindFailed)))
                .Do(e => _logger.Error("Monitor error socket: {0}, {1}", e.EventArgs.ErrorCode, e.EventArgs.Address))
                .Subscribe();
            _ = Observable.FromEventPattern <NetMQMonitorIntervalEventArgs>(monitor, nameof(monitor.ConnectRetried))
                .Do(e => _logger.Info("Monitor retry socket: {0}, {1}", e.EventArgs.Interval, e.EventArgs.Address))
                .Subscribe();
            monitor.AttachToPoller(_poller);
#endif

            _ = Observable.FromEventPattern <NetMQSocketEventArgs>(
                e => _subscriberSocket.ReceiveReady += e, e => _subscriberSocket.ReceiveReady -= e)
                .Select(e => e.EventArgs)
                .ObserveOn(Scheduler.CurrentThread)
                .Subscribe(ReceivedMessage);

            _poller.Add(_subscriberSocket);

            _subscriberSocket.Connect($"tcp://{_address}:{_port + 1}");

            shim.SignalOK();

            try
            {
                _poller.Run();
            }
            catch (Exception ex)
            {
                _logger.Fatal(ex, "Fatal error on NetMQ poller.");
            }

            // Cleanup stuff after stopping
            _poller.Remove(_subscriberSocket);
            _poller.Remove(shim);
#if MONITOR
            if (monitor != null)
            {
                monitor.DetachFromPoller();
                monitor.Dispose();
                monitor = null;
            }
#endif
            _poller.Dispose();
        }
Example #2
0
        void IShimHandler.Run(PairSocket shim)
        {
            _poller = new NetMQPoller();

            // Listen to actor dispose
            _ = Observable.FromEventPattern <NetMQSocketEventArgs>(e => shim.ReceiveReady += e, e => shim.ReceiveReady -= e)
                .Select(e => e.EventArgs)
                .ObserveOn(Scheduler.CurrentThread)
                .Subscribe(OnShimReady);

            _poller.Add(shim);

            _publisherSocket = new PublisherSocket();
            _responseSocket  = new RouterSocket();
#if MONITOR
            var monitor1 = new NetMQMonitor(_publisherSocket, "inproc://#monitor1", SocketEvents.All);
            _ = Observable.FromEventPattern <NetMQMonitorSocketEventArgs>(monitor1, "Connected")
                .Select(e => new { Event = "Connected", e })
                .Merge(Observable.FromEventPattern <NetMQMonitorSocketEventArgs>(monitor1, nameof(monitor1.Listening)).Select(e => new { Event = "Listening", e }))
                .Merge(Observable.FromEventPattern <NetMQMonitorSocketEventArgs>(monitor1, nameof(monitor1.Accepted)).Select(e => new { Event = "Accepted", e }))
                .Merge(Observable.FromEventPattern <NetMQMonitorSocketEventArgs>(monitor1, nameof(monitor1.Closed)).Select(e => new { Event = "Closed", e }))
                .Merge(Observable.FromEventPattern <NetMQMonitorSocketEventArgs>(monitor1, nameof(monitor1.Disconnected)).Select(e => new { Event = "Disconnected", e }))
                .Do(e => _logger.Info("Monitor socket: {0}, {1}", e.Event, e.e.EventArgs.Address))
                .Subscribe();
            _ = Observable.FromEventPattern <NetMQMonitorErrorEventArgs>(monitor1, nameof(monitor1.AcceptFailed))
                .Merge(Observable.FromEventPattern <NetMQMonitorErrorEventArgs>(monitor1, nameof(monitor1.ConnectDelayed)))
                .Merge(Observable.FromEventPattern <NetMQMonitorErrorEventArgs>(monitor1, nameof(monitor1.CloseFailed)))
                .Merge(Observable.FromEventPattern <NetMQMonitorErrorEventArgs>(monitor1, nameof(monitor1.BindFailed)))
                .Do(e => _logger.Error("Monitor error socket: {0}, {1}", e.EventArgs.ErrorCode, e.EventArgs.Address))
                .Subscribe();
            _ = Observable.FromEventPattern <NetMQMonitorIntervalEventArgs>(monitor1, nameof(monitor1.ConnectRetried))
                .Do(e => _logger.Info("Monitor retry socket: {0}, {1}", e.EventArgs.Interval, e.EventArgs.Address))
                .Subscribe();
            monitor1.AttachToPoller(_poller);

            var monitor2 = new NetMQMonitor(_responseSocket, "inproc://#monitor2", SocketEvents.All);
            _ = Observable.FromEventPattern <NetMQMonitorSocketEventArgs>(monitor2, "Connected")
                .Select(e => new { Event = "Connected", e })
                .Merge(Observable.FromEventPattern <NetMQMonitorSocketEventArgs>(monitor2, nameof(monitor2.Listening)).Select(e => new { Event = "Listening", e }))
                .Merge(Observable.FromEventPattern <NetMQMonitorSocketEventArgs>(monitor2, nameof(monitor2.Accepted)).Select(e => new { Event = "Accepted", e }))
                .Merge(Observable.FromEventPattern <NetMQMonitorSocketEventArgs>(monitor2, nameof(monitor2.Closed)).Select(e => new { Event = "Closed", e }))
                .Merge(Observable.FromEventPattern <NetMQMonitorSocketEventArgs>(monitor2, nameof(monitor2.Disconnected)).Select(e => new { Event = "Disconnected", e }))
                .Do(e => _logger.Info("Monitor socket: {0}, {1}", e.Event, e.e.EventArgs.Address))
                .Subscribe();
            _ = Observable.FromEventPattern <NetMQMonitorErrorEventArgs>(monitor2, nameof(monitor2.AcceptFailed))
                .Merge(Observable.FromEventPattern <NetMQMonitorErrorEventArgs>(monitor2, nameof(monitor2.ConnectDelayed)))
                .Merge(Observable.FromEventPattern <NetMQMonitorErrorEventArgs>(monitor2, nameof(monitor2.CloseFailed)))
                .Merge(Observable.FromEventPattern <NetMQMonitorErrorEventArgs>(monitor2, nameof(monitor2.BindFailed)))
                .Do(e => _logger.Error("Monitor error socket: {0}, {1}", e.EventArgs.ErrorCode, e.EventArgs.Address))
                .Subscribe();
            _ = Observable.FromEventPattern <NetMQMonitorIntervalEventArgs>(monitor2, nameof(monitor2.ConnectRetried))
                .Do(e => _logger.Info("Monitor retry socket: {0}, {1}", e.EventArgs.Interval, e.EventArgs.Address))
                .Subscribe();
            monitor2.AttachToPoller(_poller);
#endif

            // To avoid crashes if the queue builds up too fast.
            _publisherSocket.Options.SendHighWatermark    = 1000;
            _publisherSocket.Options.TcpKeepalive         = true;
            _publisherSocket.Options.TcpKeepaliveIdle     = TimeSpan.FromSeconds(5);
            _publisherSocket.Options.TcpKeepaliveInterval = TimeSpan.FromSeconds(1);
            // Number of network hops to jump, default is 1, which means local network.
            //_publisherSocket.Options.MulticastHops = 100;
            _publisherSocket.Bind($"tcp://*:{_port + 1}");
            _poller.Add(_publisherSocket);

            _responseSocket.Bind($"tcp://*:{_port}");
            _ = Observable.FromEventPattern <NetMQSocketEventArgs>(
                e => _responseSocket.ReceiveReady += e, e => _responseSocket.ReceiveReady -= e)
                .Select(e => e.EventArgs)
                .ObserveOn(Scheduler.CurrentThread)
                .Subscribe(e =>
            {
                try
                {
                    var msg = e.Socket.ReceiveMultipartMessage();
                    // Ignore messages that have less than 3 frames or no empty second frame.
                    var address = msg.First();
                    var data    = msg.Last().ConvertToString();
                    var nyxMsg  = new NyxMessage().FromDefault(data);
                    _messageSubject.OnNext(new Tuple <byte[], INyxMessage>(address.ToByteArray(), nyxMsg));
                }
                catch (Exception ex)
                {
                    _messageSubject.OnError(ex);
                }
            });

            _poller.Add(_responseSocket);

            var heartbeatTimer = new NetMQTimer(TimeSpan.FromSeconds(2));
            _ = Observable.FromEventPattern <NetMQTimerEventArgs>(e => heartbeatTimer.Elapsed += e, e => heartbeatTimer.Elapsed -= e)
                .Select(e => e.EventArgs)
                .Subscribe(OnTimeoutElapsed);
            _poller.Add(heartbeatTimer);

            heartbeatTimer.Reset();
            shim.SignalOK();

            _poller.Run();

#if MONITOR
            if (monitor1 != null)
            {
                monitor1.DetachFromPoller();
                monitor2.DetachFromPoller();
            }
#endif
            _poller.Remove(_responseSocket);
            _poller.Remove(_publisherSocket);
            _poller.Remove(heartbeatTimer);
            _poller.Remove(shim);
            _poller.Dispose();
        }