/// <summary> /// Create a new instance of a Proxy (NetMQ.Proxy) /// with the given sockets to serve as a front-end, a back-end, and a control socket. /// </summary> /// <param name="frontend">the socket that messages will be forwarded from</param> /// <param name="backend">the socket that messages will be forwarded to</param> /// <param name="controlIn"> /// this socket will have incoming messages also sent to it - you can set this to null if not /// needed /// </param> /// <param name="controlOut"> /// this socket will have outgoing messages also sent to it - you can set this to null if not /// needed /// </param> /// <param name="poller">an optional external poller to use within this proxy</param> public Proxy([NotNull] NetMQSocket frontend, [NotNull] NetMQSocket backend, [CanBeNull] NetMQSocket controlIn, [CanBeNull] NetMQSocket controlOut, [CanBeNull] INetMQPoller poller = null) { if (poller != null) { this.m_externalPoller = true; this.m_poller = poller; } this.m_frontend = frontend; this.m_backend = backend; this.m_controlIn = controlIn; this.m_controlOut = controlOut ?? controlIn; }
/// <summary> /// Create a new instance of a Proxy (NetMQ.Proxy) /// with the given sockets to serve as a front-end, a back-end, and a control socket. /// </summary> /// <param name="frontend">the socket that messages will be forwarded from</param> /// <param name="backend">the socket that messages will be forwarded to</param> /// <param name="control">this socket will have messages also sent to it - you can set this to null if not needed</param> /// <param name="poller">an optional external poller to use within this proxy</param> /// <exception cref="InvalidOperationException"> /// <paramref name="poller" /> is not <c>null</c> and either /// <paramref name="frontend" /> or <paramref name="backend" /> are not contained within it. /// </exception> public Proxy([NotNull] NetMQSocket frontend, [NotNull] NetMQSocket backend, [CanBeNull] NetMQSocket control = null, [CanBeNull] INetMQPoller poller = null) : this(frontend, backend, control, null, poller) { }
/// <summary> /// Runs the poller on the caller's thread. Only returns when <see cref="Stop" /> or <see cref="StopAsync" /> are /// called from another thread. /// </summary> public void Run() { this.CheckDisposed(); if (this.IsRunning) { throw new InvalidOperationException("NetMQPoller is already running"); } #if NET35 m_pollerThread = Thread.CurrentThread; #else SynchronizationContext oldSynchronisationContext = SynchronizationContext.Current; SynchronizationContext.SetSynchronizationContext(new NetMQSynchronizationContext(this)); this.m_isSchedulerThread.Value = true; #endif this.m_stopSignaler.Reset(); this.m_switch.SwitchOn(); try { // Recalculate all timers now foreach (NetMQTimer timer in this.m_timers) { if (timer.Enable) { timer.When = Clock.NowMs() + timer.Interval; } } // Run until stop is requested while (!this.m_stopSignaler.IsStopRequested) { if (this.m_isPollSetDirty) { this.RebuildPollset(); } long pollStart = Clock.NowMs(); // Set tickless to "infinity" long tickless = pollStart + int.MaxValue; // Find the When-value of the earliest timer.. foreach (NetMQTimer timer in this.m_timers) { // If it is enabled but no When is set yet, if (timer.When == -1 && timer.Enable) { // Set this timer's When to now plus it's Interval. timer.When = pollStart + timer.Interval; } // If it has a When and that is earlier than the earliest found thus far, if (timer.When != -1 && tickless > timer.When) { // save that value. tickless = timer.When; } } // Compute a timeout value - how many milliseconds from now that the earliest-timer will expire. long timeout = tickless - pollStart; // Use zero to indicate it has already expired. if (timeout < 0) { timeout = 0; } bool isItemAvailable = false; if (this.m_pollSet.Length != 0) { isItemAvailable = this.m_netMqSelector.Select(this.m_pollSet, this.m_pollSet.Length, timeout); } else if (timeout > 0) { //TODO: Do we really want to simply sleep and return, doing nothing during this interval? //TODO: Should a large value be passed it will sleep for a month literally. // Solution should be different, but sleep is more natural here than in selector (timers are not selector concern). Debug.Assert(timeout <= int.MaxValue); Thread.Sleep((int)timeout); } // Get the expected end time in case we time out. This looks redundant but, unfortunately, // it happens that Poll takes slightly less than the requested time and 'Clock.NowMs() >= timer.When' // may not true, even if it is supposed to be. In other words, even when Poll times out, it happens // that 'Clock.NowMs() < pollStart + timeout' long expectedPollEnd = !isItemAvailable ? pollStart + timeout : -1L; // that way we make sure we can continue the loop if new timers are added. // timers cannot be removed foreach (NetMQTimer timer in this.m_timers) { if ((Clock.NowMs() >= timer.When || expectedPollEnd >= timer.When) && timer.When != -1) { timer.InvokeElapsed(this); if (timer.Enable) { timer.When = Clock.NowMs() + timer.Interval; } } } for (int i = 0; i < this.m_pollSet.Length; i++) { NetMQSelector.Item item = this.m_pollSet[i]; if (item.Socket != null) { NetMQSocket socket = this.m_pollact[i]; if (item.ResultEvent.HasError()) { if (++socket.Errors > 1) { this.Remove(socket); item.ResultEvent = PollEvents.None; } } else { socket.Errors = 0; } if (item.ResultEvent != PollEvents.None) { socket.InvokeEvents(this, item.ResultEvent); } } else if (item.ResultEvent.HasError() || item.ResultEvent.HasIn()) { Action <Socket> action; if (this.m_pollinSockets.TryGetValue(item.FileDescriptor, out action)) { action(item.FileDescriptor); } } } } } finally { try { foreach (NetMQSocket socket in this.m_sockets.ToList()) { this.Remove(socket); } } finally { #if NET35 m_pollerThread = null; #else this.m_isSchedulerThread.Value = false; SynchronizationContext.SetSynchronizationContext(oldSynchronisationContext); #endif this.m_switch.SwitchOff(); } } }
/// <summary> /// Create a new NetMQSocketEventArgs referencing the given socket. /// </summary> /// <param name="socket">the NetMQSocket that this is in reference to</param> public NetMQSocketEventArgs([NotNull] NetMQSocket socket) { this.Socket = socket; }
/// <summary> /// Create NetMQProactor and start dedicate thread to handle incoming messages. /// </summary> /// <param name="receiveSocket">Socket to handle messages from</param> /// <param name="handler">Handler to handle incoming messages</param> public NetMQProactor(NetMQSocket receiveSocket, Action <NetMQSocket, NetMQMessage> handler) { this.m_receiveSocket = receiveSocket; this.m_handler = handler; this.m_actor = NetMQActor.Create(this.Run); }
public Item(NetMQSocket socket, PollEvents @event) { this.Socket = socket; this.Event = @event; }
/// <summary> /// Create a new SocketOptions that references the given NetMQSocket. /// </summary> /// <param name="socket">the NetMQSocket for this SocketOptions to hold a reference to</param> public SocketOptions([NotNull] NetMQSocket socket) { this.m_socket = socket; }