예제 #1
0
            public void Run(PairSocket shim)
            {
                _poller = new NetMQPoller();

                _ = Observable.FromEventPattern <NetMQSocketEventArgs>(e => shim.ReceiveReady += e, e => shim.ReceiveReady -= e)
                    .Select(e => e.EventArgs)
                    .Subscribe(OnShimReady);

                _poller.Add(shim);

                // Timer
                var timeoutTimer = new NetMQTimer(TimeSpan.FromSeconds(5));

                _ = Observable.FromEventPattern <NetMQTimerEventArgs>(e => timeoutTimer.Elapsed += e, e => timeoutTimer.Elapsed -= e)
                    .Select(e => e.EventArgs)
                    .ObserveOn(ThreadPoolScheduler.Instance)
                    .Subscribe(OnTimeoutElapsed);
                _poller.Add(timeoutTimer);

                _subscriberSocket = new SubscriberSocket();
                _subscriberSocket.Options.Linger = TimeSpan.Zero;
                _subscriberSocket.Subscribe(CoreHearbeatTopic);
                _subscriberSocket.Connect($"tcp://{_address}:{_port + 1}");
                _subject.OnNext(ConnectionStatus.Connecting);

                _ = Observable.FromEventPattern <NetMQSocketEventArgs>(e => _subscriberSocket.ReceiveReady += e, e => _subscriberSocket.ReceiveReady -= e)
                    .Select(e => e.EventArgs)
                    .Where(e => e.Socket.ReceiveFrameString() == CoreHearbeatTopic)
                    .ObserveOn(ThreadPoolScheduler.Instance)
                    .Subscribe(e =>
                {
                    timeoutTimer.Reset();
                    Thread.MemoryBarrier();
                    var status = _borgConnected
                            ? (ConnectionStatus.Online | ConnectionStatus.Connected)
                            : (ConnectionStatus.Online | ConnectionStatus.Disconnected);
                    _subject.OnNext(status);
                });

                _poller.Add(_subscriberSocket);
                timeoutTimer.Reset();
                shim.SignalOK();

                _poller.Run();

                // Cleanup stuff after stopping
                _poller.Remove(_subscriberSocket);
                _poller.Remove(timeoutTimer);
                _poller.Remove(shim);
                _poller.Dispose();
            }
예제 #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();
        }