public ZmqClient() { context = NetMQContext.Create(); subSocket = context.CreateSubscriberSocket(); subSocket.Options.ReceiveHighWatermark = 1000; subSocket.Connect(MarketDataSettings.RealTimeUpdateServerAddress); }
private void Subscribe(object state) { _running = true; foreach (string subscriberAddress in _configuration.SubscriberAddresses) { SubscriberSocket subscriberSocket = _context.CreateSubscriberSocket(); subscriberSocket.Connect(subscriberAddress); subscriberSocket.Subscribe(""); _subscriberSockets.Add(subscriberSocket); Task.Factory.StartNew(() => WaitForMessages(subscriberSocket)); } }
void establish() { subSocket = Core.ZeroMQ.CreateSubscriberSocket(); subSocket.Options.ReceiveHighWatermark = EngCfg.HighWatermark; ConnAddres = ConnectAddr(typeof(SubscriberSocket)); subSocket.Connect(ConnAddres); ConsoleEx.DebugLog("Sub socket has connected to " + ConnAddres, ConsoleEx.YELLOW); subSocket.Subscribe(topic); subSocket.ReceiveReady += Client_ReceiveReady; AddPoller(); }
public void Connect(string givenAddress) { if (IsConnected) { return; } subSocket = context.CreateSubscriberSocket(); subSocket.Connect(givenAddress); subSocket.Subscribe("EasyErgsocket"); IsConnected = true; }
/// <inheritdoc/> public void Start(Action <DateTime> notifyCompletionTime) { // notify that this is an infinite source component notifyCompletionTime(DateTime.MaxValue); this.socket = new SubscriberSocket(); this.socket.Connect(this.address); this.socket.Subscribe(this.topic); this.socket.ReceiveReady += this.ReceiveReady; this.poller = new NetMQPoller(); this.poller.Add(this.socket); this.poller.RunAsync(); }
public void Run(PairSocket shim) { _poller = new NetMQPoller(); _ = Observable.FromEventPattern <NetMQSocketEventArgs>(e => shim.ReceiveReady += e, e => shim.ReceiveReady -= e) .Select(e => e.EventArgs) .Subscribe(OnShimReady); _poller.Add(shim); // Timer var timeoutTimer = new NetMQTimer(TimeSpan.FromSeconds(5)); _ = Observable.FromEventPattern <NetMQTimerEventArgs>(e => timeoutTimer.Elapsed += e, e => timeoutTimer.Elapsed -= e) .Select(e => e.EventArgs) .ObserveOn(ThreadPoolScheduler.Instance) .Subscribe(OnTimeoutElapsed); _poller.Add(timeoutTimer); _subscriberSocket = new SubscriberSocket(); _subscriberSocket.Options.Linger = TimeSpan.Zero; _subscriberSocket.Subscribe(CoreHearbeatTopic); _subscriberSocket.Connect($"tcp://{_address}:{_port + 1}"); _subject.OnNext(ConnectionStatus.Connecting); _ = Observable.FromEventPattern <NetMQSocketEventArgs>(e => _subscriberSocket.ReceiveReady += e, e => _subscriberSocket.ReceiveReady -= e) .Select(e => e.EventArgs) .Where(e => e.Socket.ReceiveFrameString() == CoreHearbeatTopic) .ObserveOn(ThreadPoolScheduler.Instance) .Subscribe(e => { timeoutTimer.Reset(); Thread.MemoryBarrier(); var status = _borgConnected ? (ConnectionStatus.Online | ConnectionStatus.Connected) : (ConnectionStatus.Online | ConnectionStatus.Disconnected); _subject.OnNext(status); }); _poller.Add(_subscriberSocket); timeoutTimer.Reset(); shim.SignalOK(); _poller.Run(); // Cleanup stuff after stopping _poller.Remove(_subscriberSocket); _poller.Remove(timeoutTimer); _poller.Remove(shim); _poller.Dispose(); }
public PriceTickerScreenViewModel() { // get UI context so can ensure updates are on correct threada var uiContext = SynchronizationContext.Current; // add the list of Assets to display AssetViewModels.Add(new AssetViewModel { Name = "Stock 1", Price = 0 }); AssetViewModels.Add(new AssetViewModel { Name = "Stock 2", Price = 0 }); // set up subscriber to asset stream subject _assetStream.Subscribe(asset => { var avm = AssetViewModels.Single(a => a.Name == asset.Name); // update on UI context uiContext.Send(_ => { avm.Price = asset.Price; avm.History.Add(new HistoryItem { Timestamp = asset.Timestamp, Price = asset.Price }); }, null); }); // connect to the price server, receive updates and push to the subject stream Task.Run(() => { using (var client = new SubscriberSocket()) { client.Options.ReceiveHighWatermark = 1000; client.Connect("tcp://localhost:5555"); client.Subscribe("Stock 1"); client.Subscribe("Stock 2"); while (true) { var topicMessage = client.ReceiveFrameString(); var message = client.ReceiveFrameString(); // push onto subject _assetStream.OnNext(message.Deserialise <Asset>()); } } }); }
public void Sending1000Messages() { // creating two different context and sending 1000 messages int count = 0; var subReady = new ManualResetEvent(false); Task subTask = Task.Factory.StartNew(() => { using (var sub = new SubscriberSocket()) { sub.Bind("pgm://224.0.0.1:5555"); sub.Subscribe(""); subReady.Set(); while (count < 1000) { bool more; Assert.AreEqual(count, BitConverter.ToInt32(sub.ReceiveFrameBytes(out more), 0)); Assert.IsFalse(more); count++; } } }); subReady.WaitOne(); Task pubTask = Task.Factory.StartNew(() => { using (var pub = new PublisherSocket()) { pub.Connect("pgm://224.0.0.1:5555"); for (int i = 0; i < 1000; i++) { pub.SendFrame(BitConverter.GetBytes(i)); } // if we close the socket before the subscriber receives all messages subscriber // might miss messages, lets wait another second Thread.Sleep(1000); } }); pubTask.Wait(); subTask.Wait(); Assert.AreEqual(1000, count); }
public void NetMQSubscriber_WithNullTopicDispatcher_ThrowsArgumentNullException() { // Arrange var socket = new SubscriberSocket(); // Act TestDelegate construct = () => new NetMQSubscriber(socket, messageFactory, null); // Assert Assert.That(construct, Throws.ArgumentNullException); // Cleanup socket.Dispose(); }
public async Task TestProducer() { var cancel = new CancellationTokenSource(); SubscriberSocket _subSocket = null; var serializer = new EventSerializer(); var messages = new List <AccidentEvent>(); var directory = new Directory(); var configuration = new ProducerConfiguration() { IsTest = true, Endpoint = "tcp://localhost:8080", Id = Guid.NewGuid() }; var producer = new AccidentProducer(configuration, directory, new JsonSerializerSettings()); producer.Start(); await Task.Delay(500); new Task(() => { using (_subSocket = new SubscriberSocket()) { _subSocket.Options.ReceiveHighWatermark = 1000; _subSocket.Connect("tcp://localhost:8080"); _subSocket.Subscribe("Paris"); while (!cancel.IsCancellationRequested) { var topic = _subSocket.ReceiveFrameString(); var messageBytes = _subSocket.ReceiveFrameBytes(); var transportMessage = JsonConvert.DeserializeObject <TransportMessage>(Encoding.UTF32.GetString(messageBytes)); var message = (AccidentEvent)JsonConvert.DeserializeObject(Encoding.UTF32.GetString(transportMessage.Message), transportMessage.MessageType); messages.Add(message); } } }, cancel.Token).Start(); await Task.Delay(1000); Assert.Greater(messages.Count, 0); Assert.IsTrue(messages.All(m => { return(serializer.Serialize(m).StartsWith("Paris.")); })); }
public void Start(string serverAddress, int serverPublishPort, int clientId, Action <ServerToClientMessage> messageHandler) { this.messageHandler = messageHandler; subscribeSocket = new SubscriberSocket(); 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"); }
static int Main(string[] args) { if (args.Length < 2) { Console.WriteLine("Arguments: <nodeAddr> <subscr...>"); Console.WriteLine("Eg: tcp://node03.kv7.openov.nl:7817 /GOVI/KV8"); return(-1); } var nodeAddr = args[0]; var subscriptions = args.Skip(1).ToArray(); using (var socket = new SubscriberSocket()) { int msgCount = 0; socket.Connect(nodeAddr); try { subscriptions.All((s) => { socket.Subscribe(s); return(true); }); // Download just 20 messages, it's just a test tool... while (msgCount < 20) { var messageList = socket.ReceiveMultipartBytes(2); msgCount++; var msg1 = Encoding.UTF8.GetString(messageList[0]); using (GZipStream stream = new GZipStream(new MemoryStream(messageList[1]), CompressionMode.Decompress)) using (var sr = new StreamReader(stream)) { var msg2 = sr.ReadToEnd(); Console.Write($"{msg1} - {msg2.Length} chars..."); var filename = msg1.Substring(1).Replace('/', '-') + $"{msgCount}.xml"; File.WriteAllText(filename, msg2, Encoding.UTF8); Console.WriteLine(); } } } finally { socket.Disconnect(nodeAddr); socket.Close(); } } return(0); }
private void StopStationNetMQ() { // HockSocketEvents(false); try { if (null != _poller) { if (null != _subscriber) { _poller.Remove(_subscriber); } if (null != _requester) { _poller.Remove(_requester); } //_poller.Remove(_fileSubscriber); if (_poller.IsRunning) { _poller.Stop(); } _poller.Dispose(); _poller = null; } if (null != _subscriber) { _subscriber.Dispose(); _subscriber = null; } if (null != _requester) { _requester.Dispose(); _requester = null; } //_fileSubscriber.Dispose(); //_fileSubscriber = null; } catch (Exception err) { logger.ErrorFormat("Disconnect pub-sub error:{0}", err); } // this.OnDisconnected(); }
internal SubscriberHandler(SubscriberSocket subscriberSocket, SocketConfiguration configuration, NetMQPoller poller, CancellationToken token, Action <TMessage> syncCallback = null, Func <TMessage, Task> asyncCallback = null) { _token = token; _poller = poller; _socket = subscriberSocket; _configuration = configuration; _syncCallback = syncCallback; _asyncCallback = asyncCallback; }
private static void Main(string[] args) { var deciSecond = new TimeSpan(10000); using (var subscriber = new SubscriberSocket()) // For receiving updates from presentation host using (var publisher = new WSPublisher()) // For publishing updates from presentation host to audience using (var responder = new WSRouter()) // Handling on-demand requests for late-joining or crashing clients { subscriber.Bind("tcp://*:3000"); subscriber.SubscribeToAnyTopic(); publisher.Bind("ws://*:3001"); responder.Bind("ws://*:3002"); byte step = 0; subscriber.ReceiveReady += (_, __) => { if (!subscriber.TryReceiveFrameBytes(deciSecond, out var received)) { return; } step = received[0]; Console.Out.WriteLine("Sending " + step + " to audience."); publisher.TrySendFrame(deciSecond, new[] { step }); }; responder.ReceiveReady += (_, __) => { NetMQMessage msg = null; if (!responder.TryReceiveMultipartMessage(deciSecond, ref msg)) { return; } var identity = msg.Pop().Buffer; var request = msg.Pop().ConvertToString(); msg.Clear(); if (request == "Which slide are we on?") { responder.TrySendMultipartBytes(deciSecond, identity, new[] { step }); } else { if (!responder.TrySendFrame(deciSecond, identity, true)) { return; } responder.TrySendFrameEmpty(deciSecond); } }; new NetMQPoller { subscriber, responder }.Run(); // Polling both subscriber and router sockets. } }
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"); }
public void ThroughXPubXSubWithReconnectingPublisher() { using (var xpub = new XPublisherSocket()) using (var xsub = new XSubscriberSocket()) using (var poller = new NetMQPoller { xsub, xpub }) { var xPubPort = (ushort)xpub.BindRandomPort("tcp://*"); var xSubPort = (ushort)xsub.BindRandomPort("tcp://*"); var proxy = new Proxy(xsub, xpub, poller: poller); proxy.Start(); poller.RunAsync(); // long running subscriber using (var sub = new SubscriberSocket()) { sub.Connect(string.Format("tcp://localhost:{0}", xPubPort)); sub.Subscribe("A"); // publisher 1 using (var pub = new PublisherSocket()) { pub.Connect(string.Format("tcp://localhost:{0}", xSubPort)); // give the publisher a chance to learn of the subscription Thread.Sleep(100); pub.SendMoreFrame("A").SendFrame("1"); } // publisher 2 using (var pub = new PublisherSocket()) { pub.Connect(string.Format("tcp://localhost:{0}", xSubPort)); // give the publisher a chance to learn of the subscription Thread.Sleep(100); pub.SendMoreFrame("A").SendFrame("2"); } var frames = new List <string>(); Assert.True(sub.TryReceiveMultipartStrings(TimeSpan.FromSeconds(1), ref frames)); CollectionAssert.AreEqual(new[] { "A", "1" }, frames); Assert.True(sub.TryReceiveMultipartStrings(TimeSpan.FromSeconds(1), ref frames)); CollectionAssert.AreEqual(new[] { "A", "2" }, frames); } } }
public Client() { // first of all force asyncio AsyncIO.ForceDotNet.Force(); // time to send all messages before any socket gets disposed, default: 0. NetMQConfig.Linger = System.TimeSpan.FromMilliseconds(250); timer = new HRTimer(); subscriber = new SubscriberSocket(); messageHandlers = new SortedDictionary <System.UInt64, Action <NetMQMessage> >(); config(); }
public void Subscribe() { using (SubscriberSocket subscriber = new SubscriberSocket()) { subscriber.Options.ReceiveHighWatermark = 1000; subscriber.Connect("tcp://127.0.0.1:12345"); subscriber.Subscribe("TopicA"); var data = subscriber.ReceiveFrameString(); Console.WriteLine("Topic: TopicA received data: {0}", data); } }
private static void Subscribe(object filter) { using (var subscriber = new SubscriberSocket()) { subscriber.Connect(push_server); subscriber.Subscribe(filter.ToString(), Encoding.UTF8); while (receive_push) { string response = subscriber.ReceiveFrameString(Encoding.UTF8); string[] datas = response.Substring(1).Replace("}", "").Split('{'); Deal(datas); } } }
/// <summary> /// Listens for all topics on the given ZMQ endpoint /// /// Intended to be run as in a Thread: /// _subscriberThread = new Thread(NetMqSubscriber); /// _subscriberThread.Start("tcp://127.0.0.1:13337"); /// </summary> /// <param name="param">The ZMQ-endpoint as a string</param> private void NetMqSubscriber(object param) { AsyncIO.ForceDotNet.Force(); var endpoint = (string)param; Debug.Log("Creating subscriber"); var timeout = new TimeSpan(0, 0, 0, 1); //1 s try { subSocket = new SubscriberSocket(); subSocket.Options.Linger = TimeSpan.Zero; subSocket.Subscribe("volume_extremes"); subSocket.Connect(endpoint); Debug.Log("Sub connected"); var msg = new List <string>(); while (running) { if (!subSocket.TryReceiveMultipartStrings(new TimeSpan(0, 0, 0, 0, 300), ref msg)) { continue; } if (msg.Count < 2) { Debug.LogError(msg); continue; } Debug.Log("Got BBox message: " + msg[1]); bbox = JsonConvert.DeserializeObject <InvBoundingBox>(msg[1]); dirty = true; } } catch (Exception ex) { Debug.Log("Got exception: " + ex); } finally { try { subSocket.Close(); } catch (ObjectDisposedException e) { Debug.LogWarning("Tried to close socket but was already disposed"); } } Debug.Log("Subscriber has the deds"); }
public async Task RoutingTestForCustomSubscriber() { var address = "tcp://localhost:6001"; var publisherSocket = new PublisherSocket(); publisherSocket.Bind(address); var subscriberSocket = new SubscriberSocket(); subscriberSocket.Connect(address); var router = NetmqMessageRouter .WithPubSubConnecton(publisherSocket, subscriberSocket) .RegisterJsonSerializer() .RegisterRoute("VectorRoute", typeof(Vector)) .RegisterRoute("VectorLengthRoute", typeof(double)); router .Subscribe("VectorRoute") .WithResponse("VectorLengthRoute") .WithHandler((Vector vector) => { return(Math.Sqrt(vector.X * vector.X + vector.Y * vector.Y)); }); double?lengthAnswer = null; router .Subscribe("VectorLengthRoute") .WithHandler((double x) => lengthAnswer = x); router.StartRouting(); router .SendMessage(new Vector() { X = 3, Y = 4 }) .To("VectorRoute"); await Task.Delay(TimeSpan.FromSeconds(5)); router .StopRouting() .Disconnect(); Assert.AreEqual(5d, lengthAnswer); }
public bool InitializeSubscriber(string subscriberUrl = "tcp://localhost:13370", string topic = "") { MessageTopicHeaderSize = topic.Length + 1; try { SubscriberSocket = new SubscriberSocket(); SubscriberSocket.Connect(subscriberUrl); SubscriberSocket.Subscribe(topic); return(true); } catch (Exception) { return(false); } }
public EddnSubscriberService( IHostApplicationLifetime appLifetime, ILogger <EddnSubscriberService> logger, IOptionsSnapshot <EddnSettings> options, IImportTargetFactory importTargetFactory) { _appLifetime = appLifetime; _logger = logger; _importTargetFactory = importTargetFactory; _options = options.Value; _subscriberSocket = new SubscriberSocket(); _subscriberSocket.Options.ReceiveHighWatermark = _options.ReceiveHighWatermark; _appLifetime.ApplicationStopping.Register(OnStopping); _encoding = new UTF8Encoding(); }
/// <summary> /// Starts this instance, connecting it to specified publishers. /// </summary> /// <param name="publishers">The publishers to connect.</param> /// <param name="peer">The self peer identity.</param> public void Start(List <IPEndPoint> publishers, PeerIdentity peer) { _peer = peer; _socket = new SubscriberSocket(); foreach (var publisherEndpoint in publishers) { var endpoint = $"tcp://{publisherEndpoint.Address}:{publisherEndpoint.Port}"; _socket.Connect(endpoint); } _socket.Subscribe(_topicBuilder.GetMessageTag(peer.Context, peer.Id)); StartReceivingMessages(); }
private void SubscribeThread() { // Place subscribe socket initialization inside thread to make all subscribe calls happen on the same thread // Trying to prevent "Cannot close an uninitialised Msg" exceptions _subscribeSocket = new SubscriberSocket(); _subscribeSocket.Connect(_subscribeAddress); _subscribeSocket.SubscribeToAnyTopic(); _subscribeThreadRunning = true; while (!_subscribeThreadCancellation.IsCancellationRequested) { try { if (!_subscribeSocket.TryReceiveFrameBytes(new TimeSpan(0, 0, 0, 0, 200), out byte[] messageBytes))
static void Main(string[] args) { using (var sub = new SubscriberSocket()) { sub.Connect("tcp://127.0.0.1:5556"); sub.Subscribe("A"); while (true) { var topic = sub.ReceiveFrameString(); var msg = sub.ReceiveFrameString(); Console.WriteLine($"From publisher: {topic} {msg}"); } } }
public void Addresses_WithNoAddressesAdded_IsEmpty() { // Arrange var socket = new SubscriberSocket(); var subscriber = new NetMQSubscriber(socket, messageFactory, topicDispatcher); // Act var any = subscriber.Addresses.Any(); // Assert Assert.That(any, Is.False); // Cleanup subscriber.Dispose(); }
public void Start() { _publishStateUpdate = new PublisherSocket(); _publishStateUpdate.Bind(_brokerConfiguration.PublishUpdatesEndpoint); _subscribeToUpdates = new SubscriberSocket(); _subscribeToUpdates.SubscribeToAnyTopic(); _subscribeToUpdates.Bind(_brokerConfiguration.SubscribeToUpdatesEndpoint); _stateRequest = new RouterSocket(); _stateRequest.Bind(_brokerConfiguration.SendStateEndpoint); _workProc = Task.Run(DoStart, _cancel.Token).ConfigureAwait(false); _heartBeartProc = Task.Run(HandleHeartbeat, _cancel.Token).ConfigureAwait(false); }
private static void Subscriber() { using (var subscriber = new SubscriberSocket()) { subscriber.Connect("tcp://127.0.0.1:5556"); subscriber.Subscribe(""); while (true) { var topic = subscriber.ReceiveFrameString(); var msg = subscriber.ReceiveFrameString(); Console.WriteLine("From Publisher: {0} {1}", topic, msg); } } }
public void ConnectAll_WithNoAddresses_DoesNothing() { // Arrange var socket = new SubscriberSocket(); var subscriber = new NetMQSubscriber(socket, messageFactory, topicDispatcher); // Act TestDelegate connectAll = () => subscriber.InitializeConnection(); // Assert Assert.That(connectAll, Throws.Nothing); // Cleanup subscriber.Dispose(); }
void Start() { Debug.Log("Start"); //might be unnecessary target = this.gameObject; //Initializes a new Subscriber subscriberSocket = new SubscriberSocket(); //Connects to the specific IP subscriberSocket.Connect("tcp://192.168.43.117:5555"); //Connects to a specific topic subscriberSocket.Subscribe("xaris"); }
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); } } }
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); }
private static void SubscriberContinuousLoop(string pubSubAddress, string requestString) { Task.Factory.StartNew(() => { using (var progressSubscriber = new SubscriberSocket()) { progressSubscriber.Connect(pubSubAddress); progressSubscriber.SubscribeToAnyTopic(); while (true) { var topic = progressSubscriber.ReceiveFrameString(); RequestSocket.ProgressTopic progressTopic; Enum.TryParse(topic, out progressTopic); switch (progressTopic) { case RequestSocket.ProgressTopic.Send: Console.WriteLine("C: Sending {0}", requestString); break; case RequestSocket.ProgressTopic.Retry: Console.WriteLine("C: No response from server, retrying..."); break; case RequestSocket.ProgressTopic.Failure: Console.WriteLine("C: Server seems to be offline, abandoning"); break; case RequestSocket.ProgressTopic.Success: Console.WriteLine("C: Server replied OK"); break; default: throw new ArgumentOutOfRangeException(); } } } }); }
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(); } }
/// <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 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; } }
private void OnTimeoutTimer(object sender, NetMQTimerEventArgs e) { // dispose the current subscriber socket and try to connect m_poller.RemoveSocket(m_subscriber); m_subscriber.Dispose(); m_subscriber = null; Connect(); }
/// <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"); }