private PublisherSocket GetNewPublisherSocket(string addressZeroMq) { PublisherSocket publisherSocket; { _loggerDelegate?.Invoke(string.Format("Publisher socket binding to: {0}\n", addressZeroMq)); publisherSocket = new PublisherSocket(); // Corner case: wait until publisher socket is ready (see code below that waits for // "_publisherReadySignal"). NetMQMonitor monitor; { // Must ensure that we have a unique monitor name for every instance of this class. string endPoint = string.Format("inproc://#SubjectNetMQ#Publisher#{0}#{1}", addressZeroMq, Guid.NewGuid().ToString()); monitor = new NetMQMonitor(publisherSocket, endPoint, SocketEvents.Accepted | SocketEvents.Listening ); monitor.Accepted += Publisher_Event_Accepted; monitor.Listening += Publisher_Event_Listening; monitor.StartAsync(); } publisherSocket.Options.SendHighWatermark = this.HighwaterMark; try { publisherSocket.Bind(addressZeroMq); } catch (NetMQException ex) { // This is usually because the address is in use. throw new Exception(string.Format("Error E56874. Cannot bind publisher to '{0}'. 95% probability that this is caused by trying to bind a publisher to a port already in use by another process. To fix, choose a unique publisher port for this process. For more on this error, see 'Readme.md' (or the GitHub homepage for NetMQ.ReactiveExtensions).", addressZeroMq), ex); } // Corner case: wait until publisher socket is ready (see code below that sets "_publisherReadySignal"). { Stopwatch sw = Stopwatch.StartNew(); _publisherReadySignal.WaitOne(TimeSpan.FromMilliseconds(3000)); _loggerDelegate?.Invoke(string.Format("Publisher: Waited {0} ms for binding.\n", sw.ElapsedMilliseconds)); } { monitor.Accepted -= Publisher_Event_Accepted; monitor.Listening -= Publisher_Event_Listening; // Current issue with NegMQ: Cannot stop or dispose monitor, or else it stops the parent socket. //monitor.Stop(); //monitor.Dispose(); } } // Otherwise, the first item we publish may get missed by the subscriber. 500 milliseconds consistently works // locally, but occasionally fails on the AppVeyor build server. 650 milliseconds is optimal. using (EventWaitHandle wait = new ManualResetEvent(false)) { // Cannot use Thread.Sleep() here, as this is incompatible with .NET Core 1.0, Windows 8.0, 8.1, and 10. wait.WaitOne(TimeSpan.FromMilliseconds(650)); } return(publisherSocket); }
public void StartAsync() { using (var rep = new ResponseSocket()) using (var monitor = new NetMQMonitor(rep, "inproc://foo", SocketEvents.Closed)) { var task = monitor.StartAsync(); Thread.Sleep(200); Assert.AreEqual(TaskStatus.Running, task.Status); monitor.Stop(); Assert.True(task.Wait(TimeSpan.FromMilliseconds(1000))); } }
private void InitializePublisherOnFirstUse() { if (m_initializePublisherDone == false) // Double checked locking. { lock (m_initializePublisherLock) { if (m_initializePublisherDone == false) { Console.WriteLine("Publisher socket binding to: {0}", ZeroMqAddress); m_publisherSocket = new PublisherSocket(); // Corner case: wait until publisher socket is ready (see code below that waits for // "_publisherReadySignal"). NetMQMonitor monitor; { // Must ensure that we have a unique monitor name for every instance of this class. string endPoint = string.Format("inproc://#SubjectNetMQ#Publisher#{0}#{1}", this.QueueName, this.ZeroMqAddress); monitor = new NetMQMonitor(m_publisherSocket, endPoint, SocketEvents.Accepted | SocketEvents.Listening ); monitor.Accepted += Publisher_Event_Accepted; monitor.Listening += Publisher_Event_Listening; monitor.StartAsync(); } m_publisherSocket.Options.SendHighWatermark = 2000 * 1000; m_publisherSocket.Bind(this.ZeroMqAddress); // Corner case: wait until publisher socket is ready (see code below that sets // "_publisherReadySignal"). { Stopwatch sw = Stopwatch.StartNew(); m_publisherReadySignal.WaitOne(TimeSpan.FromMilliseconds(3000)); Console.Write("Publisher: Waited {0} ms for binding.\n", sw.ElapsedMilliseconds); } { monitor.Accepted -= Publisher_Event_Accepted; monitor.Listening -= Publisher_Event_Listening; // Current issue with NegMQ: Cannot stop or dispose monitor, or else it stops the parent socket. //monitor.Stop(); //monitor.Dispose(); } m_initializePublisherDone = true; } } // lock Thread.Sleep(500); // Otherwise, the first item we publish may get missed by the subscriber. } }
private static async Task CreatePushSocket() { var poller = new NetMQPoller(); push = new PushSocket(); push.BindRandomPort("tcp://127.0.0.1"); NetMQMonitor monitor = new NetMQMonitor(push, "inproc://req.inproc", SocketEvents.All); monitor.Connected += Monitor_Connected; monitor.EventReceived += Monitor_EventReceived; //monitor.AttachToPoller(poller); queue.ReceiveReady += Queue_ReceiveReady;; push.Connect(address); poller.Add(push); poller.Add(queue); poller.RunAsync(); await monitor.StartAsync(); }
private static void CreatePullSocket() { try { var poller = new NetMQPoller(); NetMQMonitor monitor = new NetMQMonitor(pull, "inproc://req.inproc", SocketEvents.All); monitor.Accepted += Monitor_Accepted; monitor.EventReceived += Monitor_EventReceived; pull.ReceiveReady += Pull_ReceiveReady1; pull.Bind(address); //monitor.AttachToPoller(poller); poller.Add(pull); poller.RunAsync(); monitor.StartAsync(); } catch (Exception ex) { } }
public bool TryConnectAndMonitorSocket(NetMQSocket socket, string address, NetMQPoller poller = null, Action <IConnectionMonitor, bool> onConnectionStateChanged = null) { _onConnectionStateChanged = onConnectionStateChanged; _monitor = new NetMQMonitor(socket, $"inproc://monitor.socket/{Guid.NewGuid()}", SocketEvents.Connected | SocketEvents.Disconnected); _monitor.Connected += MonitorConnected; _monitor.Disconnected += MonitorDisconnected; if (poller == null) { _monitorTask = _monitor.StartAsync(); } else { _monitor.AttachToPoller(poller); } socket.Connect(address); return(WaitForConnection()); }
protected override void _SocketBuilder() { reportLog("Starting Router name " + Name, LogType.INFO, section); socket = new RouterSocket(); socket.Options.TcpKeepalive = true; socket.Options.TcpKeepaliveIdle = TimeSpan.FromMilliseconds(100); socket.Options.TcpKeepaliveInterval = TimeSpan.FromMilliseconds(100); local_port = socket.BindRandomPort("tcp://*"); monitor = new NetMQMonitor(socket, "inproc://router" + Net2.GetAddressIndex(), SocketEvents.All); monitor.Disconnected += Monitor_Disconnected; monitor.Accepted += Monitor_Connected; monitor.Timeout = TimeSpan.FromMilliseconds(100); task = monitor.StartAsync(); setState(Net2State.STARTED); start_time = GetTime().sec; reportLog("Router is ready on " + local_port, LogType.INFO, section); }
private void InitializeSubscriberOnFirstUse() { if (m_initializeSubscriberDone == false) // Double checked locking. { lock (m_subscribersLock) { if (m_initializeSubscriberDone == false) { Console.WriteLine("Subscriber socket connecting to: {0}", ZeroMqAddress); m_subscriberSocket = new SubscriberSocket(); // Corner case: wait until subscriber socket is ready (see code below that waits for // "_subscriberReadySignal"). NetMQMonitor monitor; { // Must ensure that we have a unique monitor name for every instance of this class. string endpoint = string.Format("inproc://#SubjectNetMQ#Subscriber#{0}#{1}", this.QueueName, this.ZeroMqAddress); monitor = new NetMQMonitor(m_subscriberSocket, endpoint, SocketEvents.ConnectRetried | SocketEvents.Connected); monitor.ConnectRetried += Subscriber_Event_ConnectRetried; monitor.Connected += Subscriber_Event_Connected; monitor.StartAsync(); } m_subscriberSocket.Options.ReceiveHighWatermark = 2000 * 1000; m_subscriberSocket.Connect(this.ZeroMqAddress); m_subscriberSocket.Subscribe(this.QueueName); if (m_cancellationTokenSource == null) { m_cancellationTokenSource = new CancellationTokenSource(); } ManualResetEvent threadReadySignal = new ManualResetEvent(false); m_thread = new Thread(() => { try { Console.Write("Thread initialized.\n"); threadReadySignal.Set(); while (m_cancellationTokenSource.IsCancellationRequested == false) { string messageTopicReceived = m_subscriberSocket.ReceiveFrameString(); if (messageTopicReceived != QueueName) { throw new Exception(string.Format("Error E65724. We should always subscribe on the queue name '{0}', instead we got '{1}'.", QueueName, messageTopicReceived)); } var type = m_subscriberSocket.ReceiveFrameString(); switch (type) { // Originated from "OnNext". case "N": T messageReceived = m_subscriberSocket.ReceiveFrameBytes().DeserializeProtoBuf <T>(); lock (m_subscribersLock) { m_subscribers.ForEach(o => o.OnNext(messageReceived)); } break; // Originated from "OnCompleted". case "C": lock (m_subscribersLock) { m_subscribers.ForEach(o => o.OnCompleted()); // We are done! We don't want to send any more messages to subscribers, and we // want to close the listening socket. m_cancellationTokenSource.Cancel(); } break; // Originated from "OnException". case "E": Exception exception; string exceptionAsString = "Uninitialized."; try { // Not used, but useful for cross-platform debugging: we can read the error straight off the wire. exceptionAsString = m_subscriberSocket.ReceiveFrameBytes().DeserializeProtoBuf <string>(); SerializableException exceptionWrapper = m_subscriberSocket.ReceiveFrameBytes().DeSerializeException(); exception = exceptionWrapper.InnerException; } catch (Exception ex) { // If we had trouble deserializing the exception (probably due to a // different version of .NET), then do the next best thing: (1) The // inner exception is the error we got when deserializing, and (2) the // main exception is the human-readable "exception.ToString()" that we // originally captured. exception = new Exception(exceptionAsString, ex); } lock (m_subscribersLock) { m_subscribers.ForEach(o => o.OnError(exception)); } break; // Originated from a "Ping" request. case "P": // Do nothing, this is a ping command used to wait until sockets are initialized properly. Console.Write("Received ping.\n"); break; default: throw new Exception(string.Format("Error E28734. Something is wrong - received '{0}' when we expected \"N\", \"C\" or \"E\" - are we out of sync?", type)); } } } catch (Exception ex) { Console.Write("Error E23844. Exception in threadName \"{0}\". Thread exiting. Exception: \"{1}\".\n", QueueName, ex.Message); lock (m_subscribersLock) { this.m_subscribers.ForEach((ob) => ob.OnError(ex)); } } finally { lock (m_subscribersLock) { m_subscribers.Clear(); } m_cancellationTokenSource.Dispose(); // Disconnect from the socket. m_subscriberSocket.Dispose(); } }) { Name = this.QueueName, IsBackground = true // Have to set it to background, or else it will not exit when the program exits. }; m_thread.Start(); // Wait for thread to properly spin up. threadReadySignal.WaitOne(TimeSpan.FromMilliseconds(3000)); // Corner case: wait until the publisher socket is ready (see code above that sets // "_subscriberReadySignal"). { Stopwatch sw = Stopwatch.StartNew(); m_subscriberReadySignal.WaitOne(TimeSpan.FromMilliseconds(3000)); Console.Write("Subscriber: Waited {0} ms for connection.\n", sw.ElapsedMilliseconds); monitor.ConnectRetried -= Subscriber_Event_ConnectRetried; monitor.Connected -= Subscriber_Event_Connected; // Issue with NetMQ - cannot .Stop or .Dispose, or else it will dispose of the parent socket. //monitor.Stop(); //monitor.Dispose(); } Console.Write("Subscriber: finished setup.\n"); m_initializeSubscriberDone = true; } } // lock Thread.Sleep(500); // Otherwise, the first item we subscribe to may get missed by the subscriber. } }
private PublisherSocket GetNewPublisherSocket(string addressZeroMq) { PublisherSocket publisherSocket; { _loggerDelegate?.Invoke(string.Format("Publisher socket binding to: {0}\n", addressZeroMq)); publisherSocket = new PublisherSocket(); // Corner case: wait until publisher socket is ready (see code below that waits for // "_publisherReadySignal"). NetMQMonitor monitor; { // Must ensure that we have a unique monitor name for every instance of this class. string endPoint = string.Format("inproc://#SubjectNetMQ#Publisher#{0}#{1}", addressZeroMq, Guid.NewGuid().ToString()); monitor = new NetMQMonitor(publisherSocket, endPoint, SocketEvents.Accepted | SocketEvents.Listening ); monitor.Accepted += Publisher_Event_Accepted; monitor.Listening += Publisher_Event_Listening; monitor.StartAsync(); } publisherSocket.Options.SendHighWatermark = this.HighwaterMark; try { publisherSocket.Bind(addressZeroMq); } catch (NetMQException ex) { // This is usually because the address is in use. throw new Exception(string.Format("Error E56874. Cannot bind publisher to '{0}'. 95% probability that this is caused by trying to bind a publisher to a port already in use by another process. To fix, choose a unique publisher port for this process. For more on this error, see 'Readme.md' (or the GitHub homepage for NetMQ.ReactiveExtensions).", addressZeroMq), ex); } // Corner case: wait until publisher socket is ready (see code below that sets "_publisherReadySignal"). { Stopwatch sw = Stopwatch.StartNew(); _publisherReadySignal.WaitOne(TimeSpan.FromMilliseconds(3000)); _loggerDelegate?.Invoke(string.Format("Publisher: Waited {0} ms for binding.\n", sw.ElapsedMilliseconds)); } { monitor.Accepted -= Publisher_Event_Accepted; monitor.Listening -= Publisher_Event_Listening; // Current issue with NegMQ: Cannot stop or dispose monitor, or else it stops the parent socket. //monitor.Stop(); //monitor.Dispose(); } } // Otherwise, the first item we publish may get missed by the subscriber. 500 milliseconds consistently works // locally, but occasionally fails on the AppVeyor build server. 650 milliseconds is optimal. using (EventWaitHandle wait = new ManualResetEvent(false)) { // Cannot use Thread.Sleep() here, as this is incompatible with .NET Core 1.0, Windows 8.0, 8.1, and 10. wait.WaitOne(TimeSpan.FromMilliseconds(650)); } return publisherSocket; }