public void HandleMessage(Message message, RouterSocket serverSocket, PublisherSocket ioPub) { Message replyMessage = new Message(MessageType.KernelInfoReply, CreateKernelInfoReply(), message.Header); _logger.LogInformation("Sending kernel_info_reply"); serverSocket.SendMessage(replyMessage); }
public void StartAndStopStateValidation() { using (var front = new RouterSocket()) using (var back = new DealerSocket()) { front.Bind("inproc://frontend"); back.Bind("inproc://backend"); var proxy = new Proxy(front, back); Task.Factory.StartNew(proxy.Start); // Send a message through to ensure the proxy has started using (var client = new RequestSocket()) using (var server = new ResponseSocket()) { client.Connect("inproc://frontend"); server.Connect("inproc://backend"); client.SendFrame("hello"); Assert.AreEqual("hello", server.ReceiveFrameString()); server.SendFrame("reply"); Assert.AreEqual("reply", client.ReceiveFrameString()); } Assert.Throws <InvalidOperationException>(proxy.Start); Assert.Throws <InvalidOperationException>(proxy.Start); Assert.Throws <InvalidOperationException>(proxy.Start); proxy.Stop(); // blocks until stopped Assert.Throws <InvalidOperationException>(proxy.Stop); } }
public void Send_WrongServiceNameWithLogging_ShouldLogPermanentError() { const string hostAddress = "tcp://localhost:5555"; var loggingMessages = new List <string>(); // setup the counter socket for communication using (var broker = new RouterSocket()) using (var poller = new NetMQPoller()) 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.ReceiveMultipartMessage(); }; poller.Add(broker); poller.RunAsync(); // 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(); Assert.That(loggingMessages.Count, Is.EqualTo(7)); Assert.That(loggingMessages[6], Is.EqualTo("[CLIENT ERROR] permanent error, abandoning!")); } }
/// <summary> /// Router模式,会自动路由到Controler /// </summary> public void ThreadMQRouterReceive() { try { using (RouterSocket routerSocket = new RouterSocket()) { routerSocket.Bind(MQConfig.RouterReceiveServer); while (!_cancellationTokenSource.IsCancellationRequested) { try { IdKeyData receiveData = routerSocket.RouterReceive(); Task.Factory.StartNew(() => { RouteConfig.Instance.ExecCmd(receiveData.Id, receiveData.Key, receiveData.Data); }); } catch (TerminatingException) { } catch (Exception ex) { MQThreadExceptionHandler?.Invoke(ex); } } } } catch (Exception ex) { MQThreadExceptionHandler?.Invoke(ex); } }
public Shell( ICommandScheduler <JupyterRequestContext> scheduler, ConnectionInformation connectionInformation) { if (connectionInformation == null) { throw new ArgumentNullException(nameof(connectionInformation)); } _scheduler = scheduler ?? throw new ArgumentNullException(nameof(scheduler)); _shellAddress = $"{connectionInformation.Transport}://{connectionInformation.IP}:{connectionInformation.ShellPort}"; _ioPubAddress = $"{connectionInformation.Transport}://{connectionInformation.IP}:{connectionInformation.IOPubPort}"; _stdInAddress = $"{connectionInformation.Transport}://{connectionInformation.IP}:{connectionInformation.StdinPort}"; _controlAddress = $"{connectionInformation.Transport}://{connectionInformation.IP}:{connectionInformation.ControlPort}"; var signatureAlgorithm = connectionInformation.SignatureScheme.Replace("-", string.Empty).ToUpperInvariant(); _signatureValidator = new SignatureValidator(connectionInformation.Key, signatureAlgorithm); _shell = new RouterSocket(); _ioPubSocket = new PublisherSocket(); _stdIn = new RouterSocket(); _control = new RouterSocket(); _shellSender = new MessageSender(_shell, _signatureValidator); _ioPubSender = new MessageSender(_ioPubSocket, _signatureValidator); _disposables = new CompositeDisposable { _shell, _ioPubSocket, _stdIn, _control }; }
public Swarm( PrivateKey privateKey, Uri listenUrl, TimeSpan?dialTimeout = null, DateTime?createdAt = null) { _privateKey = privateKey; _listenUrl = listenUrl; _dialTimeout = dialTimeout ?? TimeSpan.FromMilliseconds(15000); _peers = new Dictionary <Peer, DateTime>(); _removedPeers = new Dictionary <Peer, DateTime>(); LastSeenTimestamps = new Dictionary <Peer, DateTime>(); DateTime now = createdAt.GetValueOrDefault(DateTime.UtcNow); LastDistributed = now; LastReceived = now; DeltaDistributed = new AsyncManualResetEvent(); DeltaReceived = new AsyncManualResetEvent(); TxReceived = new AsyncAutoResetEvent(); _dealers = new Dictionary <Address, DealerSocket>(); _router = new RouterSocket(); _deltas = new NetMQQueue <PeerSetDelta>(); _distributeMutex = new AsyncLock(); _receiveMutex = new AsyncLock(); _logger = Log.ForContext <Swarm>() .ForContext("Swarm_listenUrl", _listenUrl.ToString()); _contextInitialized = false; }
public void RawSocket() { using (var router = new RouterSocket()) using (var clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) { router.Options.RouterRawSocket = true; var port = router.BindRandomPort("tcp://127.0.0.1"); clientSocket.Connect("127.0.0.1", port); clientSocket.NoDelay = true; byte[] clientMessage = Encoding.ASCII.GetBytes("HelloRaw"); int bytesSent = clientSocket.Send(clientMessage); Assert.Greater(bytesSent, 0); byte[] id = router.ReceiveFrameBytes(); byte[] message = router.ReceiveFrameBytes(); router.SendMoreFrame(id).SendMoreFrame(message); // SendMore option is ignored var buffer = new byte[16]; int bytesRead = clientSocket.Receive(buffer); Assert.Greater(bytesRead, 0); Assert.AreEqual(Encoding.ASCII.GetString(buffer, 0, bytesRead), "HelloRaw"); } }
static void RunServer(CancellationToken cancellationToken) { Task.Factory.StartNew(() => { var random = new Random(); using (var server = new RouterSocket()) { server.Bind("tcp://*:5555"); Console.WriteLine("\t\t\tServer: Bound to *:5555"); while (!cancellationToken.IsCancellationRequested) { var request = server.ReceiveMultipartMessage(); var message = request[2].ConvertToString(); Console.WriteLine($"\t\t\tServer: Received {message}"); // Simulate work Thread.Sleep(200); var responsestr = $"World {random.Next(100)}"; Console.WriteLine($"\t\t\tServer: Sending {responsestr}"); var response = new NetMQMessage(); response.Append(request[0]); response.AppendEmptyFrame(); response.Append(responsestr); response.AppendEmptyFrame(); server.SendMultipartMessage(response); } } }); }
public void ReconnectOnRouterBug() { { using (var dealer = new DealerSocket()) { dealer.Options.Identity = Encoding.ASCII.GetBytes("dealer"); dealer.Bind("tcp://localhost:6667"); using (var router = new RouterSocket()) { router.Options.RouterMandatory = true; router.Connect("tcp://localhost:6667"); Thread.Sleep(100); router.SendMoreFrame("dealer").SendFrame("Hello"); var message = dealer.ReceiveFrameString(); Assert.That(message == "Hello"); router.Disconnect("tcp://localhost:6667"); Thread.Sleep(1000); router.Connect("tcp://localhost:6667"); Thread.Sleep(100); router.SendMoreFrame("dealer").SendFrame("Hello"); message = dealer.ReceiveFrameString(); Assert.That(message == "Hello"); } } } }
public void HasInTest() { using (var server = new RouterSocket()) using (var client = new DealerSocket()) { var port = server.BindRandomPort("tcp://*"); // no one sent a message so it should be false Assert.IsFalse(server.HasIn); client.Connect("tcp://localhost:" + port); // wait for the client to connect Thread.Sleep(100); // now we have one client connected but didn't send a message yet Assert.IsFalse(server.HasIn); client.SendFrame("1"); // wait for the message to arrive Thread.Sleep(100); // the has in should indicate a message is ready Assert.IsTrue(server.HasIn); server.SkipFrame(); // identity string message = server.ReceiveFrameString(); Assert.AreEqual(message, "1"); // we read the message, it should false again Assert.IsFalse(server.HasIn); } }
public void HandleMessage(Message message, RouterSocket shellSocket, PublisherSocket ioPubSocket) { var executeRequest = JsonSerializer.Deserialize <ExecuteRequest>(message.Content); Log.Info($"Execute Request received with code {executeRequest.Code}"); // Kernel sends a "status: busy" message on IOPub SendMessageToIoPub(message, ioPubSocket, StatusValues.Busy); // Kernel SendInputMessageToIoPub(message, ioPubSocket, executeRequest.Code); // 3: Evaluate the C# code var result = InteractiveShell.ExecuteCode(executeRequest.Code); // 4: Send execute reply to shell socket SendExecuteReplyMessage(message, shellSocket); // 5: Send execute result message to IOPub SendOutputMessageToIoPub(message, ioPubSocket, result); // 6: Send IDLE status message to IOPub SendMessageToIoPub(message, ioPubSocket, StatusValues.Idle); _executionCount += 1; }
public void Start() { using (_toGateway = new DealerSocket()) { _toGateway.Options.Identity = _id.ToByteArray(); _toGateway.Connect(_gatewayEndpoint); using (_toWorkers = new RouterSocket()) { _toWorkers.Options.Identity = _id.ToByteArray(); _toWorkers.Bind(_clusterEndpoint); using (_workPoller = new NetMQPoller { _toGateway, _toWorkers }) { _toGateway.ReceiveReady += (s, e) => { var transportMessage = e.Socket.ReceiveMultipartMessage() .GetMessageFromDealer <Work>(); var work = transportMessage.Message; if (work.Status == WorkerStatus.Ask) { _works.Add(work); } }; _toWorkers.ReceiveReady += (s, e) => { var transportMessage = e.Socket.ReceiveMultipartMessage() .GetMessageFromRouter <Work>(); var work = transportMessage.Message; if (work.Status == WorkerStatus.Ready) { _workers.Enqueue(new Guid(transportMessage.SenderId)); } else if (work.Status == WorkerStatus.Finished) { _toGateway.SendFrame(transportMessage.MessageBytes); _workers.Enqueue(new Guid(transportMessage.SenderId)); } _resetEvent.Set(); }; //register to the gateway router... _toGateway.SendFrame(Work.Ready.Serialize()); //...then start state publish _statePublishProc = Task.Run(StatePublish).ConfigureAwait(false); _workPoller.Run(); } } } }
private void SendPublicKey(byte[] requester, RouterSocket router) { var response = ResponseCreator.Create(new NoEncryption(), requester, MessageType.SendPublicKey, JsonConvert.SerializeObject(_decryptor.PublicKey)); router.SendMultipartMessage(response); }
public void SendWrongMDPVersionFromBrokerNoLoggingShouldThrowApplicationException() { const string hostAddress = "tcp://localhost:5555"; // setup the counter socket for communication using (var broker = new RouterSocket()) using (var poller = new NetMQPoller()) using (var session = new MDPClientAsync(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.ReceiveMultipartMessage(); // 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.SendMultipartMessage(msg); }; int timeOutInMillis = 10000; var timer = new NetMQTimer(timeOutInMillis); // Used so it doesn't block if something goes wrong! timer.Elapsed += (s, e) => { Assert.Fail($"Waited {timeOutInMillis} and had no response from broker"); poller.Stop(); }; poller.Add(broker); poller.Add(timer); session.ReplyReady += (s, e) => { Assert.True(e.HasError()); Assert.That(e.Exception.Message, Is.StringContaining("MDP Version mismatch")); poller.Stop(); // To unlock the Task.Wait() }; var task = Task.Factory.StartNew(() => poller.Run()); var requestMessage = new NetMQMessage(new[] { new NetMQFrame("REQUEST") }); session.Send("echo", requestMessage); task.Wait(); } }
// We have two workers, here we copy the code, normally these would run on different boxes… public static void Main() { var random = new Random(DateTime.Now.Millisecond); var workers = new List<Thread>(new[] { new Thread(WorkerTaskA), new Thread(WorkerTaskB) }); using (var client = new RouterSocket()) { client.Bind($"tcp://localhost:{PortNumber}"); foreach (var thread in workers) { thread.Start(PortNumber); } // Wait for threads to connect, since otherwise the messages we send won't be routable. Thread.Sleep(1000); for (int taskNumber = 0; taskNumber < 1000; taskNumber++) { // Send two message parts, first the address… client.SendMoreFrame(random.Next(3) > 0 ? Encoding.Unicode.GetBytes("A") : Encoding.Unicode.GetBytes("B")); // And then the workload client.SendFrame("This is the workload"); } client.SendMoreFrame(Encoding.Unicode.GetBytes("A")); client.SendFrame("END"); client.SendMoreFrame(Encoding.Unicode.GetBytes("B")); client.SendFrame("END"); } Console.ReadKey(); }
private void HeartBeatDirectories() { _heartbeatSocket = new RouterSocket(DirectoryHeartbeatEnpoint); while (!_cancel.IsCancellationRequested) { foreach (var producer in _stateOfTheWorld) { using (var heartbeatQuery = new RequestSocket(producer.Value.HeartbeatEndpoint)) { var heartbeatQueryMessage = new HeartbeatQuery() { HeartbeatEndpoint = DirectoryHeartbeatEnpoint }; var msg = Encoding.UTF32.GetBytes(JsonConvert.SerializeObject(heartbeatQueryMessage)); heartbeatQuery.SendFrame(msg); Thread.Sleep(HeartbeatDelay); var heartbeatMessage = new NetMQMessage(); if (_heartbeatSocket.TryReceiveMultipartMessage(ref heartbeatMessage)) { producer.Value.State = ProducerState.Alive; } else { producer.Value.State = ProducerState.NotResponding; } } } } }
private void ClusterSate() { using (_clusterState = new RouterSocket()) { _clusterState.Bind(_clusterStateEndpoint); _clusterState.ReceiveReady += (s, e) => { var state = e.Socket.ReceiveMultipartMessage() .GetMessageFromDealer <ClusterState>(); _clustersState.AddOrUpdate(new Guid(state.SenderId), state.Message, (key, value) => { return(value); }); _resetEvent.Set(); }; using (_clusterStatePoller = new NetMQPoller { _clusterState }) { _clusterStatePoller.Run(); } } }
public Control(int port, NetMQContext context) { this.port = port; this.context = context; this.server = this.context.CreateRouterSocket(); }
private void ListenerWork() { AsyncIO.ForceDotNet.Force(); using (var server = new RouterSocket()) { server.Bind("tcp://*:5555"); while (!_listenerCancelled) { //server.SkipFrame(); // to skip identity string identity; if (!server.TryReceiveFrameString(out identity)) { continue; } //UnityEngine.Debug.LogFormat ("identity {0}", identity); string message; if (!server.TryReceiveFrameString(out message)) { continue; } //UnityEngine.Debug.LogFormat ("message {0}", message); //server.SendMoreFrame(identity).SendFrame("message"); Request request = new Request(server, identity, message); _requestQueue.Enqueue(request); } } NetMQConfig.Cleanup(); }
public Control(int port, NetMQContext context) { this.port = port; this.context = context; this.server = this.context.CreateRouterSocket(); }
public Server() { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("SpeechLab server is starting up..."); try { server = new RouterSocket(address); } catch (NetMQException e) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("SpeechLab server could not start."); Console.WriteLine("Another instance of the server is already running or the IP address is in use by other application.\n" + "Check if IP address is correct. Current: " + address + "\n\n" + "Full exception message:"); Console.WriteLine(e.Message); Console.WriteLine("\nPress any key to stop the server..."); Console.ReadKey(); Environment.Exit(2); } recognizer = new SpeechRecognizer(); parser = new SpeechParser(); Console.WriteLine("SpeechLab server started."); Console.ForegroundColor = ConsoleColor.White; }
private void HandleHeartbeat() { _heartbeatSocket = new RouterSocket(_producerConfiguration.HeartbeatEnpoint); while (!_cancel.IsCancellationRequested) { var message = _heartbeatSocket.ReceiveMultipartMessage(); var messageBytes = message[2].Buffer; var heartbeat = JsonConvert.DeserializeObject <HeartbeatQuery>(Encoding.UTF32.GetString(messageBytes), _settings); using (var sender = new RequestSocket(heartbeat.HeartbeatEndpoint)) { var heartbeatResponse = new HeartbeatResponse() { ProducerId = _producerConfiguration.Id, Now = DateTime.Now }; var msg = Encoding.UTF32.GetBytes(JsonConvert.SerializeObject(heartbeatResponse, _settings)); sender.SendFrame(msg); Task.Delay(200).Wait(); } } }
private async Task HandleStateOfTheWorldRequest() { using (_stateRequestSocket = new RouterSocket()) { _stateRequestSocket.Bind(_configuration.StateOftheWorldEndpoint); while (!_cancel.IsCancellationRequested) { var message = _stateRequestSocket.ReceiveMultipartMessage(); var sender = message[0].Buffer; var request = _serializer.Deserialize <IStateRequest>(message[1].Buffer); var stream = await _cache.GetStreamBySubject(request.Subject); var response = new StateReply() { Subject = request.Subject, Events = stream.ToList() }; _stateRequestSocket.SendMoreFrame(sender) .SendFrame(_serializer.Serialize(response)); } } }
public void Receive_BrokerDisconnectedWithLogging_ShouldReturnRequest() { const string hostAddress = "tcp://localhost:5555"; var loggingMessages = new List <string> (); // setup the counter socket for communication using (var broker = new RouterSocket()) using (var poller = new NetMQPoller()) 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.Add(broker); poller.RunAsync(); // 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.Stop(); 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 static void Main() { using (var frontend = new RouterSocket("@tcp://127.0.0.1:5559")) using (var backend = new DealerSocket("@tcp://127.0.0.1:5560")) { // Handler for messages coming in to the frontend frontend.ReceiveReady += (s, e) => { var msg = e.Socket.ReceiveMultipartMessage(); backend.SendMultipartMessage(msg); // Relay this message to the backend }; // Handler for messages coming in to the backend backend.ReceiveReady += (s, e) => { var msg = e.Socket.ReceiveMultipartMessage(); frontend.SendMultipartMessage(msg); // Relay this message to the frontend }; using (var poller = new NetMQPoller { backend, frontend }) { // Listen out for events on both sockets and raise events when messages come in poller.Run(); } } }
public void ThreadMQRouterSend() { try { using (RouterSocket routerSocket = new RouterSocket()) { routerSocket.Bind(MQConfig.RouterSendServer); while (!_cancellationTokenSource.IsCancellationRequested) { try { IdKeyData item; if (MQRouterSendQueue.TryTake(out item)) { routerSocket.RouterSend(item); } } catch (TerminatingException) { } catch (Exception ex) { MQThreadExceptionHandler?.Invoke(ex); } } } } catch (Exception ex) { MQThreadExceptionHandler?.Invoke(ex); } }
public Kernel(ConnectionInformation connectionInformation) { this.connectionInformation = connectionInformation; // heartbeat hbSocket = new RouterSocket(); hbSocket.Bind($"{connectionInformation.transport}://{connectionInformation.ip}:{connectionInformation.hb_port}"); // control controlSocket = new RouterSocket(); controlSocket.Bind($"{connectionInformation.transport}://{connectionInformation.ip}:{connectionInformation.control_port}"); // stdin stdinSocket = new RouterSocket(); stdinSocket.Bind($"{connectionInformation.transport}://{connectionInformation.ip}:{connectionInformation.stdin_port}"); // iopub ioSocket = new PublisherSocket(); ioSocket.Bind($"{connectionInformation.transport}://{connectionInformation.ip}:{connectionInformation.iopub_port}"); // shell shellSocket = new RouterSocket(); shellSocket.Bind($"{connectionInformation.transport}://{connectionInformation.ip}:{connectionInformation.shell_port}"); payload = new List <Payload>(); nugetManager = new NuGetManager(new FileInfo(".").FullName); executionCount = 0; lastMessage = null; headerCode = getHeaderCode(); hmac = new HMACSHA256(Encoding.UTF8.GetBytes(connectionInformation.key)); }
public void SendAndReceive() { using (var front = new RouterSocket()) using (var back = new DealerSocket()) { front.Bind("inproc://frontend"); back.Bind("inproc://backend"); var proxy = new Proxy(front, back); Task.Factory.StartNew(proxy.Start); using (var client = new RequestSocket()) using (var server = new ResponseSocket()) { client.Connect("inproc://frontend"); server.Connect("inproc://backend"); client.SendFrame("hello"); Assert.AreEqual("hello", server.ReceiveFrameString()); server.SendFrame("reply"); Assert.AreEqual("reply", client.ReceiveFrameString()); } proxy.Stop(); } }
public void Receive() { async Task ReceiveAsync() { using (var server = new RouterSocket("inproc://async")) using (var client = new DealerSocket("inproc://async")) { client.SendFrame("Hello"); var(routingKey, _) = await server.ReceiveRoutingKeyAsync(); var(message, _) = await server.ReceiveFrameStringAsync(); Assert.Equal(message, "Hello"); server.SendMoreFrame(routingKey); server.SendFrame(new[] { (byte)0 }); var(bytes, _) = await client.ReceiveFrameBytesAsync(); Assert.Equal(bytes[0], 0); } } using (var runtime = new NetMQRuntime()) { runtime.Run(ReceiveAsync()); } }
public void RequestResponseMultipartMessageWithRetryFails() { const string address = "tcp://127.0.0.1:50002"; const string pubAddress = "tcp://127.0.0.1:60002"; const int numTries = 5; var requestTimeout = TimeSpan.FromMilliseconds(100); var requestMessage = new NetMQMessage(1); requestMessage.Append("Hi"); using (var progressPublisher = new PublisherSocket(pubAddress)) using (var progressSubscriber = new SubscriberSocket(pubAddress)) using (var server = new RouterSocket(address)) { progressSubscriber.SubscribeToAnyTopic(); var progressProactor = new NetMQProactor(progressSubscriber, (socket, message) => Console.WriteLine("C: {0} {1:ss.fff}", message[0].ConvertToString(), DateTime.Now)); var serverProactor = new NetMQProactor(server, (socket, message) => { Console.WriteLine("ResponseEcho recieved message {0} at {1:ss.fff}", message[2].ConvertToString(), DateTime.Now); }); using (serverProactor) using (progressProactor) { var responseMessage = RequestSocket.RequestResponseMultipartMessageWithRetry(address, requestMessage, numTries, requestTimeout, progressPublisher); Assert.IsNull(responseMessage); } } }
public void RouterDealerMessaging() { using (var server = new RouterSocket()) using (var client = new DealerSocket()) { int port = server.BindRandomPort("tcp://127.0.0.1"); client.Connect("tcp://127.0.0.1:" + port); var clientOutgoingMessage = new NetMQMessage(); clientOutgoingMessage.Append("Hello"); client.SendMultipartMessage(clientOutgoingMessage); NetMQMessage serverIncomingMessage = server.ReceiveMultipartMessage(); // number of frames should be one because first message should be identity of client Assert.Equal(2, serverIncomingMessage.FrameCount); Assert.Equal("Hello", serverIncomingMessage[1].ConvertToString()); var serverOutgoingMessage = new NetMQMessage(); // first adding the identity serverOutgoingMessage.Append(serverIncomingMessage[0]); serverOutgoingMessage.Append("World"); server.SendMultipartMessage(serverOutgoingMessage); var incomingClientMessage = client.ReceiveMultipartMessage(); Assert.Equal(1, incomingClientMessage.FrameCount); Assert.Equal("World", incomingClientMessage[0].ConvertToString()); } }
private static void Main() { using (var frontend = new RouterSocket("@tcp://127.0.0.1:5559")) using (var backend = new DealerSocket("@tcp://127.0.0.1:5560")) { // Handler for messages coming in to the frontend frontend.ReceiveReady += (s, e) => { var msg = e.Socket.ReceiveMultipartMessage(); backend.SendMultipartMessage(msg); // Relay this message to the backend }; // Handler for messages coming in to the backend backend.ReceiveReady += (s, e) => { var msg = e.Socket.ReceiveMultipartMessage(); frontend.SendMultipartMessage(msg); // Relay this message to the frontend }; using (var poller = new NetMQPoller {backend, frontend}) { // Listen out for events on both sockets and raise events when messages come in poller.Run(); } } }
// We have two workers, here we copy the code, normally these would run on different boxes… public static void Main() { var random = new Random(DateTime.Now.Millisecond); var workers = new List <Thread>(new[] { new Thread(WorkerTaskA), new Thread(WorkerTaskB) }); using (var client = new RouterSocket()) { client.Bind(string.Format("tcp://localhost:{0}", PortNumber)); foreach (var thread in workers) { thread.Start(PortNumber); } // Wait for threads to connect, since otherwise the messages we send won't be routable. Thread.Sleep(1000); for (int taskNumber = 0; taskNumber < 1000; taskNumber++) { // Send two message parts, first the address… client.SendMoreFrame(random.Next(3) > 0 ? Encoding.Unicode.GetBytes("A") : Encoding.Unicode.GetBytes("B")); // And then the workload client.SendFrame("This is the workload"); } client.SendMoreFrame(Encoding.Unicode.GetBytes("A")); client.SendFrame("END"); client.SendMoreFrame(Encoding.Unicode.GetBytes("B")); client.SendFrame("END"); } Console.ReadKey(); }
public void MessageTest() { Action<Codec> setMessage = m => { m.Id = Codec.MessageId.Message; m.Message.MessageId = 123; m.Message.RelatedMessageId = 123; m.Message.Service = "Life is short but Now lasts for ever"; m.Message.Subject = "Life is short but Now lasts for ever"; m.Message.Body = Encoding.ASCII.GetBytes("Captcha Diem"); m.Message.OneWay = 123; m.Message.ConnectionId = 123; }; Action<Codec> checkMessage = m=> { Assert.That(m.Id, Is.EqualTo(Codec.MessageId.Message)); Assert.That(m.Message.MessageId, Is.EqualTo(123)); Assert.That(m.Message.RelatedMessageId, Is.EqualTo(123)); Assert.That(m.Message.Service, Is.EqualTo("Life is short but Now lasts for ever")); Assert.That(m.Message.Subject, Is.EqualTo("Life is short but Now lasts for ever")); Assert.That(m.Message.Body, Is.EqualTo(Encoding.ASCII.GetBytes("Captcha Diem"))); Assert.That(m.Message.OneWay, Is.EqualTo(123)); Assert.That(m.Message.ConnectionId, Is.EqualTo(123)); }; using (var client = new DealerSocket("inproc://zprototest")) using (var server = new RouterSocket("inproc://zprototest")) { Codec clientMessage = new Codec(); Codec serverMessage = new Codec(); for (int i=0; i < 2; i++) { // client send message to server setMessage(clientMessage); clientMessage.Send(client); // server receive the message serverMessage.Receive(server); // check that message received ok Assert.That(serverMessage.RoutingId, Is.Not.Null); checkMessage(serverMessage); // reply to client, no need to set the message, using client data serverMessage.Send(server); // client receive the message clientMessage.Receive(client); // check that message received ok Assert.That(clientMessage.RoutingId, Is.Null); checkMessage(clientMessage); } } }
public static void Main() { var workers = new List<Thread>(WorkersCount); using (var client = new RouterSocket()) { string cnn = $"tcp://localhost:{PortNumber}"; client.Bind(cnn); Console.WriteLine("[B] Connect to {0}", cnn); for (int workerNumber = 0; workerNumber < WorkersCount; workerNumber++) { workers.Add(new Thread(WorkerTask)); workers[workerNumber].Start(PortNumber); } for (int taskNumber = 0; taskNumber < WorkersCount*10; taskNumber++) { // LRU worker is next waiting in queue string address = client.ReceiveFrameString(); //Console.WriteLine("[B] Message received: {0}", address); string empty = client.ReceiveFrameString(); //Console.WriteLine("[B] Message received: {0}", empty); string ready = client.ReceiveFrameString(); //Console.WriteLine("[B] Message received: {0}", ready); client.SendMoreFrame(address); //Console.WriteLine("[B] Message sent: {0}", address); client.SendMoreFrame(""); //Console.WriteLine("[B] Message sent: {0}", ""); client.SendFrame("This is the workload"); //Console.WriteLine("[B] Message sent: {0}", "This is the workload"); } // Now ask mamas to shut down and report their results for (int taskNbr = 0; taskNbr < WorkersCount; taskNbr++) { string address = client.ReceiveFrameString(); //Console.WriteLine("[B] Message received: {0}", address); string empty = client.ReceiveFrameString(); //Console.WriteLine("[B] Message received: {0}", empty); string ready = client.ReceiveFrameString(); //Console.WriteLine("[B] Message received: {0}", ready); client.SendMoreFrame(address); //Console.WriteLine("[B] Message sent: {0}", address); client.SendMoreFrame(""); //Console.WriteLine("[B] Message sent: {0}", ""); client.SendFrame("END"); //Console.WriteLine("[B] Message sent: {0}", "END"); } } Console.ReadLine(); }
public void ReceiveImplicitConnect_ValidScenario_ShouldReturnRequest () { const string hostAddress = "tcp://localhost:5557"; var loggingMessages = new List<string> (); // setup the counter socket for communication using (var broker = new RouterSocket ()) using (var poller = new NetMQPoller ()) 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.SendMultipartMessage (reply); }; poller.Add (broker); poller.RunAsync (); // 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); 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")); } }
/// <summary> /// Initializes an instance of NetMQReceiver with the specified ResponseSocket and binary ISerializer /// </summary> /// <param name="routerSocket">NetMQ ResponseSocket</param> /// <param name="binarySerializer">Binary Serializer</param> public NetMQReceiver(RouterSocket routerSocket, ISerializer<byte[]> binarySerializer) { if (routerSocket == null) throw new ArgumentNullException("ResponseSocket"); if (binarySerializer == null) throw new ArgumentNullException("ISerializer<byte[]>"); this.routerSocket = routerSocket; this.binarySerializer = binarySerializer; }
public Shell(ILog logger,string addressShell, string addressIOPub, NetMQContext context, Dictionary<string, IShellMessageHandler> messageHandlers) { this.logger = logger; this.addressShell = addressShell; this.addressIOPub = addressIOPub; this.context = context; this.messageHandlers = messageHandlers; this.server = this.context.CreateRouterSocket(); this.ioPubSocket = this.context.CreatePublisherSocket(); this.stopEvent = new ManualResetEventSlim(); }
public void Send_CorrectInputWithLogging_ShouldReturnCorrectReply() { const string hostAddress = "tcp://localhost:5555"; var loggingMessages = new List<string>(); // setup the counter socket for communication using (var broker = new RouterSocket()) using (var poller = new NetMQPoller()) 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.ReceiveMultipartMessage(); // 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.SendMultipartMessage(msg); }; poller.Add(broker); poller.RunAsync(); // 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(); 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); } }
void IShimHandler.Run(PairSocket shim) { _pipe = shim; _pipe.SignalOK(); _pipe.ReceiveReady += OnPipeReady; _timer = new NetMQTimer(TimeSpan.FromSeconds(1)); _timer.Elapsed += OnPingPeer; _inbox = _context.CreateRouterSocket(); _inbox.ReceiveReady += OnInboxReady; _poller = new Poller(_pipe); _poller.AddTimer(_timer); _poller.PollTillCancelled(); }
public void ReceiveMessageFailedIfWasNotProcessed() { const string hostAddress = "tcp://localhost:5555"; var loggingMessages = new List<string>(); var serviceName = "echo"; Guid requestId = Guid.Empty; using (var broker = new RouterSocket()) using (var poller = new NetMQPoller()) using (var session = new MDPClientAsync(hostAddress)) { broker.Bind(hostAddress); // we need to pick up any message in order to avoid errors broker.ReceiveReady += (s, e) => { // doesn't reply to client var msg = e.Socket.ReceiveMultipartMessage(); }; session.LogInfoReady += (s, e) => loggingMessages.Add(e.Info); session.ReplyReady += (s, e) => { Assert.IsTrue(false, "I'm not supposed to receive replies since broker is not sending them"); poller.Stop(); }; session.FailedRequest += (s, e) => { Assert.That(requestId, Is.Not.EqualTo(Guid.Empty)); Assert.That(e.RequestId, Is.EqualTo(requestId)); poller.Stop(); }; poller.Add(broker); var task = Task.Factory.StartNew(() => poller.Run()); var requestMessage = new NetMQMessage(new[] { new NetMQFrame("REQUEST") }); requestId = session.Send(serviceName, requestMessage); var result = task.Wait(session.Timeout + session.Timeout); Assert.IsTrue(result, $"During {session.Timeout}ms was not received a FailedReply"); } }
static void Main(string[] args) { using (var context = NetMQContext.Create()) { using (frontend = context.CreateRouterSocket()) { using (backend = context.CreateRouterSocket()) { // For Clients Console.WriteLine("Q: Binding frontend {0}", FRONTEND_ENDPOINT); frontend.Bind(FRONTEND_ENDPOINT); // For Workers Console.WriteLine("Q: Binding backend {0}", BACKEND_ENDPOINT); backend.Bind(BACKEND_ENDPOINT); // Logic of LRU loop // - Poll backend always, frontend only if 1+ worker ready // - If worker replies, queue worker as ready and forward reply // to client if necessary // - If client requests, pop next worker and send request to it // Queue of available workers workerQueue = new Queue<byte[]>(); // Handle worker activity on backend backend.ReceiveReady += BackendOnReceiveReady; frontend.ReceiveReady += FrontendOnReceiveReady; while (true) { backend.Poll(TimeSpan.FromMilliseconds(500)); if (workerQueue.Count > 0) frontend.Poll(TimeSpan.FromMilliseconds(500)); } } } } }
public void Send_EmptyReplyFromBrokerWithLogging_ShouldThrowApplicationException() { const string hostAddress = "tcp://localhost:5555"; var loggingMessages = new List<string>(); // setup the counter socket for communication using (var broker = new RouterSocket()) using (var poller = new NetMQPoller()) 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.ReceiveMultipartMessage(); // 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.SendMultipartMessage(msg); }; poller.Add(broker); poller.RunAsync(); // 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(); 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 Receive_BrokerDisconnectedWithLogging_ShouldReturnRequest () { const string hostAddress = "tcp://localhost:5555"; var loggingMessages = new List<string> (); // setup the counter socket for communication using (var broker = new RouterSocket ()) using (var poller = new NetMQPoller ()) 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.Add (broker); poller.RunAsync (); // 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.Stop (); 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 static void Main() { const int messageCount = 1000000; const int dealerCount = 100; Console.WriteLine("Sending {0} messages to {1} dealers", messageCount, dealerCount); //BufferPool.SetBufferManagerBufferPool(1024 * 1024 * 10, 1024); using (var router = new RouterSocket()) { router.Options.SendHighWatermark = 0; router.Bind("tcp://*:5555"); var dealers = new List<DealerSocket>(); var identities = new List<Msg>(); var random = new Random(); var identity = new byte[50]; for (var i = 0; i < dealerCount; i++) { random.NextBytes(identity); var dealer = new DealerSocket { Options = { Identity = identity.Skip(10).ToArray(), ReceiveHighWatermark = 0 } }; dealer.Connect("tcp://localhost:5555"); dealers.Add(dealer); var msg = new Msg(); msg.InitGC(identity, 10, identity.Length); // test offsets identities.Add(msg); } Thread.Sleep(500); while (!Console.KeyAvailable) { Thread.Sleep(500); var stopwatch = Stopwatch.StartNew(); for (var i = 0; i < messageCount; i++) { var msg = identities[i%identities.Count]; router.Send(ref msg, true); var msg2 = new Msg(); msg2.InitPool(1); msg2.Put((byte) 'E'); router.Send(ref msg2, false); } stopwatch.Stop(); Console.WriteLine("{0:N1} messages sent per second", messageCount/stopwatch.Elapsed.TotalSeconds); } foreach (var dealerSocket in dealers) dealerSocket.Dispose(); } }
public void SendCorrectInputWithLoggingShouldReturnCorrectReply() { const string hostAddress = "tcp://localhost:5555"; var loggingMessages = new List<string>(); var serviceName = "echo"; using (var broker = new RouterSocket()) using (var poller = new NetMQPoller()) using (var session = new MDPClientAsync(hostAddress)) { 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 4 Frame message // [client adrR][e][mdp header][service][request] if (msg.FrameCount != 6) 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][requestId] var requestId = msg.Last.ConvertToString(); // get the requestId string msg.RemoveFrame(msg.Last); // remove the request frame 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 msg.Append(requestId); e.Socket.SendMultipartMessage(msg); }; session.LogInfoReady += (s, e) => loggingMessages.Add(e.Info); session.ReplyReady += (s, e) => { var reply = e.Reply; Assert.That(reply.FrameCount, Is.EqualTo(1)); Assert.That(reply.First.ConvertToString(), Is.EqualTo("REQUEST OK")); poller.Stop(); }; int timeOutInMillis = 10000; var timer = new NetMQTimer(timeOutInMillis); // Used so it doesn't block if something goes wrong! timer.Elapsed += (s, e) => { Assert.Fail($"Waited {timeOutInMillis} and had no response from broker"); poller.Stop(); }; poller.Add(broker); poller.Add(timer); var task = Task.Factory.StartNew(() => poller.Run()); var requestMessage = new NetMQMessage(new[] { new NetMQFrame("REQUEST") }); session.Send(serviceName, requestMessage); task.Wait(); 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 ServiceRegisterTest() { Action<Codec> setMessage = m => { m.Id = Codec.MessageId.ServiceRegister; m.ServiceRegister.Service = "Life is short but Now lasts for ever"; }; Action<Codec> checkMessage = m=> { Assert.That(m.Id, Is.EqualTo(Codec.MessageId.ServiceRegister)); Assert.That(m.ServiceRegister.Service, Is.EqualTo("Life is short but Now lasts for ever")); }; using (var client = new DealerSocket("inproc://zprototest")) using (var server = new RouterSocket("inproc://zprototest")) { Codec clientMessage = new Codec(); Codec serverMessage = new Codec(); for (int i=0; i < 2; i++) { // client send message to server setMessage(clientMessage); clientMessage.Send(client); // server receive the message serverMessage.Receive(server); // check that message received ok Assert.That(serverMessage.RoutingId, Is.Not.Null); checkMessage(serverMessage); // reply to client, no need to set the message, using client data serverMessage.Send(server); // client receive the message clientMessage.Receive(client); // check that message received ok Assert.That(clientMessage.RoutingId, Is.Null); checkMessage(clientMessage); } } }
public void ReconnectToBrokerIfIsNotReplying() { const string hostAddress = "tcp://localhost:5555"; const int timeOutToReconnectInMillis = 7500; var loggingMessages = new List<string>(); var serviceName = "echo"; var messagesReceivedOnBroker = 0; // setup the counter socket for communication using (var broker = new RouterSocket()) using (var poller = new NetMQPoller()) using (var session = new MDPClientAsync(hostAddress)) { session.Timeout = TimeSpan.FromMilliseconds(timeOutToReconnectInMillis); broker.Bind(hostAddress); broker.ReceiveReady += (s, e) => { var msg = e.Socket.ReceiveMultipartMessage(); if (messagesReceivedOnBroker != 0) // doesn't respond if is the first message received! { // we expect to receive a 4 Frame message // [client adrR][e][mdp header][service][request] if (msg.FrameCount != 6) 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(!) var requestId = msg.Last.ConvertToString(); // get the requestId string msg.RemoveFrame(msg.Last); // remove the request frame 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 msg.Append(requestId); e.Socket.SendMultipartMessage(msg); } messagesReceivedOnBroker++; }; session.LogInfoReady += (s, e) => loggingMessages.Add(e.Info); session.ReplyReady += (s, e) => { var reply = e.Reply; Assert.That(reply.FrameCount, Is.EqualTo(1)); Assert.That(reply.First.ConvertToString(), Is.EqualTo("REQUEST OK")); poller.Stop(); }; var requestMessage = new NetMQMessage(new[] { new NetMQFrame("REQUEST") }); int timeOutInMillis = timeOutToReconnectInMillis + 3000; // Waits for the timeOut on the client var timer = new NetMQTimer(timeOutInMillis); timer.Elapsed += (s, e) => { session.Send(serviceName, requestMessage); // resends the request after timeout }; poller.Add(timer); poller.Add(broker); var task = Task.Factory.StartNew(() => poller.Run()); session.Send(serviceName, requestMessage); var result = task.Wait(timeOutToReconnectInMillis * 2); var numberOfConnects = loggingMessages.FindAll(x => x.Contains("[CLIENT] connecting to broker")).Count; Assert.IsTrue(numberOfConnects > 1); } }
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 broker = new RouterSocket ()) using (var poller = new NetMQPoller ()) 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.SendMultipartMessage (reply); }; // set the event handler to receive the logging messages session.LogInfoReady += (s, e) => loggingMessages.Add (e.Info); poller.Add (broker); poller.RunAsync (); 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)); } }
public void SendWrongMDPVersionFromBrokerNoLoggingShouldThrowApplicationException() { const string hostAddress = "tcp://localhost:5555"; // setup the counter socket for communication using (var broker = new RouterSocket()) using (var poller = new NetMQPoller()) using (var session = new MDPClientAsync(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.ReceiveMultipartMessage(); // we expect to receive a 4 Frame message // [REQ ADR][EMPTY]["MDPC01"]["echo"]["REQUEST"][requestId] if (msg.FrameCount != 6) 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"][requestId] 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.SendMultipartMessage(msg); }; int timeOutInMillis = 10000; var timer = new NetMQTimer(timeOutInMillis); // Used so it doesn't block if something goes wrong! timer.Elapsed += (s, e) => { Assert.Fail($"Waited {timeOutInMillis} and had no response from broker"); poller.Stop(); }; poller.Add(broker); poller.Add(timer); session.ReplyReady += (s, e) => { Assert.True(e.HasError()); Assert.That(e.Exception.Message, Is.StringContaining("MDP Version mismatch")); poller.Stop(); // To unlock the Task.Wait() }; session.FailedRequest += (s, e) => { Assert.True(e.HasError()); Assert.That(e.Exception.Message, Is.StringContaining("MDP Version mismatch")); poller.Stop(); // To unlock the Task.Wait() }; var task = Task.Factory.StartNew(() => poller.Run()); var requestMessage = new NetMQMessage(new[] { new NetMQFrame("REQUEST") }); session.Send("echo", requestMessage); task.Wait(); } }
private static void Main() { using (var frontend = new RouterSocket()) using (var backend = new RouterSocket()) { // For Clients Console.WriteLine("Q: Binding frontend {0}", FrontendEndpoint); frontend.Bind(FrontendEndpoint); // For Workers Console.WriteLine("Q: Binding backend {0}", BackendEndpoint); backend.Bind(BackendEndpoint); // Logic of LRU loop // - Poll backend always, frontend only if 1+ worker ready // - If worker replies, queue worker as ready and forward reply // to client if necessary // - If client requests, pop next worker and send request to it // Queue of available workers var workerQueue = new Queue<byte[]>(); // Handle worker activity on backend backend.ReceiveReady += (s, e) => { // Queue worker address for LRU routing byte[] workerAddress = e.Socket.ReceiveFrameBytes(); // Use worker address for LRU routing workerQueue.Enqueue(workerAddress); // Second frame is empty e.Socket.SkipFrame(); // Third frame is READY or else a client reply address byte[] clientAddress = e.Socket.ReceiveFrameBytes(); // If client reply, send rest back to frontend // Forward message to client if it's not a READY if (Encoding.Unicode.GetString(clientAddress) != LRUReady) { e.Socket.SkipFrame(); // empty byte[] reply = e.Socket.ReceiveFrameBytes(); frontend.SendMoreFrame(clientAddress); frontend.SendMoreFrame(""); frontend.SendFrame(reply); } }; frontend.ReceiveReady += (s, e) => { // Now get next client request, route to next worker // Dequeue and drop the next worker address // Now get next client request, route to LRU worker // Client request is [address][empty][request] byte[] clientAddr = e.Socket.ReceiveFrameBytes(); e.Socket.SkipFrame(); // empty byte[] request = e.Socket.ReceiveFrameBytes(); try { byte[] deq = workerQueue.Dequeue(); backend.SendMoreFrame(deq); backend.SendMoreFrame(Encoding.Unicode.GetBytes("")); backend.SendMoreFrame(clientAddr); backend.SendMoreFrame(Encoding.Unicode.GetBytes("")); backend.SendFrame(request); } catch (Exception ex) { Console.WriteLine("Q: [FrontendOnReceiveReady] Dequeue exception: {0}", ex.ToString()); } }; while (true) { backend.Poll(TimeSpan.FromMilliseconds(500)); if (workerQueue.Count > 0) frontend.Poll(TimeSpan.FromMilliseconds(500)); } } }
/// <summary> /// ctor initializing all local variables /// <para>DEFAULTS:</para> /// <para>heartbeat interval 2,500ms</para> /// <para>max retries for waiting on heartbeats 3 times</para> /// </summary> private MDPBroker () { Socket = new RouterSocket (); m_services = new List<Service> (); m_knownWorkers = new List<Worker> (); m_heartbeatInterval = TimeSpan.FromMilliseconds (2500); // otherwise the expiry would be 0(!) HeartbeatLiveliness = 3; // so m_heartbeatExpiry = value * m_heartbeatInterval = 7.500 ms m_isBound = false; }
/// <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 frontend = new RouterSocket()) using (var backend = new RouterSocket()) using (var poller = new NetMQPoller()) { 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.SendMultipartMessage(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.SendMultipartMessage(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.SendMultipartMessage(heartbeat); } // restart timer e.Timer.Enable = true; // remove all dead or expired workers workers.Purge(); }; if (verbose) Console.WriteLine("[QUEUE] Start listening!"); poller.Add(frontend); poller.Add(backend); poller.RunAsync(); // hit CRTL+C to stop the while loop while (!exit) Thread.Sleep(100); } }
public void Receive_REPLYtoREQUEST_ShouldSendCorrectReply () { const string hostAddress = "tcp://localhost:5557"; var loggingMessages = new List<string> (); // setup the counter socket for communication using (var broker = new RouterSocket ()) using (var poller = new NetMQPoller ()) 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.SendMultipartMessage (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.SendMultipartMessage (reply); } }; poller.Add (broker); poller.RunAsync (); // 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.Stop (); 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_RequestWithTooLittleFrames_ShouldThrowApplicationException () { const string hostAddress = "tcp://localhost:5555"; // setup the counter socket for communication using (var broker = new RouterSocket ()) using (var poller = new NetMQPoller ()) 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 separator reply.Push (NetMQFrame.Empty); // push worker address reply.Push (msg[0]); // send reply which is a request for the worker e.Socket.SendMultipartMessage (reply); }; poller.Add (broker); poller.RunAsync (); try { session.Receive (null); } catch (ApplicationException ex) { Assert.That (ex.Message, Is.EqualTo ("Malformed request received!")); } } }
public void Send_WrongHeaderFromBrokerNoLogging_ShouldThrowApplicationException() { const string hostAddress = "tcp://localhost:5555"; // setup the counter socket for communication using (var broker = new RouterSocket()) using (var poller = new NetMQPoller()) 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.ReceiveMultipartMessage(); // 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 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.SendMultipartMessage(msg); }; poller.Add(broker); poller.RunAsync(); // 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")); } } }
/// <summary> /// the broker setting up the cluster /// /// /// State 2 ---+ +--- State n /// | | /// +----+----+ /// client 1 ---| | |--- worker 1 /// client 2 ---+---- BROKER 1 ----+--- worker 2 /// : | | | : /// client n ---+ +----+----+ +--- worker n /// | | /// BROKER 2 BROKER n /// /// BROKER 2 and n are not included and must be setup separately /// /// A minimum of two address must be supplied /// </summary> /// <param name="args">[0] = this broker's address /// [1] = 1st peer's address /// : /// [n] = nth peer address</param> /// <remarks> /// since "inproc://" is not working in NetMQ we use "tcp://" /// for each broker we need 5 ports which for this example are /// assigned as follows (in true life it should be configurable whether /// they are ports or tcp/ip addresses) /// /// this brokers address => local frontend binds to tcp://127.0.0.1:5555 /// cloud frontend binds to :5556 /// local backend binds to :5557 /// state backend binds to :5558 /// monitor PULL binds to :5559 /// /// the sockets are connected as follows /// /// this broker's monitor PUSH connects to tcp://127.0.0.1:5559 /// /// (if peer's address and port is tcp://127.0.0.1:5575) /// /// this broker's cloud backend connects to :5576 /// this broker's state frontend connects to :5578 /// /// this scheme is fix in this example /// </remarks> public static void Main(string[] args) { Console.Title = "NetMQ Inter-Broker Router"; const string baseAddress = "tcp://127.0.0.1:"; if (args.Length < 2) { Console.WriteLine("usage: program me peer1 [peer]*"); Console.WriteLine("each broker needs 5 port for his sockets!"); Console.WriteLine("place enough distance between multiple broker addresses!"); Environment.Exit(-1); } // trapping Ctrl+C as exit signal! Console.CancelKeyPress += (s, e) => { e.Cancel = true; s_keepRunning = false; }; // get random generator for later use var rnd = new Random(); // get list for registering the clients var clients = new List<byte[]>(NbrClients); // get a list of peer addresses var peers = new List<byte[]>(); // get all peer addresses - first is this broker! for (var i = 1; i < args.Length; i++) peers.Add(Encoding.UTF8.GetBytes(args[i])); // build this broker's address var me = baseAddress + args[0]; // get the port as integer for later use var myPort = int.Parse(args[0]); Console.WriteLine("[BROKER] The broker can be stopped by using CTRL+C!"); Console.WriteLine("[BROKER] setting up sockets ..."); // set up all the addresses needed in the due course var localFrontendAddress = me; var cloudFrontendAddress = baseAddress + (myPort + 1); var localBackendAddress = baseAddress + (myPort + 2); var stateBackendAddress = baseAddress + (myPort + 3); var monitorAddress = baseAddress + (myPort + 4); // create the context and all the sockets using (var localFrontend = new RouterSocket()) using (var localBackend = new RouterSocket()) using (var cloudFrontend = new RouterSocket()) using (var cloudBackend = new RouterSocket()) using (var stateBackend = new PublisherSocket()) using (var stateFrontend = new SubscriberSocket()) using (var monitor = new PullSocket()) { // give every socket an unique identity, e.g. LocalFrontend[Port] SetIdentities(myPort, localFrontend, cloudFrontend, localBackend, stateBackend, monitor, cloudBackend, stateFrontend); // subscribe to any message on the stateFrontend socket! stateFrontend.Subscribe(""); // bind the serving sockets localFrontend.Bind(localFrontendAddress); cloudFrontend.Bind(cloudFrontendAddress); localBackend.Bind(localBackendAddress); stateBackend.Bind(stateBackendAddress); monitor.Bind(monitorAddress); // connect sockets to peers for (var i = 1; i < args.Length; i++) { // build the cloud back end address var peerPort = int.Parse(args[i]); var address = baseAddress + (peerPort + 1); Console.WriteLine("[BROKER] connect to cloud peer {0}", address); // this cloudBackend connects to all peer cloudFrontends cloudBackend.Connect(address); // build the state front end address address = baseAddress + (peerPort + 3); Console.WriteLine("[BROKER] subscribe to state peer {0}", address); // this stateFrontend to all peer stateBackends stateFrontend.Connect(address); } // setup the local worker queue for LRU and monitor cloud capacity var workerQueue = new Queue<byte[]>(); int previousLocalCapacity = 0; // receive the capacity available from other peer(s) stateFrontend.ReceiveReady += (s, e) => { // the message should contain the available cloud capacity var capacity = e.Socket.ReceiveFrameString(); Debug.Assert(string.IsNullOrWhiteSpace(capacity), "StateFrontend: message was empty!"); int couldCapacity; Debug.Assert(int.TryParse(capacity, out couldCapacity), "StateFrontend: message did not contain a number!"); }; // get the status message and print it monitor.ReceiveReady += (s, e) => { var msg = e.Socket.ReceiveFrameString(); Console.WriteLine("[MONITOR] {0}", msg); }; // all local clients are connecting to this socket // they send a REQ and get a REPLY localFrontend.ReceiveReady += (s, e) => { // [client adr][empty][message id] var request = e.Socket.ReceiveMultipartMessage(); // register the local client for later identification if not known if (!clients.Any(n => AreSame(n, request[0]))) clients.Add(request[0].Buffer); // if we have local capacity send worker else send to cloud if (workerQueue.Count > 0) { // get the LRU worker adr var worker = workerQueue.Dequeue(); // wrap message with workers address var msg = Wrap(worker, request); // send message to the worker // [worker adr][empty][client adr][empty][data] localBackend.SendMultipartMessage(msg); } else { // get an random index for peers var peerIdx = rnd.Next(peers.Count - 2) + 2; // get peers address var peer = peers[peerIdx]; // wrap message with peer's address var msg = Wrap(peer, request); // [peer adr][empty][client adr][empty][data] cloudBackend.SendMultipartMessage(msg); } }; // the workers are connected to this socket // we get a REPLY either for a cloud client [worker adr][empty][peer adr][empty][peer client adr][empty][data] // or local client [worker adr][empty][client adr][empty][data] // or a READY message [worker adr][empty][WORKER_READY] localBackend.ReceiveReady += (s, e) => { // a worker can send "READY" or a request // or an REPLAY var msg = e.Socket.ReceiveMultipartMessage(); // just to make sure we received a proper message Debug.Assert(msg != null && msg.FrameCount > 0, "[LocalBackend] message was empty or frame count == 0!"); // get the workers identity var id = Unwrap(msg); // this worker done in either way so add it to available workers workerQueue.Enqueue(id); // if it is NOT a ready message we need to route the message // it could be a reply to a peer or a local client // [WORKER_READY] or [client adr][empty][data] or [peer adr][empty][peer client adr][empty][data] if (msg[0].Buffer[0] != WorkerReady) { Debug.Assert(msg.FrameCount > 2, "[LocalBackend] None READY message malformed"); // if the adr (first frame) is any of the clients send the REPLY there // and send it to the peer otherwise if (clients.Any(n => AreSame(n, msg.First))) localFrontend.SendMultipartMessage(msg); else cloudFrontend.SendMultipartMessage(msg); } }; // this socket is connected to all peers // we receive either a REQ or a REPLY form a peer // REQ [peer adr][empty][peer client adr][empty][message id] -> send to peer for processing // REP [peer adr][empty][client adr][empty][message id] -> send to local client cloudBackend.ReceiveReady += (s, e) => { var msg = e.Socket.ReceiveMultipartMessage(); // just to make sure we received a message Debug.Assert(msg != null && msg.FrameCount > 0, "[CloudBackend] message was empty or frame count == 0!"); // we need the peers address for proper addressing var peerAdr = Unwrap(msg); // the remaining message must be at least 3 frames! Debug.Assert(msg.FrameCount > 2, "[CloudBackend] message malformed"); // if the id is any of the local clients it is a REPLY // and a REQ otherwise if (clients.Any(n => AreSame(n, msg.First))) { // [client adr][empty][message id] localFrontend.SendMultipartMessage(msg); } else { // add the peers address to the request var request = Wrap(peerAdr, msg); // [peer adr][empty][peer client adr][empty][message id] cloudFrontend.SendMultipartMessage(request); } }; // all peers are binding to this socket // we receive REPLY or REQ from peers // REQ [peer adr][empty][peer client adr][empty][data] -> send to local worker for processing // REP [peer adr][empty][client adr][empty][data] -> send to local client cloudFrontend.ReceiveReady += (s, e) => { var msg = e.Socket.ReceiveMultipartMessage(); // just to make sure we received a message Debug.Assert(msg != null && msg.FrameCount > 0, "[CloudFrontend] message was empty or frame count == 0!"); // we may need the peers address for proper addressing var peerAdr = Unwrap(msg); // the remaining message must be at least 3 frames! Debug.Assert(msg.FrameCount > 2, "[CloudFrontend] message malformed"); // if the address is any of the local clients it is a REPLY // and a REQ otherwise if (clients.Any(n => AreSame(n, msg.First))) localFrontend.SendMultipartMessage(msg); else { // in order to know which per to send back the peers adr must be added again var original = Wrap(peerAdr, msg); // reduce the capacity to reflect the use of a worker by a cloud request previousLocalCapacity = workerQueue.Count; // get the LRU worker var workerAdr = workerQueue.Dequeue(); // wrap the message with the worker address and send var request = Wrap(workerAdr, original); localBackend.SendMultipartMessage(request); } }; // in order to reduce chatter we only check to see if we have local capacity to provide to cloud // periodically every 2 seconds with a timer var timer = new NetMQTimer((int)TimeSpan.FromSeconds(2).TotalMilliseconds); timer.Elapsed += (t, e) => { // send message only if the previous send information changed if (previousLocalCapacity != workerQueue.Count) { // set the information previousLocalCapacity = workerQueue.Count; // generate the message var msg = new NetMQMessage(); var data = new NetMQFrame(previousLocalCapacity.ToString()); msg.Append(data); var stateMessage = Wrap(Encoding.UTF8.GetBytes(me), msg); // publish info stateBackend.SendMultipartMessage(stateMessage); } // restart the timer e.Timer.Enable = true; }; // start all clients and workers as threads var clientTasks = new Thread[NbrClients]; var workerTasks = new Thread[NbrWorker]; for (var i = 0; i < NbrClients; i++) { var client = new Client(localFrontendAddress, monitorAddress, (byte)i); clientTasks[i] = new Thread(client.Run) { Name = string.Format("Client_{0}", i) }; clientTasks[i].Start(); } for (var i = 0; i < NbrWorker; i++) { var worker = new Worker(localBackendAddress, (byte)i); workerTasks[i] = new Thread(worker.Run) { Name = string.Format("Worker_{0}", i) }; workerTasks[i].Start(); } // create poller and add sockets & timer var poller = new NetMQPoller { localFrontend, localBackend, cloudFrontend, cloudBackend, stateFrontend, stateBackend, monitor, timer }; // start monitoring the sockets poller.RunAsync(); // we wait for a CTRL+C to exit while (s_keepRunning) Thread.Sleep(100); Console.WriteLine("Ctrl-C encountered! Exiting the program!"); if (poller.IsRunning) poller.Stop(); poller.Dispose(); } }
/// <summary> /// sets unique identities for all sockets /// </summary> private static void SetIdentities( int myPort, RouterSocket localFrontend, RouterSocket cloudFrontend, RouterSocket localBackend, PublisherSocket stateBackend, PullSocket monitor, RouterSocket cloudBackend, SubscriberSocket stateFrontend) { localFrontend.Options.Identity = Encoding.UTF8.GetBytes("LocalFrontend[" + myPort + "]"); cloudFrontend.Options.Identity = Encoding.UTF8.GetBytes("CloudFrontend[" + (myPort + 1) + "]"); localBackend.Options.Identity = Encoding.UTF8.GetBytes("LocalBackend[" + (myPort + 2) + "]"); stateBackend.Options.Identity = Encoding.UTF8.GetBytes("StateBackend[" + (myPort + 3) + "]"); monitor.Options.Identity = Encoding.UTF8.GetBytes("Monitor[" + (myPort + 4) + "]"); cloudBackend.Options.Identity = Encoding.UTF8.GetBytes("CloudBackend"); stateFrontend.Options.Identity = Encoding.UTF8.GetBytes("StateFrontend"); }
public void Send_WrongServiceNameWithLogging_ShouldLogPermanentError() { const string hostAddress = "tcp://localhost:5555"; var loggingMessages = new List<string>(); // setup the counter socket for communication using (var broker = new RouterSocket()) using (var poller = new NetMQPoller()) 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.ReceiveMultipartMessage(); }; poller.Add(broker); poller.RunAsync(); // 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(); Assert.That(loggingMessages.Count, Is.EqualTo(7)); Assert.That(loggingMessages[6], Is.EqualTo("[CLIENT ERROR] permanent error, abandoning!")); } }
public void SendEmptyReplyFromBrokerWithLoggingShouldThrowApplicationException() { const string hostAddress = "tcp://localhost:5555"; var loggingMessages = new List<string>(); // setup the counter socket for communication using (var broker = new RouterSocket()) using (var poller = new NetMQPoller()) using (var session = new MDPClientAsync(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.ReceiveMultipartMessage(); // we expect to receive a 4 Frame message // [REQ ADR][EMPTY]["MDPC01"]["echo"]["REQUEST"][requestId] if (msg.FrameCount != 6) 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"][requestId] e.Socket.SendMultipartMessage(msg); }; session.LogInfoReady += (s, e) => loggingMessages.Add(e.Info); session.ReplyReady += (s, e) => { 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); poller.Stop(); // To unlock the Task.Wait() }; poller.Add(broker); var task = Task.Factory.StartNew(() => poller.Run()); // well formed message var requestMessage = new NetMQMessage(new[] { new NetMQFrame("REQUEST") }); // correct call session.Send("echo", requestMessage); int timeOutInMillis = 10000; var timer = new NetMQTimer(timeOutInMillis); // Used so it doesn't block if something goes wrong! timer.Elapsed += (s, e) => { Assert.Fail($"Waited {timeOutInMillis} and had no response from broker"); poller.Stop(); }; poller.Add(timer); task.Wait(); } }