static void Main(string[] args) { using (var context = NetMQContext.Create()) using (var udpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)) using (var poller = new Poller()) { // Ask OS to let us do broadcasts from socket udpSocket.SetSocketOption(SocketOptionLevel.Udp, SocketOptionName.Broadcast, 1); // Bind UDP socket to local port so we can receive pings udpSocket.Bind(new IPEndPoint(IPAddress.Any, PingPortNumber)); // We use zmq_poll to wait for activity on the UDP socket, because // this function works on non-0MQ file handles. We send a beacon // once a second, and we collect and report beacons that come in // from other nodes: poller.AddPollInSocket(udpSocket, socket => { }); poller.PollTillCancelledNonBlocking(); //poller.ad //var poller = new z //var pollItemsList = new List<ZPollItem>(); //pollItemsList.Add(new ZPollItem(ZPoll.In)); //var pollItem = ZPollItem.CreateReceiver(); //ZMessage message; //ZError error; //pollItem.ReceiveMessage(udpSocket, out message, out error); //pollItem.ReceiveMessage = (ZSocket socket, out ZMessage message, out ZError error) => // Send first ping right away } }
public NetMQScheduler(NetMQContext context, Poller poller = null) { m_context = context; if (poller == null) { m_ownPoller = true; m_poller = new Poller(); } else { m_ownPoller = false; m_poller = poller; } m_tasksQueue = new ConcurrentQueue <Task>(); m_syncObject = new object(); m_schedulerId = Interlocked.Increment(ref s_schedulerCounter); m_address = string.Format("{0}://scheduler-{1}", NetMQ.zmq.Address.InProcProtocol, m_schedulerId); m_serverSocket = context.CreatePullSocket(); m_serverSocket.Options.Linger = TimeSpan.Zero; m_serverSocket.Bind(m_address); m_currentMessageHandler = OnMessageFirstTime; m_serverSocket.ReceiveReady += m_currentMessageHandler; m_poller.AddSocket(m_serverSocket); m_clientSocket = m_context.CreatePushSocket(); m_clientSocket.Connect(m_address); m_schedulerThread = new ThreadLocal <bool>(() => false); if (m_ownPoller) { m_poller.PollTillCancelledNonBlocking(); } }
private NetMQScheduler(Poller poller, PushSocket pushSocket, PullSocket pullSocket) { if (poller == null) { m_ownPoller = true; m_poller = new Poller(); } else { m_ownPoller = false; m_poller = poller; } var address = string.Format("{0}://scheduler-{1}", Address.InProcProtocol, Interlocked.Increment(ref s_schedulerCounter)); m_serverSocket = pullSocket; m_serverSocket.Options.Linger = TimeSpan.Zero; m_serverSocket.Bind(address); m_currentMessageHandler = OnMessageFirstTime; m_serverSocket.ReceiveReady += m_currentMessageHandler; m_poller.AddSocket(m_serverSocket); m_clientSocket = pushSocket; m_clientSocket.Connect(address); m_isSchedulerThread = new ThreadLocal <bool>(() => false); if (m_ownPoller) { m_poller.PollTillCancelledNonBlocking(); } }
public void Run() { Console.WriteLine("[CLIENT {0}] Starting", m_id); var rnd = new Random(m_id); // each request shall have an unique id in order to recognize an reply for a request var messageId = new byte[5]; // create clientId for messages var clientId = new[] { m_id }; // a flag to signal that an answer has arrived bool messageAnswered = false; // we use a poller because we have a socket and a timer to monitor using (var clientPoller = new Poller()) using (var context = NetMQContext.Create()) using (var client = context.CreateRequestSocket()) using (var monitor = context.CreatePushSocket()) { client.Connect(m_localFrontendAddress); monitor.Connect(m_monitorAddress); client.Options.Identity = new[] { m_id }; var timer = new NetMQTimer((int)TimeSpan.FromSeconds(10).TotalMilliseconds); // use as flag to indicate exit var exit = false; // every 10 s check if message has been received, if not then send error message and ext // and restart timer otherwise timer.Elapsed += (s, e) => { if (messageAnswered) { e.Timer.Enable = true; } else { var msg = string.Format("[CLIENT {0}] ERR - EXIT - lost message {1}", m_id, messageId); // send an error message monitor.Send(msg); // if poller is started than stop it if (clientPoller.IsStarted) clientPoller.CancelAndJoin(); // mark the required exit exit = true; } }; // process arriving answers client.ReceiveReady += (s, e) => { // mark the arrival of an answer messageAnswered = true; // worker is supposed to answer with our request id var reply = e.Socket.ReceiveMultipartMessage(); if (reply.FrameCount == 0) { // something went wrong monitor.Send(string.Format("[CLIENT {0}] Received an empty message!", m_id)); // mark the exit flag to ensure the exit exit = true; } else { var sb = new StringBuilder(); // create success message foreach (var frame in reply) sb.Append("[" + frame.ConvertToString() + "]"); // send the success message monitor.Send(string.Format("[CLIENT {0}] Received answer {1}", m_id, sb.ToString())); } }; // add socket & timer to poller clientPoller.AddSocket(client); clientPoller.AddTimer(timer); // start poller in another thread to allow the continued processing clientPoller.PollTillCancelledNonBlocking(); // if true the message has been answered // the 0th message is always answered messageAnswered = true; while (!exit) { // simulate sporadic activity by randomly delaying Thread.Sleep((int)TimeSpan.FromSeconds(rnd.Next(5)).TotalMilliseconds); // only send next message if the previous one has been replied to if (messageAnswered) { // generate random 5 byte as identity for for the message rnd.NextBytes(messageId); messageAnswered = false; // create message [client adr][empty][message id] and send it var msg = new NetMQMessage(); msg.Push(messageId); msg.Push(NetMQFrame.Empty); msg.Push(clientId); client.SendMessage(msg); } } // stop poller if needed if (clientPoller.IsStarted) clientPoller.CancelAndJoin(); } }
/// <summary> /// Start proxying messages between the front and back ends. /// </summary> /// <exception cref="InvalidOperationException">The proxy has already been started.</exception> public void Start() { _status = "Attempting to start"; if (Interlocked.CompareExchange(ref _state, Running, NotStarted) != NotStarted) { throw new InvalidOperationException("ZeroMQ XPub-XSub hub has already been started"); } _status = "Starting"; _subscriber.ReceiveReady += OnSubscriberReady; _publisher.ReceiveReady += OnPublisherReady; _poller = new Poller(_subscriber, _publisher); if (_heartbeat != null) { _poller.AddTimer(_heartbeat); } this.SetJobState(JobState.Running); _status = "Started"; _poller.PollTillCancelledNonBlocking(); _status = "Running Until Canceled"; }
/// <summary> /// ParanoidPirate.Queue [-v] /// /// Does load-balancing with heartbeating on worker tasks to detect /// crashed, blocked or slow running worker tasks . /// </summary> private static void Main(string[] args) { Console.Title = "NetMQ ParanoidPirate Queue"; // serves as flag for exiting the program var exit = false; // catch CTRL+C as exit command Console.CancelKeyPress += (s, e) => { e.Cancel = true; exit = true; }; var verbose = args.Length > 0 && args[0] == "-v"; using (var context = NetMQContext.Create()) using (var frontend = context.CreateRouterSocket()) using (var backend = context.CreateRouterSocket()) using (var poller = new Poller()) { frontend.Bind(Commons.QueueFrontend); backend.Bind(Commons.QueueBackend); var workers = new Workers(); // client sends to this socket frontend.ReceiveReady += (s, e) => { // only process incoming client requests // if we have workers available handle client requests as long as we have workers // storage capability of the socket otherwise and pick up later if (workers.Available) { // get all message frames! var request = frontend.ReceiveMultipartMessage(); if (verbose) Console.WriteLine("[QUEUE] received {0}", request); // get next available worker var worker = workers.Next(); // wrap message with worker's address var msg = Wrap(worker, request); if (verbose) Console.WriteLine("[QUEUE -> WORKER] sending {0}", msg); backend.SendMessage(msg); } }; // worker sends to this socket backend.ReceiveReady += (s, e) => { var msg = e.Socket.ReceiveMultipartMessage(); if (verbose) Console.WriteLine("[QUEUE <- WORKER] received {0}", msg); // use workers identity for load-balancing var workerIdentity = Unwrap(msg); var worker = new Worker(workerIdentity); workers.Ready(worker); // just convenience var readableWorkerId = workerIdentity.ConvertToString(); if (msg.FrameCount == 1) { var data = msg[0].ConvertToString(); // the message is either READY or HEARTBEAT or corrupted switch (data) { case Commons.PPPHeartbeat: Console.WriteLine("[QUEUE <- WORKER] Received a Heartbeat from {0}", readableWorkerId); break; case Commons.PPPReady: Console.WriteLine("[QUEUE <- WORKER] Received a READY form {0}", readableWorkerId); break; default: Console.WriteLine("[QUEUE <- WORKER] ERROR received an invalid message!"); break; } } else { if (verbose) Console.WriteLine("[QUEUE -> CLIENT] sending {0}", msg); frontend.SendMessage(msg); } }; var timer = new NetMQTimer(Commons.HeartbeatInterval); // every specified ms QUEUE shall send a heartbeat to all connected workers timer.Elapsed += (s, e) => { // send heartbeat to every worker foreach (var worker in workers) { var heartbeat = new NetMQMessage(); heartbeat.Push(new NetMQFrame(Commons.PPPHeartbeat)); heartbeat.Push(worker.Identity); Console.WriteLine("[QUEUE -> WORKER] sending heartbeat!"); backend.SendMessage(heartbeat); } // restart timer e.Timer.Enable = true; // remove all dead or expired workers workers.Purge(); }; if (verbose) Console.WriteLine("[QUEUE] Start listening!"); poller.AddSocket(frontend); poller.AddSocket(backend); poller.PollTillCancelledNonBlocking(); // hit CRTL+C to stop the while loop while (!exit) {} // Cleanup poller.RemoveTimer(timer); // stop the poler task poller.CancelAndJoin(); // remove the sockets - Dispose is called automatically poller.RemoveSocket(frontend); poller.RemoveSocket(backend); } }
private static IDisposable StartNetMQServer() { var host = new WampHost(); var serverContext = NetMQContext.Create(); var serverSocket = serverContext.CreateResponseSocket();// serverContext.CreateRouterSocket(); var serverPoller = new Poller(serverSocket); var serverScheduler = new NetMQScheduler(serverContext, serverPoller); serverPoller.PollTillCancelledNonBlocking(); host.RegisterTransport(new NetMQTransport(serverSocket, serverScheduler), new JTokenJsonBinding(), new JTokenMsgpackBinding(), new ProtobufBinding()); host.Open(); var realm = host.RealmContainer.GetRealmByName("realm1"); realm.Services.RegisterCallee(new SumService(), new CalleeNameInterceptor()).Wait(); // add services (aka, RPC endpoints) like this // realm.Services.RegisterPublisher // register some event triggerer here return host; }