public void Start(string serverAddress, int serverPublishPort, int clientId, Action<ServerToClientMessage> messageHandler) { this.messageHandler = messageHandler; ctx = NetMQContext.Create(); subscribeSocket = ctx.CreateSubscriberSocket(); subscribeSocket.Connect(string.Format("tcp://{0}:{1}", serverAddress, serverPublishPort)); subscribeSocket.Subscribe(clientId.ToString()); subscribeSocket.Subscribe("a"); isRunning = true; receiveThread = new Thread(Run); receiveThread.Name = "ClientMessageListenThread"; receiveThread.Start(); logger.Info("Server message subscriber started"); }
private void OnShimReady(NetMQSocketEventArgs args) { try { var msg = args.Socket.ReceiveMultipartMessage(); var cmd = msg.First.ConvertToString(); if (cmd == NetMQActor.EndShimMessage) { _poller?.Stop(); return; } if (msg.FrameCount <= 1) { return; } switch (cmd) { case "subscribe": _logger.Debug("Adding node to group {0}", msg[1].ConvertToString()); _subscriberSocket?.Subscribe(msg[1].ConvertToString()); break; case "unsubscribe": _logger.Debug("Removing node from group {0}", msg[1].ConvertToString()); _subscriberSocket?.Unsubscribe(msg[1].ConvertToString()); break; } } catch (Exception ex) { _logger.Fatal(ex, "Error on BorgShim."); } }
private void OnShimMessage(object sender, NetMQSocketEventArgs e) { var command = e.Socket.ReceiveFrameString(); if (command == NetMQActor.EndShimMessage) { _poller.Stop(); } else if (command == SubscribeCommand) { var topic = e.Socket.ReceiveFrameString(); _subscriptions.Add(topic); _subscriber?.Subscribe(topic); } }
static void Main(string[] args) { using (var subSocket = new SubscriberSocket()) { subSocket.Options.ReceiveHighWatermark = 100; subSocket.Connect("tcp://localhost:12345"); subSocket.Subscribe(""); Console.WriteLine("Subscriber socket connecting..."); while (true) { string messageTopicReceived = subSocket.ReceiveFrameString(); string messageReceived = subSocket.ReceiveFrameString(); Console.WriteLine(messageReceived); Thread.Sleep(300); } } }
public void WelcomeMessage() { using (var pub = new XPublisherSocket()) using (var sub = new SubscriberSocket()) { pub.Bind("inproc://welcome"); pub.SetWelcomeMessage("W"); sub.Subscribe("W"); sub.Connect("inproc://welcome"); var subscription = pub.ReceiveFrameBytes(); Assert.AreEqual(subscription[1], (byte)'W'); Assert.AreEqual("W", sub.ReceiveFrameString()); } }
private void EventTask(string channel) { Debug.Log("Start event thread on chanel " + channel); var address = string.Format(">tcp://{0}:{1}", serverIp, eventPort); using (var subscriber = new SubscriberSocket(address)) { // Listen to all topics subscriber.Subscribe(channel); while (true) { var eventPacket = subscriber.ReceiveFrameBytes(); EnqueueEvent(eventPacket); } } }
public void Run() { using (var subSocket = new SubscriberSocket()) { subSocket.Options.ReceiveHighWatermark = 1000; subSocket.Connect(@"tcp://127.0.0.1:2020"); subSocket.Subscribe(_subscribePattern); Console.WriteLine($"Subscriber socket <{_subscriberName}> connecting to pattern <{_subscribePattern}>"); while (true) { string messageTopicReceived = subSocket.ReceiveFrameString(); string messageReceived = subSocket.ReceiveFrameString(); Console.WriteLine($"<{_subscriberName}> Modtaget Tilbud : {messageReceived}"); System.Threading.Thread.Sleep(5000); SendAnswer(); } } }
static void XSub() { var a3 = $"{address}:55508"; string topic = "TopicA"; // one of "TopicA" or "TopicB" using (var subSocket = new SubscriberSocket(a3)) { subSocket.Options.ReceiveHighWatermark = 1000; subSocket.Subscribe(topic); Console.WriteLine("Subscriber socket connecting..."); while (true) { string messageTopicReceived = subSocket.ReceiveFrameString(); string messageReceived = subSocket.ReceiveFrameString(); Console.WriteLine(messageReceived); } } }
/// <summary> /// Main /// </summary> public static void Main(string[] args) { using (SubscriberSocket subSocket = new SubscriberSocket()) { subSocket.Options.ReceiveHighWatermark = 1000; subSocket.Connect("tcp://localhost:5559"); subSocket.Subscribe(""); while (true) { string messageReceived = subSocket.ReceiveFrameString(); string[] messageData = messageReceived.Split(' '); if (messageData.Length != 2) { continue; } string[] orderData = messageData[1].Split('|'); if (orderData.Length != 9) { continue; } Response response = new Response { Login = int.Parse(messageData[0]), Action = orderData[0], Symbol = orderData[1], Ticket = int.Parse(orderData[2]), Type = int.Parse(orderData[3]), OpenPrice = double.Parse(orderData[4]), ClosePrice = double.Parse(orderData[5]), Lots = double.Parse(orderData[6]), SL = double.Parse(orderData[7]), TP = double.Parse(orderData[8]) }; Console.WriteLine("Login: "******", Action: " + response.Action + ", Symbol: " + response.Symbol); } } }
private void monitor() { while (running) { while (!reloading) { try { // We only listen for updates if the user has selected anything to listen to if (configuration.watches != null && configuration.watches.Count > 0) { using (var subscriber = new SubscriberSocket()) { subscriber.Connect("tcp://api.eddp.co:5556"); subscriber.Subscribe("eddp.delta.system"); while (running && !reloading) { if (subscriber.TryReceiveFrameString(new TimeSpan(0, 0, 1), out string topic)) { string message = subscriber.ReceiveFrameString(); Logging.Debug("Message is " + message); JObject json = JObject.Parse(message); if (topic == "eddp.delta.system") { handleSystemDelta(json); } } } } } } catch (Exception ex) { Logging.Error("Caught exception", ex); } finally { Thread.Sleep(1000); } } Thread.Sleep(1000); reloading = false; } }
/// <summary> /// Setup subscriber and publisher for this network /// </summary> /// <param name="ip"></param> /// <param name="only_pub"></param> void setup(string ip = "") { if (state == NetworkState.SETUP && busy == false) { app_exit_sub = false; busy = true; if (type != NetworkType.SUB) { publisher = new PublisherSocket(); if (is_subscriber_monitor_enabled) { //monitor = new NetMQMonitor(publisher, "inproc://pub.inproc" + local_port, SocketEvents.All); //monitor.Disconnected += Monitor_Disconnected; //monitor.EventReceived += Monitor_EventReceived; //monitor.Accepted += Monitor_Accepted; //monitor.Timeout = new TimeSpan(0, 0, 0, 0, 1000); //Task task = monitor.StartAsync(); } publisher.Bind("tcp://*:" + local_port); if (ip == "") { ip = remote_ip; } if (type != NetworkType.PUB) { //We shoudl have a subscriber too ! subscriber = new SubscriberSocket(); subscriber.Subscribe(""); subscriber.Connect("tcp://" + ip + ":" + remote_port); sub_thread = new System.Threading.Thread(new System.Threading.ThreadStart(zmqSubThread)); sub_thread.Start(); } delegateNewLog?.Invoke("Creating new network for remote: " + remote_ip + " and port: " + remote_port + " " + type.ToString(), RRS.Tools.Log.LogType.INFO, section); state = NetworkState.CONNECTED; busy = false; } } }
private void OnShimMessage(object sender, NetMQSocketEventArgs e) { string command = e.Socket.ReceiveFrameString(); if (command == NetMQActor.EndShimMessage) { m_poller.Cancel(); } else if (command == SubscribeCommand) { string topic = e.Socket.ReceiveFrameString(); m_subscriptions.Add(topic); if (m_subscriber != null) { m_subscriber.Subscribe(topic); } } }
private void TaskAudioSub(CancellationToken cancelToken, BlockingCollection <ClientAudio> outputQueue, string address) { using (var subSocket = new SubscriberSocket()) { //subSocket.Options.ReceiveHighWatermark = 1000; subSocket.Connect(address); subSocket.Subscribe(callsign); while (!cancelToken.IsCancellationRequested) { var messageTopicReceived = subSocket.ReceiveFrameString(); //Should always == _username int bytesReceived = 0; ClientAudio clientAudio = subSocket.Deserialise <ClientAudio>(out bytesReceived); ClientStatistics.AudioBytesReceived += bytesReceived; outputQueue.Add(clientAudio); } } taskAudioSub = null; }
public void TopicPubSub() { using (var pub = new PublisherSocket()) using (var sub = new SubscriberSocket()) { var port = pub.BindRandomPort("tcp://127.0.0.1"); sub.Connect("tcp://127.0.0.1:" + port); sub.Subscribe("A"); // let the subscriber connect to the publisher before sending a message Thread.Sleep(500); pub.SendMoreFrame("A").SendFrame("Hello"); CollectionAssert.AreEqual( new[] { "A", "Hello" }, sub.ReceiveMultipartStrings()); } }
static void Main(string[] args) { string uuid = "A"; using (var subSocket = new SubscriberSocket()) { subSocket.Connect("tcp://192.168.1.106:5555"); // subSocket.Options.ReceiveHighWatermark = 0; subSocket.Subscribe(uuid); Console.WriteLine("Subscriber socket connecting..."); while (true) { string uuid_value = subSocket.ReceiveFrameString(); byte[] RMSValue = subSocket.ReceiveFrameBytes(); string result = string.Concat(Enumerable.Repeat("#", (int)(Math.Round((BitConverter.ToDouble(RMSValue, 0) * 200))))); Console.WriteLine(result); } } }
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; }
public void SubscribeProgress(Action <TextProgressInfo> callback) { Task.Run(() => { using (var socket = new SubscriberSocket()) { socket.Options.ReceiveHighWatermark = 1000; socket.Connect(StatusUri.OriginalString); socket.Subscribe(Topic); { var messageTopicReceived = socket.ReceiveFrameString(); Debug.Assert(messageTopicReceived.Equals(Topic)); var messageReceived = socket.ReceiveFrameString(); callback(new TextProgressInfo(messageReceived)); Console.WriteLine(messageReceived); } } }); }
void Start() { trackManager = GetComponent <TrackManager>(); statDisplayManager = GetComponent <StatDisplayManager>(); cameraManager = GetComponent <CameraManager>(); //if there is no otherBoatType set just use the playerBoatType... if this isn't set either we're screwed anyways... if (otherBoatType == null) { otherBoatType = playerBoatType; } initLanes(); Debug.Log("Starting up NetMQ interface on " + address); context = NetMQContext.Create(); subSocket = context.CreateSubscriberSocket(); subSocket.Connect(address); subSocket.Subscribe("EasyErgsocket"); }
private void Work() { using (var subscriberSocket = new SubscriberSocket()) { subscriberSocket.Connect(_brokerEndpoint); subscriberSocket.Subscribe("FX"); while (!_cancel.IsCancellationRequested) { var message = subscriberSocket.ReceiveMultipartMessage() .GetMessageFromProducer <Price>(); var price = message.Message; _prices.AddOrUpdate(price.Asset, price, (key, value) => { return(value); }); } } }
public void LargeMessage() { using (var pub = new PublisherSocket()) using (var sub = new SubscriberSocket()) { var port = pub.BindRandomPort("tcp://127.0.0.1"); sub.Connect("tcp://127.0.0.1:" + port); sub.Subscribe(""); Thread.Sleep(100); var msg = new byte[300]; pub.SendFrame(msg); byte[] msg2 = sub.ReceiveFrameBytes(); Assert.AreEqual(300, msg2.Length); } }
public ReactiveClient() { var context = NetMQContext.Create(); reqSocket = context.CreateRequestSocket(); reqSocket.Connect("tcp://127.0.0.1:3334"); reqSocket.Send("GetMarket"); var data = reqSocket.Receive(); var mess = Encoding.UTF8.GetString(data); Console.WriteLine(mess); subSocket = context.CreateSubscriberSocket(); subSocket.Connect("tcp://127.0.0.1:3333"); subSocket.Subscribe(""); var thread = new Thread(ReceiveThread); thread.Start(); }
// Thread function that handles the socket connection and reads in data private void ListenerWork() { AsyncIO.ForceDotNet.Force(); // Create new sub socket using (var subSocket = new SubscriberSocket()) { //High watermark is the number of messages that will be kept in memory //until the socket enters exception state and drops or blocks messages //at setting 1000 there is no limit... subSocket.Options.ReceiveHighWatermark = 1; //connect socket with IP subSocket.Connect(this.serverIP); //socket.subscribe(topic) //Because we don't care about having a topic we send // "" to subscribe to all topics subSocket.Subscribe(""); // Loop until cancel while (!_listenerCancelled) { //keep trying to read in data until we "hear something" byte[] frameBytes; if (!subSocket.TryReceiveFrameBytes(out frameBytes)) { continue; } //print out findings to Log //Prolly remove this later... //UnityEngine.Debug.Log(frameBytes.ToString()); //Enqueue data into list to be handled _messageQueue.Enqueue(frameBytes); } //After being cancelled, close socket connection and cleanup config subSocket.Close(); } NetMQConfig.Cleanup(); }
private static void Main() { Console.Title = "NetMQ Weather Update Client"; const int zipToSubscribeTo = 10001; const int iterations = 100; int totalTemp = 0; int totalHumidity = 0; Console.WriteLine("Collecting updates for weather service for zipcode {0}...", zipToSubscribeTo); using (var subscriber = new SubscriberSocket()) { subscriber.Connect("tcp://127.0.0.1:5556"); subscriber.Subscribe(zipToSubscribeTo.ToString(CultureInfo.InvariantCulture)); for (int i = 0; i < iterations; i++) { string results = subscriber.ReceiveFrameString(); Console.Write("."); // "zip temp relh" ... "10001 84 23" -> ["10001", "84", "23"] string[] split = results.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); int zip = int.Parse(split[0]); if (zip != zipToSubscribeTo) { throw new Exception($"Received message for unexpected zipcode: {zip} (expected {zipToSubscribeTo})"); } totalTemp += int.Parse(split[1]); totalHumidity += int.Parse(split[2]); } } Console.WriteLine(); Console.WriteLine("Average temperature was: {0}", totalTemp / iterations); Console.WriteLine("Average relative humidity was: {0}", totalHumidity / iterations); Console.ReadLine(); }
// Client thread which does not block Update() void NetMQClient() { AsyncIO.ForceDotNet.Force(); NetMQConfig.ManualTerminationTakeOver(); NetMQConfig.ContextCreate(true); //string msg; var timeout = new System.TimeSpan(0, 0, 1); //1sec Debug.Log("Connect to the server."); var subSocket = new SubscriberSocket(); subSocket.Options.ReceiveHighWatermark = 0; subSocket.Connect("tcp://192.168.1.122:55555"); subSocket.Subscribe(""); bool is_connected = true; while (is_connected && stop_thread_ == false) { is_connected = subSocket.TryReceiveFrameString(timeout, out msg); //Debug.Log(msg); //byte[] decodedBytes = System.Convert.FromBase64String(msg); //Debug.Log(decodedBytes); //string decodedText = Encoding.UTF8.GetString(decodedBytes); //Debug.Log(decodedText); //Mat buffer = new Mat(decodedText, ImreadModes.Unchanged); //image = Cv2.ImDecode(buffer, ImreadModes.Unchanged); //using (var window = new Window("window", image: src, flags: WindowMode.AutoSize)) { //Cv2.WaitKey(); //} //Debug.Log(src); } subSocket.Close(); Debug.Log("ContextTerminate."); NetMQConfig.ContextTerminate(); NetMQConfig.Cleanup(); }
private void ListenerWork() { AsyncIO.ForceDotNet.Force(); using (var subSocket = new SubscriberSocket()) { subSocket.Options.ReceiveHighWatermark = 1000; subSocket.Connect("tcp://localhost:12345"); subSocket.Subscribe(""); while (!_listenerCancelled) { string frameString; if (!subSocket.TryReceiveFrameString(out frameString)) { continue; } _messageQueue.Enqueue(frameString); } subSocket.Close(); } NetMQConfig.Cleanup(); }
public virtual void Setup(INetManager netManager) { if (string.IsNullOrEmpty(ResponseHostString)) { throw new ArgumentNullException(nameof(ResponseHostString)); } _subscriberSocket = new SubscriberSocket(PublisherSocketString); _subscriberSocket.Subscribe(FrontendID); Poller = new NetMQPoller() { _subscriberSocket, }; NetSend = netManager; _subscriberSocket.ReceiveReady += ProcessSubscribe; IsSetuped = true; }
public void Subscribe(string topic) { if (string.IsNullOrEmpty(topic) || topics.Contains(topic)) { return; } topics.Add(topic); socket.Subscribe(topic); if (topics.Count > 0 && receivingThread == null) { cts = new CancellationTokenSource(); receivingThread = Task.Run(async() => { while (!cts.IsCancellationRequested && await Receive()) { ; } }, cts.Token); } }
private void Work() { using (var subscriberSocket = new SubscriberSocket()) { subscriberSocket.Options.Identity = _id.ToByteArray(); subscriberSocket.Connect(_brokerEndpoint); subscriberSocket.Subscribe(FxMarket.CCyPairWithUniquePrice); while (!_cancel.IsCancellationRequested) { var message = subscriberSocket.ReceiveMultipartMessage() .GetMessageFromProducer <Price>(); var price = message.Message; _prices.AddOrUpdate(price.Asset, price, (key, value) => { return(value); }); } } }
public static void Listen(string song, string address = null) { if (address == null) { address = Address; } if (subscriber_socket == null) { subscriber_socket = context.CreateSubscriberSocket(); subscriber_socket.Connect(string.Format("tcp://{0}:{1}", address, PublisherPort)); } subscriber_socket.Subscribe(song); if (thread == null) { thread = new Thread(() => OnReceived(subscriber_socket)); thread.Start(); } }
private static void Main() { Console.Title = "NetMQ Weather Update Client"; const int zipToSubscribeTo = 10001; const int iterations = 100; int totalTemp = 0; int totalHumidity = 0; Console.WriteLine("Collecting updates for weather service for zipcode {0}...", zipToSubscribeTo); using (var subscriber = new SubscriberSocket()) { subscriber.Connect("tcp://127.0.0.1:5556"); subscriber.Subscribe(zipToSubscribeTo.ToString(CultureInfo.InvariantCulture)); for (int i = 0; i < iterations; i++) { string results = subscriber.ReceiveFrameString(); Console.Write("."); // "zip temp relh" ... "10001 84 23" -> ["10001", "84", "23"] string[] split = results.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); int zip = int.Parse(split[0]); if (zip != zipToSubscribeTo) { throw new Exception(string.Format("Received message for unexpected zipcode: {0} (expected {1})", zip, zipToSubscribeTo)); } totalTemp += int.Parse(split[1]); totalHumidity += int.Parse(split[2]); } } Console.WriteLine(); Console.WriteLine("Average temperature was: {0}", totalTemp/iterations); Console.WriteLine("Average relative humidity was: {0}", totalHumidity/iterations); }
internal void GivenMessageToPublish_WhenMessageValid_PublishesToSubscriber() { // Arrange var publisher = new MockDataPublisher( this.container, DataBusFactory.Create(this.container), EncryptionSettings.None(), ZmqNetworkAddress.LocalHost(new Port(55555))); publisher.Start().Wait(); const string testAddress = "tcp://localhost:55555"; var subscriber = new SubscriberSocket(testAddress); subscriber.Connect(testAddress); subscriber.Subscribe(TestTopic); Task.Delay(100).Wait(); // Allow sockets to subscribe // Act const string toSend = "1234,1234"; publisher.Endpoint.SendAsync((TestTopic, toSend)); var topic = subscriber.ReceiveFrameBytes(); var message = subscriber.ReceiveFrameBytes(); // Assert Assert.Equal(TestTopic, Encoding.UTF8.GetString(topic)); Assert.Equal(toSend, Encoding.UTF8.GetString(message)); Assert.Equal(ComponentState.Running, publisher.ComponentState); Assert.Equal(1, publisher.SentCount); // Tear Down subscriber.Disconnect(testAddress); subscriber.Dispose(); publisher.Stop().Wait(); publisher.Dispose(); }
private void TaskClientAudioSub(CancellationToken cancelToken, BlockingCollection <ClientAudio> outputQueue, string bind) { using (var subSocket = new SubscriberSocket()) { subSocket.Options.ReceiveHighWatermark = 50; subSocket.Bind(bind); subSocket.Subscribe(""); while (!cancelToken.IsCancellationRequested) { var clientID = subSocket.ReceiveFrameString(); var audioData = subSocket.ReceiveFrameBytes(); serverStatistics.AudioBytesReceived += audioData.Length; outputQueue.Add(new ClientAudio() { Callsign = clientID, Data = audioData }); } taskClientDataSub = null; } }
/// <summary> /// Main /// </summary> public static void Main(string[] args) { using (SubscriberSocket subSocket = new SubscriberSocket()) { subSocket.Options.ReceiveHighWatermark = 1000; subSocket.Connect("tcp://localhost:5559"); subSocket.Subscribe(""); while (true) { string messageReceived = subSocket.ReceiveFrameString(); string[] messageData = messageReceived.Split(' '); if (messageData.Length != 2) { continue; } string[] quotesData = messageData[1].Split('|'); if (quotesData.Length != 4) { continue; } Response response = new Response { Login = int.Parse(messageData[0]), Symbol = quotesData[0], Ask = double.Parse(quotesData[1]), Bid = double.Parse(quotesData[2]), Spread = int.Parse(quotesData[3]) }; Console.WriteLine("Login: "******", Symbol: " + response.Symbol + ", Ask: " + response.Ask + ", Bid: " + response.Bid, ", Spread: " + response.Spread); } } }
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; } }
/// <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(); } }
private void RunActor(PairSocket shim) { // save the shim to the class to use later m_shim = shim; // create all subscriber, publisher and beacon using (m_subscriber = new SubscriberSocket()) using (m_publisher = new PublisherSocket()) using (m_beacon = new NetMQBeacon()) { // listen to actor commands m_shim.ReceiveReady += OnShimReady; // subscribe to all messages m_subscriber.Subscribe(""); // we bind to a random port, we will later publish this port // using the beacon m_randomPort = m_subscriber.BindRandomPort("tcp://*"); Console.WriteLine("Bus subscriber is bound to {0}", m_subscriber.Options.LastEndpoint); // listen to incoming messages from other publishers, forward them to the shim m_subscriber.ReceiveReady += OnSubscriberReady; // configure the beacon to listen on the broadcast port Console.WriteLine("Beacon is being configured to UDP port {0}", m_broadcastPort); m_beacon.Configure(m_broadcastPort); // publishing the random port to all other nodes Console.WriteLine("Beacon is publishing the Bus subscriber port {0}", m_randomPort); m_beacon.Publish(m_randomPort.ToString(), TimeSpan.FromSeconds(1)); // Subscribe to all beacon on the port Console.WriteLine("Beacon is subscribing to all beacons on UDP port {0}", m_broadcastPort); m_beacon.Subscribe(""); // listen to incoming beacons m_beacon.ReceiveReady += OnBeaconReady; // Create a timer to clear dead nodes NetMQTimer timer = new NetMQTimer(TimeSpan.FromSeconds(1)); timer.Elapsed += ClearDeadNodes; // Create and configure the poller with all sockets and the timer m_poller = new NetMQPoller { m_shim, m_subscriber, m_beacon, timer }; // signal the actor that we finished with configuration and // ready to work m_shim.SignalOK(); // polling until cancelled m_poller.Run(); } }