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(); }
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(); }