private async Task Handler() { while (this.IsRunning) { try { bool isListening = false; var connectionString = this.FrontendEndpoint.ToConnectionString(); using (var frontendSocket = new RouterSocket()) using (this.FrontendBuffer = new NetMQQueue <TransportMessage>()) using (var poller = new NetMQPoller() { frontendSocket, this.FrontendBuffer }) using (var monitor = new NetMQ.Monitoring.NetMQMonitor(frontendSocket, $"inproc://monitor.forwarderdevice.{Guid.NewGuid().ToString()}", SocketEvents.Listening | SocketEvents.Accepted | SocketEvents.Disconnected | SocketEvents.Closed)) { frontendSocket.ReceiveReady += (sender, e) => { try { var netmqMessage = new NetMQMessage(); while (e.Socket.TryReceiveMultipartMessage(ref netmqMessage)) { var message = netmqMessage.ToMessage(out var envelope); string serviceIdentifier = message.Metadata.TryGetLast("serviceIdentifier", out var encodedService) ? Encoding.UTF8.GetString(encodedService) : null; try { var cancellationSource = new CancellationTokenSource(5000); var registeredBackend = this.ResolveBackend(serviceIdentifier, cancellationSource.Token); //var registeredBackend = this.InprocTransportScope.GetNextServerTransport(serviceIdentifier, cancellationSource.Token); message.Metadata.Add($"envelope[{this.Identity}]", envelope); //registeredBackend.ReceiveBuffer.QueueMessage(message); registeredBackend.Send(message).ContinueWith(task => { this.OnDiagnosticMessage($"Failed to forward to backend [{task.Exception.InnerException.Message}]"); }, TaskContinuationOptions.OnlyOnFaulted); } catch (OperationCanceledException) { this.OnDiagnosticMessage($"No backends available for {serviceIdentifier}!!!"); var nmqm = MessageHelpers.CreateNetMQErrorMessage(envelope, "No backends found", message.Metadata); e.Socket.SendMultipartMessage(nmqm); } } } catch (Exception ex) { this.OnDiagnosticMessage(ex.Message + ": " + ex.StackTrace); } }; this.FrontendBuffer.ReceiveReady += (sender, e) => { try { while (this.FrontendBuffer.TryDequeue(out TransportMessage message, TimeSpan.Zero)) { if (!message.Metadata.TryPluckLast($"envelope[{this.Identity}]", out var envelope)) { throw new Exception("Message envelope not found"); } if (!frontendSocket.TrySendMultipartMessage(TimeSpan.FromSeconds(1), message.ToNetMQMessage(envelope))) { this.OnDiagnosticMessage("Failed to forward to frontend"); } } } catch (Exception ex) { this.OnDiagnosticMessage(ex.Message + ": " + ex.StackTrace); } }; monitor.Listening += (sender, e) => { this.OnDiagnosticMessage($"Frontend router socket listening at {connectionString}"); isListening = true; }; monitor.Closed += (sender, e) => { this.OnDiagnosticMessage($"Frontend router socket closed on {connectionString}"); isListening = false; }; monitor.Accepted += (sender, e) => { this.OnDiagnosticMessage($"Frontend router socket connection accepted at {connectionString}"); }; monitor.Disconnected += (sender, e) => { this.OnDiagnosticMessage($"Frontend router socket disconnected at {connectionString}"); }; this.OnDiagnosticMessage($"Attempting to bind frontend socket to {connectionString}"); monitor.StartAsync(); monitor.AttachToPoller(poller); var pollerTask = new Task(poller.Run); pollerTask.ContinueWith(task => { var ex = task.Exception; this.OnDiagnosticMessage(ex.Message + ": " + ex.StackTrace); isListening = false; }, TaskContinuationOptions.OnlyOnFaulted); pollerTask.Start(); frontendSocket.Bind(connectionString); var start = DateTime.Now; while (!isListening) { if ((DateTime.Now - start).TotalMilliseconds > 5000) { throw new Exception($"Frontend socket bind timeout ({connectionString})"); } await Task.Delay(1000); } while (this.IsRunning && isListening) { await Task.Delay(1000); } poller.StopAsync(); frontendSocket.Disconnect(connectionString); monitor.DetachFromPoller(); monitor.Stop(); } } catch (Exception ex) { this.OnDiagnosticMessage(ex.Message + ": " + ex.StackTrace); } } }
private async Task BackendHandler() { while (this.IsRunning) { try { while (this.RegisteredBackendIdentifiers.TryDequeue(out string identifier)) { } bool isListening = false; var connectionString = this.BackendEndpoint.ToConnectionString(); using (var backendSocket = new RouterSocket()) using (this.AltBackendBuffer = new NetMQQueue <TransportMessage>()) using (var poller = new NetMQPoller() { backendSocket, this.AltBackendBuffer }) using (var monitor = new NetMQ.Monitoring.NetMQMonitor(backendSocket, $"inproc://monitor.routerdevice.backend.{Guid.NewGuid().ToString()}", SocketEvents.Listening | SocketEvents.Disconnected | SocketEvents.Closed | SocketEvents.BindFailed)) { backendSocket.ReceiveReady += (sender, e) => { try { //Console.WriteLine("Backend message received"); //Console.WriteLine($"RECEIVED BACKEND ({this.BackendSocket.HasIn}) ({this.BackendSocket.HasOut})"); var netmqMessage = new NetMQMessage(); while (e.Socket.TryReceiveMultipartMessage(ref netmqMessage)) { var message = netmqMessage.ToMessage(out var envelope); this.OnBackendReceived(message); //this.BackendBuffer.Enqueue(message); if (message.Metadata.TryPluck("Greeting", out var encodedGreeting)) { var identifier = BitConverter.ToString(envelope); if (this.RegisteredBackends.TryAdd(identifier, new RegisteredBackend(envelope, DateTime.UtcNow))) { Console.WriteLine($"Backend registered [ {identifier} ]"); this.RegisteredBackendIdentifiers.Enqueue(identifier); } else { this.RegisteredBackends[identifier].RegsiteredDate = DateTime.UtcNow; } } else { this.AltFrontendBuffer.Enqueue(message); } } } catch (Exception ex) { Console.WriteLine(ex.Message + ": " + ex.StackTrace); } }; //var lastFlushed = DateTime.UtcNow; //backendSocket.SendReady += (sender, e) => //{ // try // { // if (!this.FrontendBuffer.IsEmpty) // { // while (this.FrontendBuffer.TryDequeue(out Message message)) // { // Console.WriteLine("Frontend forwarding"); // if (!e.Socket.TrySendMultipartMessage(TimeSpan.FromSeconds(1), message.ToNetMQMessage(true))) // { // Console.WriteLine("Failed to forward to backend"); // //var forwardedMessage = new Message(1, message.Frames, System.Text.Encoding.UTF8.GetBytes("Failed to forward to backend"), sourceEnvelope); // //this.FrontendSocket.SendMultipartMessage(forwardedMessage.ToNetMQMessage(true)); // } // } // lastFlushed = DateTime.UtcNow; // } // if ((DateTime.UtcNow - lastFlushed).TotalSeconds > 1) // Task.Delay(1).Wait(); // } // catch (Exception ex) // { // Console.WriteLine(ex.Message + ": " + ex.StackTrace); // } //}; this.AltBackendBuffer.ReceiveReady += (sender, e) => { try { while (this.AltBackendBuffer.TryDequeue(out TransportMessage message, TimeSpan.Zero)) { if (!message.Metadata.TryPluck($"backendEnvelope[{this.Identity}]", out var envelope)) { throw new Exception("Message backend envelope not found"); } this.OnFrontendForwarded(message); if (!backendSocket.TrySendMultipartMessage(TimeSpan.FromSeconds(1), message.ToNetMQMessage(envelope))) { Console.WriteLine("Failed to forward to backend"); //var forwardedMessage = new Message(1, message.Frames, System.Text.Encoding.UTF8.GetBytes("Failed to forward to backend"), sourceEnvelope); //this.FrontendSocket.SendMultipartMessage(forwardedMessage.ToNetMQMessage(true)); } } } catch (Exception ex) { Console.WriteLine(ex.Message + ": " + ex.StackTrace); } }; monitor.Listening += (sender, e) => { Console.WriteLine($"Backend router socket listening at {connectionString}"); isListening = true; }; monitor.Closed += (sender, e) => { Console.WriteLine($"Backend router socket accepted connection on {connectionString}"); isListening = false; }; monitor.Disconnected += (sender, e) => { Console.WriteLine($"Backend router socket disconnected at {connectionString}"); }; monitor.BindFailed += (sender, e) => { Console.WriteLine($"Backend router bind failed {connectionString}"); }; Console.WriteLine($"Attempting to bind backend socket to {connectionString}"); monitor.StartAsync(); monitor.AttachToPoller(poller); var pollerTask = new Task(poller.Run); pollerTask.ContinueWith((Task task) => { var ex = task.Exception; Console.WriteLine(ex.Message + ": " + ex.StackTrace); isListening = false; }, TaskContinuationOptions.OnlyOnFaulted); pollerTask.Start(); backendSocket.Bind(connectionString); var start = DateTime.Now; while (!isListening) { if ((DateTime.Now - start).TotalMilliseconds > 5000) { throw new Exception($"Backend socket bind timeout ({connectionString})"); } await Task.Delay(1000); } while (this.IsRunning && isListening) { if (this.BackendAnnouncer != null) { //Console.WriteLine("Registering backend"); await this.BackendAnnouncer.Register(this.BackendEndpoint); } await Task.Delay(1000); } poller.StopAsync(); backendSocket.Disconnect(connectionString); monitor.DetachFromPoller(); monitor.Stop(); } } catch (Exception ex) { Console.WriteLine(ex.Message + ": " + ex.StackTrace); } } }
private async Task Handler() { while (this.IsRunning) { try { using (var socket = new DealerSocket()) using (this.BackendBuffer = new NetMQQueue <TransportMessage>()) using (var poller = new NetMQPoller() { socket, this.BackendBuffer }) using (var monitor = new NetMQ.Monitoring.NetMQMonitor(socket, $"inproc://monitor.forwarderdevice.backend.{Guid.NewGuid().ToString()}", SocketEvents.Connected | SocketEvents.Disconnected)) { socket.Options.Identity = System.Text.Encoding.ASCII.GetBytes(Guid.NewGuid().ToString().Replace("-", "").ToLowerInvariant()); socket.ReceiveReady += (sender, e) => { try { var netmqMessage = new NetMQMessage(); if (e.Socket.TryReceiveMultipartMessage(ref netmqMessage)) { var message = netmqMessage.ToMessage(); this.ForwarderDevice.OnBackendReceived(message); this.ForwarderDevice.frontendBuffer.Enqueue(message); } } catch (Exception ex) { this.ForwarderDevice.OnDiagnosticMessage(ex.Message + ": " + ex.StackTrace); } }; this.BackendBuffer.ReceiveReady += (sender, e) => { try { while (this.BackendBuffer.TryDequeue(out TransportMessage message, TimeSpan.Zero)) { this.ForwarderDevice.OnFrontendForwarded(message); this.ForwarderDevice.OnDiagnosticMessage("Forwarding message to " + this.Endpoint.ToConnectionString()); if (!socket.TrySendMultipartMessage(TimeSpan.FromSeconds(1), message.ToNetMQMessage())) { this.ForwarderDevice.OnDiagnosticMessage("Failed to send message"); } } } catch (Exception ex) { this.ForwarderDevice.OnDiagnosticMessage(ex.Message + ": " + ex.StackTrace); } }; monitor.Connected += (sender, e) => { this.ForwarderDevice.OnDiagnosticMessage($"Dealer socket conntected to {this.Endpoint.ToConnectionString()}"); this.IsConnected = true; }; monitor.Disconnected += (sender, e) => { this.ForwarderDevice.OnDiagnosticMessage($"Dealer socket disconntected from {this.Endpoint.ToConnectionString()}"); this.IsConnected = false; }; this.ForwarderDevice.OnDiagnosticMessage($"Attempting to connect to {this.Endpoint.ToConnectionString()}"); monitor.StartAsync(); monitor.AttachToPoller(poller); var pollerTask = new Task(poller.Run); pollerTask.ContinueWith((Task task) => { var ex = task.Exception; this.ForwarderDevice.OnDiagnosticMessage(ex.Message + ": " + ex.StackTrace); this.IsConnected = false; }, TaskContinuationOptions.OnlyOnFaulted); pollerTask.Start(); socket.Connect(this.Endpoint.ToConnectionString()); var start = DateTime.Now; while (!this.IsConnected) { if ((DateTime.Now - start).TotalMilliseconds > 5000) { throw new Exception($"Connection timeout [{this.ServiceName}]"); } await Task.Delay(1000); } while (this.IsConnected && this.IsRunning) { await Task.Delay(1000); } this.ForwarderDevice.OnDiagnosticMessage("Closing dealer socket..."); poller.StopAsync(); socket.Disconnect(this.Endpoint.ToConnectionString()); monitor.DetachFromPoller(); monitor.Stop(); this.IsConnected = false; } if (this.IsRunning) { await Task.Delay(1000); } } catch (Exception ex) { this.ForwarderDevice.OnDiagnosticMessage(ex.Message + ": " + ex.StackTrace); } } }
private async Task FrontendHandler() { while (this.IsRunning) { try { bool isListening = false; var connectionString = this.FrontendEndpoint.ToConnectionString(); using (var frontendSocket = new RouterSocket()) using (this.AltFrontendBuffer = new NetMQQueue <TransportMessage>()) using (var poller = new NetMQPoller() { frontendSocket, this.AltFrontendBuffer }) using (var monitor = new NetMQ.Monitoring.NetMQMonitor(frontendSocket, $"inproc://monitor.routerdevice.frontend.{Guid.NewGuid().ToString()}", SocketEvents.Listening | SocketEvents.Accepted | SocketEvents.Disconnected | SocketEvents.Closed)) { frontendSocket.ReceiveReady += (sender, e) => { try { var netmqMessage = new NetMQMessage(); while (e.Socket.TryReceiveMultipartMessage(ref netmqMessage)) { //Console.WriteLine("Frontend message received"); var message = netmqMessage.ToMessage(out var envelope); this.OnFrontendReceived(message); //this.receiveCount++; //Console.WriteLine("RECEIVED " + this.receiveCount); //var sourceEnvelope = message.Envelope; RegisteredBackend registeredBackend = null; var forwardStart = DateTime.UtcNow; while (this.IsRunning && registeredBackend == null) { while (this.RegisteredBackendIdentifiers.TryDequeue(out string backendIdentifier)) { registeredBackend = this.RegisteredBackends[backendIdentifier]; if ((DateTime.UtcNow - registeredBackend.RegsiteredDate).TotalMilliseconds < 2000) { this.RegisteredBackendIdentifiers.Enqueue(backendIdentifier); break; } else { if (this.RegisteredBackends.TryRemove(backendIdentifier, out RegisteredBackend expiredBackend)) { Console.WriteLine($"Backend {backendIdentifier} expired"); } } } if (registeredBackend != null || (DateTime.Now - forwardStart).TotalMilliseconds > 30000) { break; } System.Threading.Thread.Sleep(100); } if (registeredBackend != null) { //Console.WriteLine($"Forwarding to [ {BitConverter.ToString(registeredBackend.Envelope)} ]"); message.Metadata.Add($"envelope[{this.Identity}]", envelope); message.Metadata.Add($"backendEnvelope[{this.Identity}]", registeredBackend.Envelope); this.AltBackendBuffer.Enqueue(message); ////this.BackendSocket.SendMultipartMessage(message.ToNetMQMessage(true)); //if (!this.BackendSocket.TrySendMultipartMessage(TimeSpan.FromSeconds(1), message.ToNetMQMessage(true))) //{ // Console.WriteLine("Failed to forward to backend"); // var forwardedMessage = new Message(1, message.Frames, System.Text.Encoding.UTF8.GetBytes("Failed to forward to backend"), sourceEnvelope); // this.FrontendSocket.SendMultipartMessage(forwardedMessage.ToNetMQMessage(true)); //} } else { Console.WriteLine("No backends available!!!"); var nmqm = MessageHelpers.CreateNetMQErrorMessage(envelope, "No backends found", message.Metadata); e.Socket.SendMultipartMessage(nmqm); } } } catch (Exception ex) { Console.WriteLine(ex.Message + ": " + ex.StackTrace); } }; //var lastFlushed = DateTime.UtcNow; //frontendSocket.SendReady += (sender, e) => //{ // try // { // if (!this.BackendBuffer.IsEmpty) // { // while (this.BackendBuffer.TryDequeue(out Message message)) // { // Console.WriteLine("Backend forwarding"); // if (!e.Socket.TrySendMultipartMessage(TimeSpan.FromSeconds(1), message.ToNetMQMessage(true))) // { // Console.WriteLine("Failed to forward to frontend"); // //var forwardedMessage = new Message(1, message.Frames, System.Text.Encoding.UTF8.GetBytes("Failed to forward to backend"), sourceEnvelope); // //this.FrontendSocket.SendMultipartMessage(forwardedMessage.ToNetMQMessage(true)); // } // } // lastFlushed = DateTime.UtcNow; // } // if ((DateTime.UtcNow - lastFlushed).TotalSeconds > 1) // Task.Delay(1).Wait(); // } // catch (Exception ex) // { // Console.WriteLine(ex.Message + ": " + ex.StackTrace); // } //}; this.AltFrontendBuffer.ReceiveReady += (sender, e) => { try { while (this.AltFrontendBuffer.TryDequeue(out TransportMessage message, TimeSpan.Zero)) { if (!message.Metadata.TryPluck($"envelope[{this.Identity}]", out var envelope)) { throw new Exception("Message envelope not found"); } this.OnBackendForwarded(message); if (!frontendSocket.TrySendMultipartMessage(TimeSpan.FromSeconds(1), message.ToNetMQMessage(envelope))) { Console.WriteLine("Failed to forward to frontend"); } } } catch (Exception ex) { Console.WriteLine(ex.Message + ": " + ex.StackTrace); } }; monitor.Listening += (sender, e) => { Console.WriteLine($"Frontend router socket listening at {connectionString}"); isListening = true; }; monitor.Closed += (sender, e) => { Console.WriteLine($"Frontend router socket closed on {connectionString}"); isListening = false; }; monitor.Accepted += (sender, e) => { Console.WriteLine($"Frontend router socket connection accepted at {connectionString}"); }; monitor.Disconnected += (sender, e) => { Console.WriteLine($"Frontend router socket disconnected at {connectionString}"); }; Console.WriteLine($"Attempting to bind frontend socket to {connectionString}"); monitor.StartAsync(); monitor.AttachToPoller(poller); var pollerTask = new Task(poller.Run); pollerTask.ContinueWith((Task task) => { var ex = task.Exception; Console.WriteLine(ex.Message + ": " + ex.StackTrace); isListening = false; }, TaskContinuationOptions.OnlyOnFaulted); pollerTask.Start(); frontendSocket.Bind(connectionString); var start = DateTime.Now; while (!isListening) { if ((DateTime.Now - start).TotalMilliseconds > 5000) { throw new Exception($"Frontend socket bind timeout ({connectionString})"); } await Task.Delay(1000); } while (this.IsRunning && isListening) { if (this.FrontendAnnouncer != null) { //Console.WriteLine("Registering frontend"); await this.FrontendAnnouncer.Register(this.FrontendEndpoint); } await Task.Delay(1000); } poller.StopAsync(); frontendSocket.Disconnect(connectionString); monitor.DetachFromPoller(); monitor.Stop(); } } catch (Exception ex) { Console.WriteLine(ex.Message + ": " + ex.StackTrace); } } }