static void Main(string[] args) { using (NetMQContext context = NetMQContext.Create()) { using (WSRouter router = context.CreateWSRouter()) using (WSPublisher publisher = context.CreateWSPublisher()) { router.Bind("ws://localhost:80"); publisher.Bind("ws://localhost:81"); router.ReceiveReady += (sender, eventArgs) => { string identity = router.ReceiveString(); string message = router.ReceiveString(); router.SendMore(identity).Send("OK"); publisher.SendMore("chat").Send(message); }; Poller poller = new Poller(); poller.AddSocket(router); // we must add the publisher to the poller although we are not registering to any event. // The internal stream socket handle connections and subscriptions and use the events internally poller.AddSocket(publisher); poller.Start(); } } }
public void RunPipeline(PairSocket shim) { publisherSocket = context.CreatePublisherSocket(); publisherSocket.Bind("tcp://*:" + StreamingProtocol.Port); snapshotSocket = context.CreateResponseSocket(); snapshotSocket.Bind("tcp://*:" + SnapshotProtocol.Port); snapshotSocket.ReceiveReady += OnSnapshotReady; shim.ReceiveReady += OnShimReady; heartbeatTimer = new NetMQTimer(StreamingProtocol.HeartbeatInterval); heartbeatTimer.Elapsed += OnHeartbeatTimerElapsed; shim.SignalOK(); poller = new Poller(); poller.AddSocket(shim); poller.AddSocket(snapshotSocket); poller.AddTimer(heartbeatTimer); poller.Start(); publisherSocket.Dispose(); snapshotSocket.Dispose(); }
private static void Main() { using (var context = NetMQContext.Create()) using (var frontend = context.CreateRouterSocket()) using (var backend = context.CreateDealerSocket()) { frontend.Bind(FrontendEndpoint); backend.Bind(BackendEndpoint); // Handler for messages coming in to the frontend frontend.ReceiveReady += (sender, e) => { var msg = frontend.ReceiveMessage(); backend.SendMessage(msg); // Relay this message to the backend }; // Handler for messages coming in to the backend backend.ReceiveReady += (sender, e) => { var msg = backend.ReceiveMessage(); frontend.SendMessage(msg); // Relay this message to the frontend }; using (var poller = new Poller()) { poller.AddSocket(backend); poller.AddSocket(frontend); // Listen out for events on both sockets and raise events when messages come in poller.PollTillCancelled(); } } }
private static void Main(string[] args) { using (var ctx = NetMQContext.Create()) { using (NetMQSocket frontend = ctx.CreateRouterSocket(), backend = ctx.CreateDealerSocket()) { frontend.Bind(FRONTEND_ENDPOINT); backend.Bind(BACKEND_ENDPOINT); //Handler for messages coming in to the frontend frontend.ReceiveReady += (sender, e) => { var msg = frontend.ReceiveMessage(); backend.SendMessage(msg); //Relay this message to the backend }; //Handler for messages coming in to the backend backend.ReceiveReady += (sender, e) => { var msg = backend.ReceiveMessage(); frontend.SendMessage(msg); //Relay this message to the frontend }; using (var poller = new Poller()) { poller.AddSocket(backend); poller.AddSocket(frontend); //Listen out for events on both sockets and raise events when messages come in poller.Start(); } } } }
public void Listen(CancellationToken cancellationToken) { using (var electionServer = context.CreateResponseSocket()) using (var leaderServer = context.CreateResponseSocket()) using (var pingServer = context.CreateResponseSocket()) using (var poller = new Poller()) { electionServer.Bind(Settings.ElectionListenerEndpoint); leaderServer.Bind(Settings.LeaderListenerEndpoint); pingServer.Bind(Settings.PingListenerEndpoint); logger.Log($"ElectionListenerEndpoint: {Settings.ElectionListenerEndpoint}"); logger.Log($"LeaderListenerEndpoint: {Settings.LeaderListenerEndpoint}"); logger.Log($"PingListenerEndpoint: {Settings.PingListenerEndpoint}"); poller.AddSocket(electionServer); poller.AddSocket(leaderServer); poller.AddSocket(pingServer); // Listen for new messages on the electionServer socket electionServer.ReceiveReady += (s, a) => { var msg = a.Socket.ReceiveFrameString(); logger.Log($"ELECTION MESSAGE: {msg}"); if (msg == Message.Election) { a.Socket.SendFrame(msg == Message.Election ? Message.Ok : Message.Fail); } }; // Listen for new messages on the leaderServer socket leaderServer.ReceiveReady += (s, a) => { var winnerMessage = a.Socket.ReceiveFrameString(); OnLeaderChanged(winnerMessage); logger.Log($"NEW LEADER MESSAGE RECEIVED: {winnerMessage}"); }; // Listen for pings pingServer.ReceiveReady += (s, a) => { a.Socket.ReceiveFrameString(); a.Socket.SendFrame(Message.Ok); }; logger.Log("-----------------------------------"); poller.PollTillCancelled(); } }
void IShimHandler.Run(PairSocket pipe) { _pipe = pipe; _pipe.SignalOK(); _pipe.ReceiveReady += OnPipeReady; _zre = Zre.Create(_ctx, _name); _zre.ReceiveReady += OnZreReady; _poller = new Poller(); _poller.AddSocket(_zre); _poller.AddSocket(_pipe); _poller.PollTillCancelled(); }
public void Receive_BrokerDisconnectedWithLogging_ShouldReturnRequest() { const string host_address = "tcp://localhost:5555"; var loggingMessages = new List <string> (); // setup the counter socket for communication using (var ctx = NetMQContext.Create()) using (var broker = ctx.CreateRouterSocket()) using (var poller = new NetMQ.Poller()) using (var session = new MDPWorker(host_address, "test")) { broker.Bind(host_address); // we need to pick up any message in order to avoid errors but don't answer broker.ReceiveReady += (s, e) => e.Socket.ReceiveMessage(); poller.AddSocket(broker); var t = Task.Factory.StartNew(() => poller.Start()); // speed up the test session.HeartbeatDelay = TimeSpan.FromMilliseconds(250); session.ReconnectDelay = TimeSpan.FromMilliseconds(250); // set the event handler to receive the logging messages session.LogInfoReady += (s, e) => loggingMessages.Add(e.Info); // initialize the worker - broker protocol session.Receive(null); poller.Stop(); poller.RemoveSocket(broker); Assert.That(loggingMessages.Count(m => m.Contains("retrying")), Is.EqualTo(3)); // 3 times retrying and 1 time initial connecting Assert.That(loggingMessages.Count(m => m.Contains("localhost")), Is.EqualTo(4)); Assert.That(loggingMessages.Last().Contains("abandoning")); } }
private void PollerThread() { while (true) { try { if (poller == null || !poller.IsStarted) { SignalService.Logger.Info("Start NetMQ Poller"); poller = new Poller(); poller.AddSocket(router); poller.Start(); } } catch (Exception e) { SignalService.Logger.Error("NetMQ Poller Thread Exception.\n{0}", e.StackTrace); if (poller != null) { poller.Stop(); poller.Dispose(); } } } }
public void ReceiveImplicitConnect_ValidScenario_ShouldReturnRequest() { const string host_address = "tcp://localhost:5557"; var loggingMessages = new List <string> (); // setup the counter socket for communication using (var ctx = NetMQContext.Create()) using (var broker = ctx.CreateRouterSocket()) using (var poller = new NetMQ.Poller()) using (var session = new MDPWorker(host_address, "test", new[] { (byte)'1' })) { broker.Bind(host_address); // we need to pick up any message in order to avoid errors broker.ReceiveReady += (s, e) => { var msg = e.Socket.ReceiveMessage(); // we expect to receive a 5 Frame mesage // [WORKER ADR][EMPTY]["MDPW01"]["READY"]["test"] if (msg.FrameCount != 5) { Assert.Fail("Message with wrong count of frames {0}", msg.FrameCount); } // make sure the frames are as expected Assert.That(msg[1], Is.EqualTo(NetMQFrame.Empty)); Assert.That(msg[2].ConvertToString(), Is.EqualTo("MDPW01")); Assert.That(msg[3].BufferSize, Is.EqualTo(1)); Assert.That(msg[3].Buffer[0], Is.EqualTo((byte)MDPCommand.Ready)); Assert.That(msg[4].ConvertToString(), Is.EqualTo("test")); // tell worker to stop gracefully var reply = new NetMQMessage(); reply.Push(new[] { (byte)MDPCommand.Kill }); // push MDP Version reply.Push(msg[2]); // push separator reply.Push(NetMQFrame.Empty); // push worker address reply.Push(msg[0]); // send reply which is a request for the worker e.Socket.SendMessage(reply); }; poller.AddSocket(broker); var t = Task.Factory.StartNew(() => poller.Start()); // set the event handler to receive the logging messages session.LogInfoReady += (s, e) => loggingMessages.Add(e.Info); // initialize the worker - broker protocol session.Receive(null); poller.Stop(); poller.RemoveSocket(broker); Assert.That(loggingMessages.Count, Is.EqualTo(5)); Assert.That(loggingMessages[0], Is.EqualTo("[WORKER] connected to broker at tcp://localhost:5557")); Assert.That(loggingMessages[1].Contains("[WORKER] sending"), Is.True); Assert.That(loggingMessages[2].Contains("[WORKER] received")); Assert.That(loggingMessages[4].Contains("abandoning")); } }
public static void Main(string[] args) { // // Task worker - design 2 // Adds pub-sub flow to receive and respond to kill signal // // Author: metadings // // Socket to receive messages on, // Socket to send messages to and // Socket for control input using (var context = NetMQContext.Create()) using (var receiver = context.CreatePullSocket()) using (var sender = context.CreatePushSocket()) using (var controller = context.CreateSubscriberSocket()) { receiver.Connect("tcp://127.0.0.1:5557"); sender.Connect("tcp://127.0.0.1:5558"); controller.Connect("tcp://127.0.0.1:5559"); controller.SubscribeToAnyTopic(); var poller = new Poller(); poller.AddSocket(receiver); poller.AddSocket(controller); receiver.ReceiveReady += (o, eventArgs) => { var workload = int.Parse(eventArgs.Socket.ReceiveFrameString()); Console.WriteLine("{0}.", workload); // Show progress Thread.Sleep(workload); // Do the work sender.SendFrame(new byte[0]); // Send results to sink }; controller.ReceiveReady += (o, eventArgs) => { if (eventArgs.Socket.ReceiveFrameString() == "KILL"); poller.Cancel(); }; poller.PollTillCancelled(); } }
public void ReceiveImplicitConnect_ValidScenario_ShouldReturnRequest() { const string hostAddress = "tcp://localhost:5557"; var loggingMessages = new List<string> (); // setup the counter socket for communication using (var context = NetMQContext.Create ()) using (var broker = context.CreateRouterSocket ()) using (var poller = new Poller ()) using (var session = new MDPWorker (hostAddress, "test", new[] { (byte) '1' })) { broker.Bind (hostAddress); // we need to pick up any message in order to avoid errors broker.ReceiveReady += (s, e) => { var msg = e.Socket.ReceiveMultipartMessage (); // we expect to receive a 5 Frame message // [WORKER ADR][EMPTY]["MDPW01"]["READY"]["test"] if (msg.FrameCount != 5) Assert.Fail ("Message with wrong count of frames {0}", msg.FrameCount); // make sure the frames are as expected Assert.That (msg[1], Is.EqualTo (NetMQFrame.Empty)); Assert.That (msg[2].ConvertToString (), Is.EqualTo ("MDPW01")); Assert.That (msg[3].BufferSize, Is.EqualTo (1)); Assert.That (msg[3].Buffer[0], Is.EqualTo ((byte) MDPCommand.Ready)); Assert.That (msg[4].ConvertToString (), Is.EqualTo ("test")); // tell worker to stop gracefully var reply = new NetMQMessage (); reply.Push (new[] { (byte) MDPCommand.Kill }); // push MDP Version reply.Push (msg[2]); // push separator reply.Push (NetMQFrame.Empty); // push worker address reply.Push (msg[0]); // send reply which is a request for the worker e.Socket.SendMessage (reply); }; poller.AddSocket (broker); Task.Factory.StartNew (poller.PollTillCancelled); // set the event handler to receive the logging messages session.LogInfoReady += (s, e) => loggingMessages.Add (e.Info); // initialise the worker - broker protocol session.Receive (null); poller.CancelAndJoin (); poller.RemoveSocket (broker); Assert.That (loggingMessages.Count, Is.EqualTo (5)); Assert.That (loggingMessages[0], Is.EqualTo ("[WORKER] connected to broker at tcp://localhost:5557")); Assert.That (loggingMessages[1].Contains ("[WORKER] sending"), Is.True); Assert.That (loggingMessages[2].Contains ("[WORKER] received")); Assert.That (loggingMessages[4].Contains ("abandoning")); } }
public void Receive_RequestWithWrongFirstFrame_ShouldThrowApplicationException() { const string host_address = "tcp://localhost:5555"; // setup the counter socket for communication using (var ctx = NetMQContext.Create()) using (var broker = ctx.CreateRouterSocket()) using (var poller = new NetMQ.Poller()) using (var session = new MDPWorker(host_address, "test")) { broker.Bind(host_address); // we need to pick up any message in order to avoid errors broker.ReceiveReady += (s, e) => { var msg = e.Socket.ReceiveMessage(); // we expect to receive a 5 Frame mesage // [WORKER ADR][EMPTY]["MDPW01"]["READY"]["test"] if (msg.FrameCount != 5) { Assert.Fail("Message with wrong count of frames {0}", msg.FrameCount); } // make sure the frames are as expected Assert.That(msg[1], Is.EqualTo(NetMQFrame.Empty)); Assert.That(msg[2].ConvertToString(), Is.EqualTo("MDPW01")); Assert.That(msg[3].BufferSize, Is.EqualTo(1)); Assert.That(msg[3].Buffer[0], Is.EqualTo((byte)MDPCommand.Ready)); Assert.That(msg[4].ConvertToString(), Is.EqualTo("test")); // tell worker to stop gracefully var reply = new NetMQMessage(); reply.Push(new[] { (byte)MDPCommand.Kill }); // push MDP Version reply.Push("MDPW01"); // push separator reply.Push("Should be empty"); // push worker address reply.Push(msg[0]); // send reply which is a request for the worker e.Socket.SendMessage(reply); }; poller.AddSocket(broker); var t = Task.Factory.StartNew(() => poller.Start()); try { var reply = session.Receive(null); } catch (ApplicationException ex) { Assert.That(ex.Message, Is.EqualTo("First frame must be an empty frame!")); } poller.Stop(); poller.RemoveSocket(broker); } }
public void Send_WrongHeaderFromBrokerNoLogging_ShouldThrowApplicationException() { const string host_address = "tcp://localhost:5555"; // setup the counter socket for communication using (var ctx = NetMQContext.Create()) using (var broker = ctx.CreateRouterSocket()) using (var poller = new Poller()) using (var session = new MDPClient(host_address)) { broker.Bind(host_address); // we need to pick up any message in order to avoid errors broker.ReceiveReady += (s, e) => { // return empty reply var msg = e.Socket.ReceiveMessage(); // we expect to receive a 4 Frame mesage // [REQ ADR][EMPTY]["MDPC01"]["echo"]["REQUEST"] if (msg.FrameCount != 5) { Assert.Fail("Message with wrong count of frames {0}", msg.FrameCount); } // REQUEST socket will strip the his address + empty frame // ROUTER has to add the address prelude in order to identify the correct socket(!) // [REQ ADR][EMPTY]["MDPC00"]["echo"]["REQUEST"] var clientAddress = msg.Pop(); msg.Pop(); // forget empty frame var mdpVersion = msg.Pop(); msg.Pop(); // drop service name version msg.Push("NoService"); msg.Push(mdpVersion); msg.Push(NetMQFrame.Empty); msg.Push(clientAddress); // reinsert the client's address e.Socket.SendMessage(msg); }; poller.AddSocket(broker); var t = Task.Factory.StartNew(() => poller.Start()); // well formed message var requestMessage = new NetMQMessage(new[] { new NetMQFrame("REQUEST") }); try { session.Send("echo", requestMessage); } catch (ApplicationException ex) { Assert.That(ex.Message, Is.EqualTo("[CLIENT INFO] answered by wrong service: NoService")); } poller.Stop(); poller.RemoveSocket(broker); } }
public MessageHelper(string address, string topic) { _context = NetMQContext.Create(); _subscribeSocket = _context.CreateSubscriberSocket(); _subscribeSocket.Connect(address); _subscribeSocket.ReceiveReady += SubscribeSocketOnReceiveReady; _subscribeSocket.Subscribe(topic); _poller = new Poller(); _poller.AddSocket(_subscribeSocket); Task.Factory.StartNew(_poller.Start); }
public void Send_CorrectInputWithLogging_ShouldReturnCorrectReply() { const string host_address = "tcp://localhost:5555"; var loggingMessages = new List <string> (); // setup the counter socket for communication using (var ctx = NetMQContext.Create()) using (var broker = ctx.CreateRouterSocket()) using (var poller = new Poller()) using (var session = new MDPClient(host_address)) { broker.Bind(host_address); // we need to pick up any message in order to avoid errors broker.ReceiveReady += (s, e) => { var msg = e.Socket.ReceiveMessage(); // we expect to receive a 4 Frame mesage // [client adrR][e][mdp header][service][request] if (msg.FrameCount != 5) { Assert.Fail("Message with wrong count of frames {0}", msg.FrameCount); } // REQUEST socket will strip the his address + empty frame // ROUTER has to add the address prelude in order to identify the correct socket(!) // [client adr][e][mdp header][service][reply] var request = msg.Last.ConvertToString(); // get the request string msg.RemoveFrame(msg.Last); // remove the request frame msg.Append(new NetMQFrame(request + " OK")); // append the reply frame e.Socket.SendMessage(msg); }; poller.AddSocket(broker); var t = Task.Factory.StartNew(() => poller.Start()); // set the event handler to receive the logging messages session.LogInfoReady += (s, e) => loggingMessages.Add(e.Info); // well formed message var requestMessage = new NetMQMessage(new[] { new NetMQFrame("REQUEST") }); // correct call var reply = session.Send("echo", requestMessage); poller.Stop(); poller.RemoveSocket(broker); Assert.That(reply.FrameCount, Is.EqualTo(1)); Assert.That(reply.First.ConvertToString(), Is.EqualTo("REQUEST OK")); Assert.That(loggingMessages.Count, Is.EqualTo(3)); Assert.That(loggingMessages[0], Is.EqualTo("[CLIENT] connecting to broker at tcp://localhost:5555")); Assert.That(loggingMessages[1].Contains("[CLIENT INFO] sending"), Is.True); Assert.That(loggingMessages[2].Contains("[CLIENT INFO] received"), Is.True); } }
public void Send_CorrectInputWithLogging_ShouldReturnCorrectReply() { const string hostAddress = "tcp://localhost:5555"; var loggingMessages = new List<string>(); // setup the counter socket for communication using (var context = NetMQContext.Create()) using (var broker = context.CreateRouterSocket()) using (var poller = new Poller()) using (var session = new MDPClient(hostAddress)) { broker.Bind(hostAddress); // we need to pick up any message in order to avoid errors broker.ReceiveReady += (s, e) => { var msg = e.Socket.ReceiveMessage(); // we expect to receive a 4 Frame message // [client adrR][e][mdp header][service][request] if (msg.FrameCount != 5) Assert.Fail("Message with wrong count of frames {0}", msg.FrameCount); // REQUEST socket will strip the his address + empty frame // ROUTER has to add the address prelude in order to identify the correct socket(!) // [client adr][e][mdp header][service][reply] var request = msg.Last.ConvertToString(); // get the request string msg.RemoveFrame(msg.Last); // remove the request frame msg.Append(new NetMQFrame(request + " OK")); // append the reply frame e.Socket.SendMessage(msg); }; poller.AddSocket(broker); Task.Factory.StartNew(poller.PollTillCancelled); // set the event handler to receive the logging messages session.LogInfoReady += (s, e) => loggingMessages.Add(e.Info); // well formed message var requestMessage = new NetMQMessage(new[] { new NetMQFrame("REQUEST") }); // correct call var reply = session.Send("echo", requestMessage); poller.CancelAndJoin(); poller.RemoveSocket(broker); Assert.That(reply.FrameCount, Is.EqualTo(1)); Assert.That(reply.First.ConvertToString(), Is.EqualTo("REQUEST OK")); Assert.That(loggingMessages.Count, Is.EqualTo(3)); Assert.That(loggingMessages[0], Is.EqualTo("[CLIENT] connecting to broker at tcp://localhost:5555")); Assert.That(loggingMessages[1].Contains("[CLIENT INFO] sending"), Is.True); Assert.That(loggingMessages[2].Contains("[CLIENT INFO] received"), Is.True); } }
public void Send_EmptyReplyFromBrokerWithLogging_ShouldThrowApplicationException() { const string host_address = "tcp://localhost:5555"; var loggingMessages = new List <string> (); // setup the counter socket for communication using (var ctx = NetMQContext.Create()) using (var broker = ctx.CreateRouterSocket()) using (var poller = new Poller()) using (var session = new MDPClient(host_address)) { broker.Bind(host_address); // we need to pick up any message in order to avoid errors broker.ReceiveReady += (s, e) => { // return empty reply var msg = e.Socket.ReceiveMessage(); // we expect to receive a 4 Frame mesage // [REQ ADR][EMPTY]["MDPC01"]["echo"]["REQUEST"] if (msg.FrameCount != 5) { Assert.Fail("Message with wrong count of frames {0}", msg.FrameCount); } // REQUEST socket will strip the his address + empty frame // ROUTER has to add the address prelude in order to identify the correct socket(!) // [REQ ADR][EMPTY]["MDPC01"]["echo"]["REQUEST"] e.Socket.SendMessage(msg); }; poller.AddSocket(broker); var t = Task.Factory.StartNew(() => poller.Start()); // set the event handler to receive the logging messages session.LogInfoReady += (s, e) => loggingMessages.Add(e.Info); // well formed message var requestMessage = new NetMQMessage(new[] { new NetMQFrame("REQUEST") }); // correct call session.Send("echo", requestMessage); poller.Stop(); poller.RemoveSocket(broker); Assert.That(loggingMessages.Count, Is.EqualTo(3)); Assert.That(loggingMessages[0], Is.EqualTo("[CLIENT] connecting to broker at tcp://localhost:5555")); Assert.That(loggingMessages[1].Contains("[CLIENT INFO] sending"), Is.True); Assert.That(loggingMessages[2].Contains("[CLIENT INFO] received"), Is.True); } }
public void Start() { using (m_serverSocket = m_context.CreateResponseSocket()) { foreach (var address in m_addresses) { m_log.InfoFormat("Listening on {0}", address); m_serverSocket.Bind(address); } m_serverSocket.ReceiveReady += OnMessage; m_poller = new Poller(); m_poller.AddSocket(m_serverSocket); m_poller.Start(); } }
public void SingleSocketPollTest() { using (NetMQContext contex = NetMQContext.Create()) { using (var rep = contex.CreateResponseSocket()) { rep.Bind("tcp://127.0.0.1:5002"); using (var req = contex.CreateRequestSocket()) using (Poller poller = new Poller()) { req.Connect("tcp://127.0.0.1:5002"); //The ReceiveReady event is raised by the Poller rep.ReceiveReady += (s, a) => { bool more; string m = a.Socket.ReceiveString(out more); Assert.False(more); Assert.AreEqual("Hello", m); a.Socket.Send("World"); }; poller.AddSocket(rep); Task pollerTask = Task.Factory.StartNew(poller.Start); req.Send("Hello"); bool more2; string m1 = req.ReceiveString(out more2); Assert.IsFalse(more2); Assert.AreEqual("World", m1); poller.Stop(); Thread.Sleep(100); Assert.IsTrue(pollerTask.IsCompleted); } } } }
private void Connect() { // getting the snapshot using (RequestSocket requestSocket = context.CreateRequestSocket()) { requestSocket.Connect(string.Format("tcp://{0}:{1}", address, SnapshotProtocol.Port)); requestSocket.Send(SnapshotProtocol.GetTradessCommand); string json; requestSocket.Options.ReceiveTimeout = SnapshotProtocol.RequestTimeout; try { json = requestSocket.ReceiveString(); } catch (AgainException ex) { // Fail to receive trades, we call on error and don't try to do anything with subscriber // calling on error from poller thread block the application Task.Run(() => subject.OnError(new Exception("No response from server"))); return; } while (json != SnapshotProtocol.EndOfTickers) { PublishTicker(json); json = requestSocket.ReceiveString(); } } subscriberSocket = context.CreateSubscriberSocket(); subscriberSocket.Subscribe(StreamingProtocol.TradesTopic); subscriberSocket.Subscribe(StreamingProtocol.HeartbeatTopic); subscriberSocket.Connect(string.Format("tcp://{0}:{1}", address, StreamingProtocol.Port)); subscriberSocket.ReceiveReady += OnSubscriberReady; poller.AddSocket(subscriberSocket); // reset timeout timer timeoutTimer.Enable = false; timeoutTimer.Enable = true; }
private void Connect() { subscriberSocket = context.CreateSubscriberSocket(); subscriberSocket.Subscribe(StreamingProtocol.HeartbeatTopic); subscriberSocket.Connect(string.Format("tcp://{0}:{1}", address, StreamingProtocol.Port)); subject.OnNext(new ConnectionInfo(ConnectionStatus.Connecting, this.address)); subscriberSocket.ReceiveReady += OnSubscriberReady; poller.AddSocket(subscriberSocket); // reset timeout timer timeoutTimer.Enable = false; timeoutTimer.Enable = true; }
/// <summary> /// run the broker - if not bound to endpoint automatically binds to known endpoint /// </summary> /// <param name="token">CancellationToken to cancel the method</param> /// <exception cref="InvalidOperationException">Can't start same broker more than once!</exception> public void RunSynchronous(CancellationToken token) { if (m_isRunning) { throw new InvalidOperationException("Can't start same broker more than once!"); } if (!m_isBound) { Bind(); } m_isRunning = true; using (var poller = new NetMQ.Poller()) { Socket.ReceiveReady += ProcessReceiveMessage; // get timer for scheduling heartbeat var timer = new NetMQTimer(HeartbeatInterval); // send every 'HeartbeatInterval' a heartbeat to all not expired workers timer.Elapsed += (s, e) => SendHeartbeat(); poller.AddSocket(Socket); poller.AddTimer(timer); Log("[BROKER] Starting to listen for incoming messages ..."); // start the poller and wait for the return, which will happen once token is // signalling Cancel(!) Task.Factory.StartNew(poller.Start, token).Wait(); Log("[BROKER] ... Stopped!"); // clean up poller.RemoveTimer(timer); poller.RemoveSocket(Socket); // unregister event handler Socket.ReceiveReady -= ProcessReceiveMessage; } m_isRunning = false; }
static void Main(string[] args) { using (var context = NetMQContext.Create()) { string[] topics = new string[] { "A", "B", "C" }; Random random = new Random(); using (var publisher = context.CreateXPublisherSocket()) { // Set publisher to manual subscriptions mode publisher.Options.ManualPublisher = true; publisher.Bind("tcp://*:5556"); publisher.ReceiveReady += (sender, eventArgs) => { var message = publisher.ReceiveString(); // we only handle subscription requests, unsubscription and any // other type of messages will be dropped if (message[0] == (char)1) { // calling Subscribe to add subscription to the last subscriber publisher.Subscribe(message.Substring(1)); } }; NetMQTimer sendTimer = new NetMQTimer(1000); sendTimer.Elapsed += (sender, eventArgs) => { // sends a message every second with random topic and current time publisher. SendMore(topics[random.Next(3)]). Send(DateTime.Now.ToString()); }; Poller poller = new Poller(); poller.AddSocket(publisher); poller.AddTimer(sendTimer); poller.PollTillCancelled(); } } }
static void Main(string[] args) { using (NetMQContext context = NetMQContext.Create()) using (NetMQSocket subscribeSocket = context.CreateSubscriberSocket()) { subscribeSocket.Connect("tcp://127.0.0.1:5002"); subscribeSocket.ReceiveReady += SubSocketOnReceiveReady; subscribeSocket.Subscribe(""); //Prefix of messages to receive. Empty string receives all messages subscribeSocket.Options.TcpKeepalive = true; subscribeSocket.Options.TcpKeepaliveIdle = TimeSpan.FromSeconds(5); subscribeSocket.Options.TcpKeepaliveInterval = TimeSpan.FromSeconds(1); Poller poller = new Poller(); poller.AddSocket(subscribeSocket); Task.Factory.StartNew(poller.Start); Console.WriteLine("Waiting to receive messages. Press 'q' to quit."); while (Console.ReadLine() != "q") { } poller.Stop(true); } }
public void RunPipeline(PairSocket shim) { // we should signal before running the poller but this will block the application shim.SignalOK(); this.poller = new Poller(); shim.ReceiveReady += OnShimReady; poller.AddSocket(shim); timeoutTimer = new NetMQTimer(StreamingProtocol.Timeout); timeoutTimer.Elapsed += TimeoutElapsed; poller.AddTimer(timeoutTimer); Connect(); poller.Start(); if (subscriberSocket != null) { subscriberSocket.Dispose(); } }
public void Run(PairSocket shim) { m_pipe = shim; shim.SignalOK(); m_pipe.ReceiveReady += OnPipeReady; m_pingTimer = new NetMQTimer(0); m_pingTimer.Elapsed += PingElapsed; m_pingTimer.Enable = false; m_poller = new Poller(); m_poller.AddSocket(m_pipe); m_poller.AddTimer(m_pingTimer); m_poller.PollTillCancelled(); // the beacon might never been configured if (m_udpSocket != null) { m_udpSocket.Close(); } }
public void Send_WrongServiceNameWithLogging_ShouldLogPermanentError() { const string host_address = "tcp://localhost:5555"; var loggingMessages = new List <string> (); // setup the counter socket for communication using (var ctx = NetMQContext.Create()) using (var broker = ctx.CreateRouterSocket()) using (var poller = new Poller()) using (var session = new MDPClient(host_address)) { broker.Bind(host_address); // we need to pick up any message in order to avoid errors broker.ReceiveReady += (s, e) => { // just swallow message -> wrong service name var msg = e.Socket.ReceiveMessage(); }; poller.AddSocket(broker); var t = Task.Factory.StartNew(() => poller.Start()); // set the event handler to receive the logging messages session.LogInfoReady += (s, e) => loggingMessages.Add(e.Info); // well formed message var requestMessage = new NetMQMessage(new[] { new NetMQFrame("REQUEST") }); // wrong service name session.Send("xyz", requestMessage); poller.Stop(); poller.RemoveSocket(broker); Assert.That(loggingMessages.Count, Is.EqualTo(7)); Assert.That(loggingMessages[6], Is.EqualTo("[CLIENT ERROR] permanent error, abandoning!")); } }
/// <summary> /// run the broker - if not bound to endpoint automatically binds to known endpoint /// </summary> /// <param name="token">CancellationToken to cancel the method</param> /// <exception cref="InvalidOperationException">Can't start same broker more than once!</exception> public void RunSynchronous (CancellationToken token) { if (m_isRunning) throw new InvalidOperationException ("Can't start same broker more than once!"); if (!m_isBound) Bind (); m_isRunning = true; using (var poller = new Poller ()) { Socket.ReceiveReady += ProcessReceivedMessage; // get timer for scheduling heartbeat var timer = new NetMQTimer (HeartbeatInterval); // send every 'HeartbeatInterval' a heartbeat to all not expired workers timer.Elapsed += (s, e) => SendHeartbeat (); poller.AddSocket (Socket); poller.AddTimer (timer); Log ("Starting to listen for incoming messages ..."); // start the poller and wait for the return, which will happen once token is // signalling Cancel(!) Task.Factory.StartNew (poller.PollTillCancelled, token).Wait (); Log ("... Stopped!"); // clean up poller.RemoveTimer (timer); poller.RemoveSocket (Socket); // unregister event handler Socket.ReceiveReady -= ProcessReceivedMessage; } m_isRunning = false; }
private void Connect() { List<SubscriberSocket> sockets = new List<SubscriberSocket>(); Poller poller = new Poller(); SubscriberSocket connectedSocket = null; // event handler to handle message from socket EventHandler<NetMQSocketEventArgs> handleMessage = (sender, args) => { connectedSocket = (SubscriberSocket)args.Socket; poller.Cancel(); }; NetMQTimer timeoutTimer = new NetMQTimer(TimeOut); // just cancel the poller without seting the connected socket timeoutTimer.Elapsed += (sender, args) => poller.Cancel(); poller.AddTimer(timeoutTimer); foreach (var address in m_addresses) { var socket = m_context.CreateSubscriberSocket(); sockets.Add(socket); socket.ReceiveReady += handleMessage; poller.AddSocket(socket); // Subscribe to welcome message socket.Subscribe(WelcomeMessage); socket.Connect(address); } poller.PollTillCancelled(); // if we a connected socket the connection attempt succeed if (connectedSocket != null) { // remove the connected socket form the list sockets.Remove(connectedSocket); // close all exsiting connections foreach (var socket in sockets) { // to close them immediatly we set the linger to zero socket.Options.Linger = TimeSpan.Zero; socket.Dispose(); } // set the socket m_subscriber = connectedSocket; // drop the welcome message m_subscriber.SkipMultipartMessage(); // subscribe to heartbeat m_subscriber.Subscribe(HeartbeatMessage); // subscribe to all subscriptions foreach (string subscription in m_subscriptions) { m_subscriber.Subscribe(subscription); } m_subscriber.ReceiveReady -= handleMessage; m_subscriber.ReceiveReady += OnSubscriberMessage; m_poller.AddSocket(m_subscriber); m_timeoutTimer.Enable = true; m_reconnectTimer.Enable = false; } else { // close all exsiting connections foreach (var socket in sockets) { // to close them immediatly we set the linger to zero socket.Options.Linger = TimeSpan.Zero; socket.Dispose(); } m_reconnectTimer.Enable = true; m_timeoutTimer.Enable = false; } }
public void Receive_BrokerDisconnectedWithLogging_ShouldReturnRequest() { const string hostAddress = "tcp://localhost:5555"; var loggingMessages = new List<string> (); // setup the counter socket for communication using (var context = NetMQContext.Create ()) using (var broker = context.CreateRouterSocket ()) using (var poller = new Poller ()) using (var session = new MDPWorker (hostAddress, "test")) { broker.Bind (hostAddress); // we need to pick up any message in order to avoid errors but don't answer broker.ReceiveReady += (s, e) => e.Socket.ReceiveMultipartMessage (); poller.AddSocket (broker); Task.Factory.StartNew (poller.PollTillCancelled); // speed up the test session.HeartbeatDelay = TimeSpan.FromMilliseconds (250); session.ReconnectDelay = TimeSpan.FromMilliseconds (250); // set the event handler to receive the logging messages session.LogInfoReady += (s, e) => loggingMessages.Add (e.Info); // initialise the worker - broker protocol session.Receive (null); poller.CancelAndJoin (); poller.RemoveSocket (broker); Assert.That (loggingMessages.Count (m => m.Contains ("retrying")), Is.EqualTo (3)); // 3 times retrying and 1 time initial connecting Assert.That (loggingMessages.Count (m => m.Contains ("localhost")), Is.EqualTo (4)); Assert.That (loggingMessages.Last ().Contains ("abandoning")); } }
private SubscriberSocket Connect(string[] addresses) { List<SubscriberSocket> sockets = new List<SubscriberSocket>(); Poller poller = new Poller(); SubscriberSocket connectedSocket = null; // event handler to handle message from socket EventHandler<NetMQSocketEventArgs> handleMessage = (sender, args) => { if (connectedSocket == null) { connectedSocket = (SubscriberSocket) args.Socket; poller.Cancel(); } }; // If timeout elapsed just cancel the poller without seting the connected socket NetMQTimer timeoutTimer = new NetMQTimer(TimeSpan.FromSeconds(5)); timeoutTimer.Elapsed += (sender, args) => poller.Cancel(); poller.AddTimer(timeoutTimer); foreach (var address in addresses) { var socket = m_context.CreateSubscriberSocket(); sockets.Add(socket); socket.ReceiveReady += handleMessage; poller.AddSocket(socket); // Subscribe to welcome message socket.Subscribe("WM"); socket.Connect(address); } poller.PollTillCancelled(); // if we a connected socket the connection attempt succeed if (connectedSocket != null) { // remove the connected socket form the list sockets.Remove(connectedSocket); // close all existing sockets CloseSockets(sockets); // drop the welcome message connectedSocket.SkipMultipartMessage(); // subscribe to heartbeat connectedSocket.Subscribe("HB"); // subscribe to our only topic connectedSocket.Subscribe("A"); connectedSocket.ReceiveReady -= handleMessage; connectedSocket.ReceiveReady += OnSubscriberMessage; return connectedSocket; } else { // close all existing sockets CloseSockets(sockets); return null; } }
static void Main(string[] args) { // this key should be shared between authorization server and publisher const string Key = "SecretKey"; string[] symbols = new[] {"EURUSD", "GBPUSD", "EURJPY", "USDJPY", "EURGBP", "GBPJPY"}; Random random = new Random(); using (var context = NetMQContext.Create()) { using (var publisher = context.CreateXPublisherSocket()) { publisher.Options.ManualPublisher = true; publisher.Bind("tcp://*:5558"); publisher.ReceiveReady += (sender, eventArgs) => { byte[] subscriptionBytes = publisher.Receive(); if (subscriptionBytes[0] == 1 || subscriptionBytes[0] == 0) { // the rest of the bytes is the token, convert them to string string serializedToken = Encoding.ASCII.GetString( subscriptionBytes, 1, subscriptionBytes.Length - 1); // deserialize the token Token token; if (Token.TryDeserialize(serializedToken, out token)) { // Check if the token is valid if (token.Validate(Key)) { // first byte indicate if it a subscription or unsubscription if (subscriptionBytes[0] == 1) { Console.WriteLine("Subscription request {0}", token.Subscription); publisher.Subscribe(token.Subscription); } else { publisher.Unsubscribe(token.Subscription); } } else { Console.WriteLine("Invalid token {0}", serializedToken); } } } }; // Some fake publishing NetMQTimer publishTimer = new NetMQTimer(100); publishTimer.Elapsed += (sender, eventArgs) => { publisher. SendMore(symbols[random.Next(symbols.Length)]). Send(random.Next().ToString()); }; Poller poller = new Poller(); poller.AddSocket(publisher); poller.AddTimer(publishTimer); poller.PollTillCancelled(); } } }
public void AddSocketAfterRemovingTest() { using (NetMQContext contex = NetMQContext.Create()) { // we are using three responses to make sure we actually //move the correct socket and other sockets still work using (var router = contex.CreateRouterSocket()) using (var router2 = contex.CreateRouterSocket()) using (var router3 = contex.CreateRouterSocket()) { router.Bind("tcp://127.0.0.1:5002"); router2.Bind("tcp://127.0.0.1:5003"); router3.Bind("tcp://127.0.0.1:5004"); using (var dealer = contex.CreateDealerSocket()) using (var dealer2 = contex.CreateDealerSocket()) using (var dealer3 = contex.CreateDealerSocket()) using (Poller poller = new Poller()) { dealer.Connect("tcp://127.0.0.1:5002"); dealer2.Connect("tcp://127.0.0.1:5003"); dealer3.Connect("tcp://127.0.0.1:5004"); bool router1arrived = false; bool router2arrived = false; bool router3arrived = false; bool more; //The ReceiveReady event is raised by the Poller router.ReceiveReady += (s, a) => { router1arrived = true; router.Receive(out more); router.Receive(out more); poller.RemoveSocket(router); }; poller.AddSocket(router); //The ReceiveReady event is raised by the Poller router3.ReceiveReady += (s, a) => { router3.Receive(out more); router3.Receive(out more); router3arrived = true; }; //The ReceiveReady event is raised by the Poller router2.ReceiveReady += (s, a) => { router2arrived = true; router2.Receive(out more); router2.Receive(out more); poller.AddSocket(router3); }; poller.AddSocket(router2); Task task = Task.Factory.StartNew(poller.Start); dealer.Send("1"); Thread.Sleep(300); dealer2.Send("2"); Thread.Sleep(300); dealer3.Send("3"); Thread.Sleep(300); poller.Stop(true); task.Wait(); Assert.IsTrue(router1arrived); Assert.IsTrue(router2arrived); Assert.IsTrue(router3arrived); } } } }
public void CancelSocketTest() { using (NetMQContext contex = NetMQContext.Create()) { // we are using three responses to make sure we actually //move the correct socket and other sockets still work using (var router = contex.CreateRouterSocket()) using (var router2 = contex.CreateRouterSocket()) using (var router3 = contex.CreateRouterSocket()) { router.Bind("tcp://127.0.0.1:5002"); router2.Bind("tcp://127.0.0.1:5003"); router3.Bind("tcp://127.0.0.1:5004"); using (var dealer = contex.CreateDealerSocket()) using (var dealer2 = contex.CreateDealerSocket()) using (var dealer3 = contex.CreateDealerSocket()) using (Poller poller = new Poller()) { dealer.Connect("tcp://127.0.0.1:5002"); dealer2.Connect("tcp://127.0.0.1:5003"); dealer3.Connect("tcp://127.0.0.1:5004"); bool first = true; //The ReceiveReady event is raised by the Poller router2.ReceiveReady += (s, a) => { bool more; // identity byte[] identity = a.Socket.Receive(out more); // message a.Socket.Receive(out more); a.Socket.SendMore(identity); a.Socket.Send("2"); }; poller.AddSocket(router2); //The ReceiveReady event is raised by the Poller router.ReceiveReady += (s, a) => { if (!first) { Assert.Fail("This should happen because we cancelled the socket"); } first = false; bool more; // identity a.Socket.Receive(out more); string m = a.Socket.ReceiveString(out more); Assert.False(more); Assert.AreEqual("Hello", m); // cancelling the socket poller.RemoveSocket(a.Socket); }; poller.AddSocket(router); //The ReceiveReady event is raised by the Poller router3.ReceiveReady += (s, a) => { bool more; // identity byte[] identity = a.Socket.Receive(out more); // message a.Socket.Receive(out more); a.Socket.SendMore(identity).Send("3"); }; poller.AddSocket(router3); Task pollerTask = Task.Factory.StartNew(poller.Start); dealer.Send("Hello"); // sending this should not arrive on the poller, //therefore response for this will never arrive dealer.Send("Hello2"); Thread.Sleep(100); // sending this should not arrive on the poller, //therefore response for this will never arrive dealer.Send("Hello3"); Thread.Sleep(500); bool more2; // making sure the socket defined before the one cancelled still works dealer2.Send("1"); string msg = dealer2.ReceiveString(out more2); Assert.AreEqual("2", msg); // making sure the socket defined after the one cancelled still works dealer3.Send("1"); msg = dealer3.ReceiveString(out more2); Assert.AreEqual("3", msg); // we have to give this some time if we want to make sure //it's really not happening and it not only because of time Thread.Sleep(300); poller.Stop(); Thread.Sleep(100); Assert.IsTrue(pollerTask.IsCompleted); } } } }
public void Receive_RequestWithWrongFirstFrame_ShouldThrowApplicationException() { const string hostAddress = "tcp://localhost:5555"; // setup the counter socket for communication using (var context = NetMQContext.Create ()) using (var broker = context.CreateRouterSocket ()) using (var poller = new Poller ()) using (var session = new MDPWorker (hostAddress, "test")) { broker.Bind (hostAddress); // we need to pick up any message in order to avoid errors broker.ReceiveReady += (s, e) => { var msg = e.Socket.ReceiveMultipartMessage (); // we expect to receive a 5 Frame message // [WORKER ADR][EMPTY]["MDPW01"]["READY"]["test"] if (msg.FrameCount != 5) Assert.Fail ("Message with wrong count of frames {0}", msg.FrameCount); // make sure the frames are as expected Assert.That (msg[1], Is.EqualTo (NetMQFrame.Empty)); Assert.That (msg[2].ConvertToString (), Is.EqualTo ("MDPW01")); Assert.That (msg[3].BufferSize, Is.EqualTo (1)); Assert.That (msg[3].Buffer[0], Is.EqualTo ((byte) MDPCommand.Ready)); Assert.That (msg[4].ConvertToString (), Is.EqualTo ("test")); // tell worker to stop gracefully var reply = new NetMQMessage (); reply.Push (new[] { (byte) MDPCommand.Kill }); // push MDP Version reply.Push ("MDPW01"); // push separator reply.Push ("Should be empty"); // push worker address reply.Push (msg[0]); // send reply which is a request for the worker e.Socket.SendMessage (reply); }; poller.AddSocket (broker); Task.Factory.StartNew (poller.PollTillCancelled); try { session.Receive (null); } catch (ApplicationException ex) { Assert.That (ex.Message, Is.EqualTo ("First frame must be an empty frame!")); } poller.CancelAndJoin (); poller.RemoveSocket (broker); } }
public void Send_WrongServiceNameWithLogging_ShouldLogPermanentError() { const string hostAddress = "tcp://localhost:5555"; var loggingMessages = new List<string>(); // setup the counter socket for communication using (var context = NetMQContext.Create()) using (var broker = context.CreateRouterSocket()) using (var poller = new Poller()) using (var session = new MDPClient(hostAddress)) { broker.Bind(hostAddress); // we need to pick up any message in order to avoid errors broker.ReceiveReady += (s, e) => { // just swallow message -> wrong service name e.Socket.ReceiveMessage(); }; poller.AddSocket(broker); Task.Factory.StartNew(poller.PollTillCancelled); // set the event handler to receive the logging messages session.LogInfoReady += (s, e) => loggingMessages.Add(e.Info); // well formed message var requestMessage = new NetMQMessage(new[] { new NetMQFrame("REQUEST") }); // wrong service name session.Send("xyz", requestMessage); poller.CancelAndJoin(); poller.RemoveSocket(broker); Assert.That(loggingMessages.Count, Is.EqualTo(7)); Assert.That(loggingMessages[6], Is.EqualTo("[CLIENT ERROR] permanent error, abandoning!")); } }
public void Send_WrongMDPVersionFromBrokerNoLogging_ShouldThrowApplicationException() { const string hostAddress = "tcp://localhost:5555"; // setup the counter socket for communication using (var context = NetMQContext.Create()) using (var broker = context.CreateRouterSocket()) using (var poller = new Poller()) using (var session = new MDPClient(hostAddress)) { broker.Bind(hostAddress); // we need to pick up any message in order to avoid errors broker.ReceiveReady += (s, e) => { // return empty reply var msg = e.Socket.ReceiveMessage(); // we expect to receive a 4 Frame message // [REQ ADR][EMPTY]["MDPC01"]["echo"]["REQUEST"] if (msg.FrameCount != 5) Assert.Fail("Message with wrong count of frames {0}", msg.FrameCount); // REQUEST socket will strip the his address + empty frame // ROUTER has to add the address prelude in order to identify the correct socket(!) // [REQ ADR][EMPTY]["MDPC00"]["echo"]["REQUEST"] var clientAddress = msg.Pop(); msg.Pop(); // forget empty frame msg.Pop(); // drop the MDP Version Frame msg.Push("MDPC00"); // insert wrong MDP version msg.Push(NetMQFrame.Empty); msg.Push(clientAddress); // reinsert the client's address e.Socket.SendMessage(msg); }; poller.AddSocket(broker); Task.Factory.StartNew(poller.PollTillCancelled); // well formed message var requestMessage = new NetMQMessage(new[] { new NetMQFrame("REQUEST") }); try { session.Send("echo", requestMessage); } catch (ApplicationException ex) { Assert.That(ex.Message, Is.StringContaining("MDP Version mismatch")); } poller.CancelAndJoin(); poller.RemoveSocket(broker); } }
public void AddTwoSocketAfterRemovingTest() { using (NetMQContext contex = NetMQContext.Create()) { // we are using three responses to make sure we actually //move the correct socket and other sockets still work using (var router = contex.CreateRouterSocket()) using (var router2 = contex.CreateRouterSocket()) using (var router3 = contex.CreateRouterSocket()) using (var router4 = contex.CreateRouterSocket()) { router.Bind("tcp://127.0.0.1:5002"); router2.Bind("tcp://127.0.0.1:5003"); router3.Bind("tcp://127.0.0.1:5004"); router4.Bind("tcp://127.0.0.1:5005"); using (var dealer = contex.CreateDealerSocket()) using (var dealer2 = contex.CreateDealerSocket()) using (var dealer3 = contex.CreateDealerSocket()) using (var dealer4 = contex.CreateDealerSocket()) using (Poller poller = new Poller()) { dealer.Connect("tcp://127.0.0.1:5002"); dealer2.Connect("tcp://127.0.0.1:5003"); dealer3.Connect("tcp://127.0.0.1:5004"); dealer4.Connect("tcp://127.0.0.1:5005"); int router1arrived = 0; int router2arrived = 0; bool router3arrived = false; bool router4arrived = false; bool more; //The ReceiveReady event is raised by the Poller router.ReceiveReady += (s, a) => { router1arrived++; router.Receive(out more); router.Receive(out more); poller.RemoveSocket(router); }; poller.AddSocket(router); //The ReceiveReady event is raised by the Poller router3.ReceiveReady += (s, a) => { router3.Receive(out more); router3.Receive(out more); router3arrived = true; }; //The ReceiveReady event is raised by the Poller router4.ReceiveReady += (s, a) => { router4.Receive(out more); router4.Receive(out more); router4arrived = true; }; //The ReceiveReady event is raised by the Poller router2.ReceiveReady += (s, a) => { router2arrived++; router2.Receive(out more); router2.Receive(out more); if (router2arrived == 1) { poller.AddSocket(router3); poller.AddSocket(router4); } }; poller.AddSocket(router2); Task task = Task.Factory.StartNew(poller.Start); dealer.Send("1"); Thread.Sleep(300); dealer2.Send("2"); Thread.Sleep(300); dealer3.Send("3"); dealer4.Send("4"); dealer2.Send("2"); dealer.Send("1"); Thread.Sleep(300); poller.Stop(true); task.Wait(); router.Receive(true, out more); Assert.IsTrue(more); router.Receive(true, out more); Assert.IsFalse(more); Assert.AreEqual(1, router1arrived); Assert.AreEqual(2, router2arrived); Assert.IsTrue(router3arrived); Assert.IsTrue(router4arrived); } } } }
public void Run() { //NOTES //1. Use many threads each writing to ConcurrentQueue //2. Extra thread to read from ConcurrentQueue, and this is the one that // will deal with writing to the server ConcurrentQueue<string> messages = new ConcurrentQueue<string>(); int delay = 3000; Poller poller = new Poller(); using (NetMQContext ctx = NetMQContext.Create()) { using (var server = ctx.CreateRouterSocket()) { server.Bind("tcp://127.0.0.1:5556"); //start some threads, where each thread, will use a client side //broker (simple thread that monitors a CooncurrentQueue), where //ONLY the client side broker talks to the server for (int i = 0; i < 3; i++) { Task.Factory.StartNew((state) => { while (true) { messages.Enqueue(state.ToString()); Thread.Sleep(delay); } }, string.Format("client {0}", i), TaskCreationOptions.LongRunning); } //single sender loop Task.Factory.StartNew((state) => { var client = ctx.CreateDealerSocket(); client.Connect("tcp://127.0.0.1:5556"); client.ReceiveReady += Client_ReceiveReady; poller.AddSocket(client); while (true) { string clientMessage = null; if (messages.TryDequeue(out clientMessage)) { var messageToServer = new NetMQMessage(); messageToServer.AppendEmptyFrame(); messageToServer.Append(clientMessage); client.SendMessage(messageToServer); } } }, TaskCreationOptions.LongRunning); //start the poller Task task = Task.Factory.StartNew(poller.Start); //server loop while (true) { var clientMessage = server.ReceiveMessage(); Console.WriteLine("========================"); Console.WriteLine(" INCOMING CLIENT MESSAGE "); Console.WriteLine("========================"); for (int i = 0; i < clientMessage.FrameCount; i++) { Console.WriteLine("Frame[{0}] = {1}", i, clientMessage[i].ConvertToString()); } if (clientMessage.FrameCount == 3) { var clientAddress = clientMessage[0]; var clientOriginalMessage = clientMessage[2].ConvertToString(); string response = string.Format("{0} back from server {1}", clientOriginalMessage, DateTime.Now.ToLongTimeString()); var messageToClient = new NetMQMessage(); messageToClient.Append(clientAddress); messageToClient.AppendEmptyFrame(); messageToClient.Append(response); server.SendMessage(messageToClient); } } } } }
public void AddSocketDuringWorkTest() { using (NetMQContext contex = NetMQContext.Create()) { // we are using three responses to make sure we actually //move the correct socket and other sockets still work using (var router = contex.CreateRouterSocket()) using (var router2 = contex.CreateRouterSocket()) { router.Bind("tcp://127.0.0.1:5002"); router2.Bind("tcp://127.0.0.1:5003"); using (var dealer = contex.CreateDealerSocket()) using (var dealer2 = contex.CreateDealerSocket()) using (Poller poller = new Poller()) { dealer.Connect("tcp://127.0.0.1:5002"); dealer2.Connect("tcp://127.0.0.1:5003"); bool router1arrived = false; bool router2arrived = false; bool more; //The ReceiveReady event is raised by the Poller router2.ReceiveReady += (s, a) => { router2.Receive(out more); router2.Receive(out more); router2arrived = true; }; //The ReceiveReady event is raised by the Poller router.ReceiveReady += (s, a) => { router1arrived = true; router.Receive(out more); router.Receive(out more); poller.AddSocket(router2); }; poller.AddSocket(router); Task task = Task.Factory.StartNew(poller.Start); dealer.Send("1"); Thread.Sleep(300); dealer2.Send("2"); Thread.Sleep(300); poller.Stop(true); task.Wait(); Assert.IsTrue(router1arrived); Assert.IsTrue(router2arrived); } } } }
public void Receive_REPLYtoREQUEST_ShouldSendCorrectReply() { const string host_address = "tcp://localhost:5557"; var loggingMessages = new List <string> (); // setup the counter socket for communication using (var ctx = NetMQContext.Create()) using (var broker = ctx.CreateRouterSocket()) using (var poller = new NetMQ.Poller()) using (var session = new MDPWorker(host_address, "test", new[] { (byte)'W', (byte)'1' })) { broker.Bind(host_address); // we need to pick up any message in order to avoid errors broker.ReceiveReady += (s, e) => { var msg = e.Socket.ReceiveMessage(); if (msg[3].Buffer[0] == (byte)MDPCommand.Ready) { // this is a READY message and we // send REQUEST message var request = new NetMQMessage(); request.Push("echo test"); // [request] request.Push(NetMQFrame.Empty); // [e][request] request.Push("C1"); // [client adr][e][request] request.Push(new[] { (byte)MDPCommand.Request }); // [command][client adr][e][request] request.Push(msg[2]); // [header][command][client adr][e][request] request.Push(NetMQFrame.Empty); // [e][header][command][client adr][e][request] request.Push(msg[0]); // [worker adr][e][header][command][client adr][e][request] // send reply which is a request for the worker e.Socket.SendMessage(request); } if (msg[3].Buffer[0] == (byte)MDPCommand.Reply) { // we expect to receive // [WORKER ADR][e]["MDPW01"][REPLY][CLIENT ADR][e][request == "echo test"] // make sure the frames are as expected Assert.That(msg[0].ConvertToString(), Is.EqualTo("W1")); Assert.That(msg[1], Is.EqualTo(NetMQFrame.Empty)); Assert.That(msg[2].ConvertToString(), Is.EqualTo("MDPW01")); Assert.That(msg[3].BufferSize, Is.EqualTo(1)); Assert.That(msg[3].Buffer[0], Is.EqualTo((byte)MDPCommand.Reply)); Assert.That(msg[4].ConvertToString(), Is.EqualTo("C1")); Assert.That(msg[5], Is.EqualTo(NetMQFrame.Empty)); Assert.That(msg[6].ConvertToString(), Is.EqualTo("echo test")); // tell worker to stop gracefully var reply = new NetMQMessage(); reply.Push(new[] { (byte)MDPCommand.Kill }); // push MDP Version reply.Push(msg[2]); // push separator reply.Push(NetMQFrame.Empty); // push worker address reply.Push(msg[0]); // send reply which is a request for the worker e.Socket.SendMessage(reply); } }; poller.AddSocket(broker); var t = Task.Factory.StartNew(() => poller.Start()); // set the event handler to receive the logging messages session.LogInfoReady += (s, e) => loggingMessages.Add(e.Info); // initialize the worker - broker protocol // and get initial request var workerRequest = session.Receive(null); // just echo the request session.Receive(workerRequest); poller.Stop(); poller.RemoveSocket(broker); Assert.That(loggingMessages.Count, Is.EqualTo(8)); Assert.That(loggingMessages[0], Is.EqualTo("[WORKER] connected to broker at tcp://localhost:5557")); Assert.That(loggingMessages[1].Contains("Ready")); Assert.That(loggingMessages[2].Contains("[WORKER] received")); Assert.That(loggingMessages[3].Contains("Request")); Assert.That(loggingMessages[4].Contains("Reply")); Assert.That(loggingMessages[6].Contains("Kill")); Assert.That(loggingMessages[7].Contains("abandoning")); } }
public void Receive_REPLYtoREQUEST_ShouldSendCorrectReply() { const string hostAddress = "tcp://localhost:5557"; var loggingMessages = new List<string> (); // setup the counter socket for communication using (var context = NetMQContext.Create ()) using (var broker = context.CreateRouterSocket ()) using (var poller = new Poller ()) using (var session = new MDPWorker (hostAddress, "test", new[] { (byte) 'W', (byte) '1' })) { broker.Bind (hostAddress); // we need to pick up any message in order to avoid errors broker.ReceiveReady += (s, e) => { var msg = e.Socket.ReceiveMultipartMessage (); if (msg[3].Buffer[0] == (byte) MDPCommand.Ready) { // this is a READY message and we // send REQUEST message var request = new NetMQMessage (); request.Push ("echo test"); // [request] request.Push (NetMQFrame.Empty); // [e][request] request.Push ("C1"); // [client adr][e][request] request.Push (new[] { (byte) MDPCommand.Request }); // [command][client adr][e][request] request.Push (msg[2]); // [header][command][client adr][e][request] request.Push (NetMQFrame.Empty); // [e][header][command][client adr][e][request] request.Push (msg[0]); // [worker adr][e][header][command][client adr][e][request] // send reply which is a request for the worker e.Socket.SendMessage (request); } if (msg[3].Buffer[0] == (byte) MDPCommand.Reply) { // we expect to receive // [WORKER ADR][e]["MDPW01"][REPLY][CLIENT ADR][e][request == "echo test"] // make sure the frames are as expected Assert.That (msg[0].ConvertToString (), Is.EqualTo ("W1")); Assert.That (msg[1], Is.EqualTo (NetMQFrame.Empty)); Assert.That (msg[2].ConvertToString (), Is.EqualTo ("MDPW01")); Assert.That (msg[3].BufferSize, Is.EqualTo (1)); Assert.That (msg[3].Buffer[0], Is.EqualTo ((byte) MDPCommand.Reply)); Assert.That (msg[4].ConvertToString (), Is.EqualTo ("C1")); Assert.That (msg[5], Is.EqualTo (NetMQFrame.Empty)); Assert.That (msg[6].ConvertToString (), Is.EqualTo ("echo test")); // tell worker to stop gracefully var reply = new NetMQMessage (); reply.Push (new[] { (byte) MDPCommand.Kill }); // push MDP Version reply.Push (msg[2]); // push separator reply.Push (NetMQFrame.Empty); // push worker address reply.Push (msg[0]); // send reply which is a request for the worker e.Socket.SendMessage (reply); } }; poller.AddSocket (broker); Task.Factory.StartNew (poller.PollTillCancelled); // set the event handler to receive the logging messages session.LogInfoReady += (s, e) => loggingMessages.Add (e.Info); // initialise the worker - broker protocol // and get initial request var workerRequest = session.Receive (null); // just echo the request session.Receive (workerRequest); poller.CancelAndJoin (); poller.RemoveSocket (broker); Assert.That (loggingMessages.Count, Is.EqualTo (8)); Assert.That (loggingMessages[0], Is.EqualTo ("[WORKER] connected to broker at tcp://localhost:5557")); Assert.That (loggingMessages[1].Contains ("Ready")); Assert.That (loggingMessages[2].Contains ("[WORKER] received")); Assert.That (loggingMessages[3].Contains ("Request")); Assert.That (loggingMessages[4].Contains ("Reply")); Assert.That (loggingMessages[6].Contains ("Kill")); Assert.That (loggingMessages[7].Contains ("abandoning")); } }
public void Receive_RequestWithWrongMDPComand_ShouldLogCorrectMessage() { const string hostAddress = "tcp://localhost:5555"; var loggingMessages = new List<string> (); var first = true; // setup the counter socket for communication using (var context = NetMQContext.Create ()) using (var broker = context.CreateRouterSocket ()) using (var poller = new Poller ()) using (var session = new MDPWorker (hostAddress, "test", Encoding.ASCII.GetBytes ("Worker"), 2)) { broker.Bind (hostAddress); // we need to pick up any message in order to avoid errors broker.ReceiveReady += (s, e) => { var msg = e.Socket.ReceiveMultipartMessage (); // we expect to receive a 5 Frame message // [WORKER ADR][EMPTY]["MDPW01"]["READY"]["test"] if (msg.FrameCount != 5) return; // it is a HEARTBEAT // make sure the frames are as expected Assert.That (msg[1], Is.EqualTo (NetMQFrame.Empty)); Assert.That (msg[2].ConvertToString (), Is.EqualTo ("MDPW01")); Assert.That (msg[3].BufferSize, Is.EqualTo (1)); Assert.That (msg[3].Buffer[0], Is.EqualTo ((byte) MDPCommand.Ready)); Assert.That (msg[4].ConvertToString (), Is.EqualTo ("test")); // tell worker to stop gracefully var reply = new NetMQMessage (); if (first) { reply.Push (new[] { (byte) 0xff }); first = false; } else reply.Push (new[] { (byte) MDPCommand.Kill }); // push MDP Version reply.Push ("MDPW01"); // push separator reply.Push (NetMQFrame.Empty); // push worker address reply.Push (msg[0]); // send reply which is a request for the worker e.Socket.SendMessage (reply); }; // set the event handler to receive the logging messages session.LogInfoReady += (s, e) => loggingMessages.Add (e.Info); poller.AddSocket (broker); Task.Factory.StartNew (poller.PollTillCancelled); session.HeartbeatDelay = TimeSpan.FromMilliseconds (250); session.ReconnectDelay = TimeSpan.FromMilliseconds (250); // initialise the worker - broker protocol session.Receive (null); Assert.That (loggingMessages.Count (m => m.Contains ("[WORKER ERROR] invalid command received")), Is.EqualTo (1)); Assert.That (loggingMessages.Count (m => m.Contains ("abandoning")), Is.EqualTo (1)); poller.CancelAndJoin (); poller.RemoveSocket (broker); } }
public void Run() { //NOTES //1. Use ThreadLocal<DealerSocket> where each thread has // its own client DealerSocket to talk to server //2. Each thread can send using it own socket //3. Each thread socket is added to poller ThreadLocal<DealerSocket> clientSocketPerThread = new ThreadLocal<DealerSocket>(); int delay = 3000; Poller poller = new Poller(); using (NetMQContext ctx = NetMQContext.Create()) { using (var server = ctx.CreateRouterSocket()) { server.Bind("tcp://127.0.0.1:5556"); //start some threads, each with its own DealerSocket //to talk to the server socket. Creates lots of sockets, //but no nasty race conditions no shared state, each //thread has its own socket, happy days for (int i = 0; i < 3; i++) { Task.Factory.StartNew((state) => { DealerSocket client = null; if (!clientSocketPerThread.IsValueCreated) { client = ctx.CreateDealerSocket(); client.Connect("tcp://127.0.0.1:5556"); client.ReceiveReady += Client_ReceiveReady; clientSocketPerThread.Value = client; poller.AddSocket(client); } else { client = clientSocketPerThread.Value; } while (true) { var messageToServer = new NetMQMessage(); messageToServer.AppendEmptyFrame(); messageToServer.Append(state.ToString()); client.SendMessage(messageToServer); Thread.Sleep(delay); } },string.Format("client {0}", i), TaskCreationOptions.LongRunning); } //start the poller Task task = Task.Factory.StartNew(poller.Start); //server loop while (true) { var clientMessage = server.ReceiveMessage(); Console.WriteLine("========================"); Console.WriteLine(" INCOMING CLIENT MESSAGE "); Console.WriteLine("========================"); for (int i = 0; i < clientMessage.FrameCount; i++) { Console.WriteLine("Frame[{0}] = {1}", i, clientMessage[i].ConvertToString()); } if (clientMessage.FrameCount == 3) { var clientAddress = clientMessage[0]; var clientOriginalMessage = clientMessage[2].ConvertToString(); string response = string.Format("{0} back from server {1}", clientOriginalMessage, DateTime.Now.ToLongTimeString()); var messageToClient = new NetMQMessage(); messageToClient.Append(clientAddress); messageToClient.AppendEmptyFrame(); messageToClient.Append(response); server.SendMessage(messageToClient); } } } } }
public void Send_EmptyReplyFromBrokerWithLogging_ShouldThrowApplicationException() { const string hostAddress = "tcp://localhost:5555"; var loggingMessages = new List<string>(); // setup the counter socket for communication using (var context = NetMQContext.Create()) using (var broker = context.CreateRouterSocket()) using (var poller = new Poller()) using (var session = new MDPClient(hostAddress)) { broker.Bind(hostAddress); // we need to pick up any message in order to avoid errors broker.ReceiveReady += (s, e) => { // return empty reply var msg = e.Socket.ReceiveMessage(); // we expect to receive a 4 Frame message // [REQ ADR][EMPTY]["MDPC01"]["echo"]["REQUEST"] if (msg.FrameCount != 5) Assert.Fail("Message with wrong count of frames {0}", msg.FrameCount); // REQUEST socket will strip the his address + empty frame // ROUTER has to add the address prelude in order to identify the correct socket(!) // [REQ ADR][EMPTY]["MDPC01"]["echo"]["REQUEST"] e.Socket.SendMessage(msg); }; poller.AddSocket(broker); Task.Factory.StartNew(poller.PollTillCancelled); // set the event handler to receive the logging messages session.LogInfoReady += (s, e) => loggingMessages.Add(e.Info); // well formed message var requestMessage = new NetMQMessage(new[] { new NetMQFrame("REQUEST") }); // correct call session.Send("echo", requestMessage); poller.CancelAndJoin(); poller.RemoveSocket(broker); Assert.That(loggingMessages.Count, Is.EqualTo(3)); Assert.That(loggingMessages[0], Is.EqualTo("[CLIENT] connecting to broker at tcp://localhost:5555")); Assert.That(loggingMessages[1].Contains("[CLIENT INFO] sending"), Is.True); Assert.That(loggingMessages[2].Contains("[CLIENT INFO] received"), Is.True); } }
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> /// Tries to connect to the QDMS server. /// </summary> public void Connect() { Dispose(); _context = NetMQContext.Create(); _reqSocket = _context.CreateDealerSocket(); _subSocket = _context.CreateSubscriberSocket(); _dealerSocket = _context.CreateSocket(ZmqSocketType.Dealer); _reqSocket.Options.Identity = Encoding.UTF8.GetBytes(_name); _subSocket.Options.Identity = Encoding.UTF8.GetBytes(_name); _dealerSocket.Options.Identity = Encoding.UTF8.GetBytes(_name); _dealerSocket.ReceiveReady += _dealerSocket_ReceiveReady; _reqSocket.ReceiveReady += _reqSocket_ReceiveReady; _subSocket.ReceiveReady += _subSocket_ReceiveReady; _reqSocket.Connect(string.Format("tcp://{0}:{1}", _host, _realTimeRequestPort)); //start off by sending a ping to make sure everything is regular string reply = ""; try { _reqSocket.SendMore(""); _reqSocket.Send("PING"); _reqSocket.ReceiveString(TimeSpan.FromSeconds(1)); //empty frame starts the REP message //todo receive string? reply = _reqSocket.ReceiveString(TimeSpan.FromMilliseconds(50)); } catch { Dispose(); } if (reply != "PONG") //server didn't reply or replied incorrectly { _reqSocket.Disconnect(string.Format("tcp://{0}:{1}", _host, _realTimeRequestPort)); _reqSocket.Close(); { RaiseEvent(Error, this, new ErrorArgs(-1, "Could not connect to server.")); return; } } _lastHeartBeat = DateTime.Now; _subSocket.Connect(string.Format("tcp://{0}:{1}", _host, _realTimePublishPort)); _dealerSocket.Connect(string.Format("tcp://{0}:{1}", _host, _historicalDataPort)); _running = true; //this loop sends out historical data requests and receives the data _dealerLoopThread = new Thread(DealerLoop) { Name = "Client Dealer Loop" }; _dealerLoopThread.Start(); //this loop takes care of replies to the request socket: heartbeats and data request status messages _poller = new Poller(); _poller.AddSocket(_reqSocket); _poller.AddSocket(_subSocket); _poller.AddSocket(_dealerSocket); Task.Factory.StartNew(_poller.Start, TaskCreationOptions.LongRunning); _heartBeatTimer = new Timer(1000); _heartBeatTimer.Elapsed += _timer_Elapsed; _heartBeatTimer.Start(); }
public void Receive_RequestWithWrongMDPComand_ShouldLogCorrectMessage() { const string host_address = "tcp://localhost:5555"; var loggingMessages = new List <string> (); var first = true; // setup the counter socket for communication using (var ctx = NetMQContext.Create()) using (var broker = ctx.CreateRouterSocket()) using (var poller = new NetMQ.Poller()) using (var session = new MDPWorker(host_address, "test", Encoding.ASCII.GetBytes("Worker"), 2)) { broker.Bind(host_address); // we need to pick up any message in order to avoid errors broker.ReceiveReady += (s, e) => { var msg = e.Socket.ReceiveMessage(); // we expect to receive a 5 Frame mesage // [WORKER ADR][EMPTY]["MDPW01"]["READY"]["test"] if (msg.FrameCount != 5) { return; // it is a HEARTBEAT } // make sure the frames are as expected Assert.That(msg[1], Is.EqualTo(NetMQFrame.Empty)); Assert.That(msg[2].ConvertToString(), Is.EqualTo("MDPW01")); Assert.That(msg[3].BufferSize, Is.EqualTo(1)); Assert.That(msg[3].Buffer[0], Is.EqualTo((byte)MDPCommand.Ready)); Assert.That(msg[4].ConvertToString(), Is.EqualTo("test")); // tell worker to stop gracefully var reply = new NetMQMessage(); if (first) { reply.Push(new[] { (byte)0xff }); first = false; } else { reply.Push(new[] { (byte)MDPCommand.Kill }); } // push MDP Version reply.Push("MDPW01"); // push separator reply.Push(NetMQFrame.Empty); // push worker address reply.Push(msg[0]); // send reply which is a request for the worker e.Socket.SendMessage(reply); }; // set the event handler to receive the logging messages session.LogInfoReady += (s, e) => loggingMessages.Add(e.Info); poller.AddSocket(broker); var t = Task.Factory.StartNew(() => poller.Start()); session.HeartbeatDelay = TimeSpan.FromMilliseconds(250); session.ReconnectDelay = TimeSpan.FromMilliseconds(250); // initialize the worker - broker protocol session.Receive(null); Assert.That(loggingMessages.Count(m => m.Contains("[WORKER ERROR] invalid command received")), Is.EqualTo(1)); Assert.That(loggingMessages.Count(m => m.Contains("abandoning")), Is.EqualTo(1)); poller.Stop(); poller.RemoveSocket(broker); } }