public static void Main() { RabbitMqConsoleEventListener loggingEventSource = new RabbitMqConsoleEventListener(); // Set default interval for heartbeats // Reduce the heartbeat interval so that bad connections are detected sooner than the default of 60s ushort heartbeatInterval = 20; if (ushort.TryParse(Environment.GetEnvironmentVariable("HEARTBEAT_INTERVAL_SEC"), out heartbeatInterval)) { Console.WriteLine("Setting heartbeat interval from HEARTBEAT_INTERVAL_SEC"); } else { Console.WriteLine("HEARTBEAT_INTERVAL_SEC environment variable not defined, using default."); heartbeatInterval = 20; } Console.WriteLine("Setting heartbeat interval to {0} s", heartbeatInterval); int port = 5670; if (int.TryParse(Environment.GetEnvironmentVariable("RABBITMQ_NODE_PORT"), out port)) { Console.WriteLine("Setting port from RABBITMQ_NODE_PORT"); } else { port = 5670; } Console.WriteLine("Port: {0}", port); if (Environment.GetEnvironmentVariable("VCAP_SERVICES") == null) { // Not running on Cloud Foundry factory = new ConnectionFactory() { HostName = "localhost", UserName = "******", Password = "******", Port = port, AutomaticRecoveryEnabled = true, RequestedHeartbeat = heartbeatInterval }; } else { // Running on PCF services = new ServiceCollection(); var config = new ConfigurationBuilder() .AddEnvironmentVariables() .AddCloudFoundry() .Build(); services.AddRabbitConnection(config); factory = services.BuildServiceProvider().GetService <ConnectionFactory>(); } taskQueueName = Environment.GetEnvironmentVariable("QUEUE_NAME"); if (taskQueueName == null) { taskQueueName = "task_queue"; } Console.WriteLine("Setting queue name to {0}", taskQueueName); // Since we have a durable queue anyways, there should be no need to recreate it on a connection failure. // Otherwise this currently can result in exceptions (if the durable queue home node is down), that // hangs the RMQ client. if (bool.TryParse(Environment.GetEnvironmentVariable("TOPOLOGY_RECOVERY_ENABLED"), out enableTopologyRecovery)) { Console.WriteLine("Setting topology recovery from TOPOLOGY_RECOVERY_ENABLED"); } else { enableTopologyRecovery = true; } factory.TopologyRecoveryEnabled = enableTopologyRecovery; Console.WriteLine("Topology recovery enabled: {0}", factory.TopologyRecoveryEnabled); using (connection = factory.CreateConnection()) { // An autorecovery occurred connection.RecoverySucceeded += (sender, e) => { if (enableTopologyRecovery) { /* * Note: if consumer.IsRunning is false here, it could just be because the Registered event * has not yet fired for the recovered consumer */ Console.WriteLine("RecoverySucceeded, now waiting on Registered event - ThreadId: {0}", Thread.CurrentThread.ManagedThreadId); if (consumerRegistered.Wait(factory.ContinuationTimeout)) { Console.WriteLine("RecoverySucceeded, consumer restarted - Consumer tag: {0} IsRunning: {1}", consumer.ConsumerTag, consumer.IsRunning); } else { Console.WriteLine("RecoverySucceeded, consumer did not restart! - Consumer tag: {0}", consumer.ConsumerTag); CreateConsumer(taskQueueName); } } else { /* * Without topology recovery enabled, we are forced to create a new consumer */ Console.WriteLine("RecoverySucceeded, topology recovery disabled, creating a new consumer"); CreateConsumer(taskQueueName); } }; using (channel = connection.CreateModel()) { channel.CallbackException += (sender, e) => Console.WriteLine(e.Exception); channel.ModelShutdown += (sender, e) => Console.WriteLine($"Channel closed: {e.Cause?.ToString()}"); channel.QueueDeclare(queue: taskQueueName, durable: true, exclusive: false, autoDelete: false, arguments: null); Console.WriteLine("Creating initial consumer and waiting for Registered..."); CreateConsumer(taskQueueName); if (consumerRegistered.Wait(factory.ContinuationTimeout)) { Console.WriteLine("Initial consumer started - Consumer tag: {0} IsRunning: {1}", consumer.ConsumerTag, consumer.IsRunning); while (true) { consumerLock.EnterReadLock(); try { Console.WriteLine("Current consumer tag: {0} IsRunning: {1} ThreadId: {2}", consumer.ConsumerTag, consumer.IsRunning, Thread.CurrentThread.ManagedThreadId); } finally { consumerLock.ExitReadLock(); } Thread.Sleep(TimeSpan.FromSeconds(5)); } } else { Console.WriteLine("Initial consumer did not start!"); } } } }
public static void Main(string[] args) { RabbitMqConsoleEventListener loggingEventSource = new RabbitMqConsoleEventListener(); int numMsgsPublished = 1; // Set default interval to publish messages ushort heartbeatInterval = 20; string heartbeatIntervalStr = Environment.GetEnvironmentVariable("HEARTBEAT_INTERVAL_SEC"); if (heartbeatIntervalStr == null) { Console.WriteLine("HEARTBEAT_INTERVAL_SEC environment variable not defined, using default."); } else { heartbeatInterval = Convert.ToUInt16(heartbeatIntervalStr); } Console.WriteLine("Setting heartbeat interval to {0} s", heartbeatInterval); // Set default interval to publish messages int publishIntervalSec = 600; string publishIntervalStr = Environment.GetEnvironmentVariable("PUBLISH_INTERVAL_SEC"); if (publishIntervalStr == null) { Console.WriteLine("PUBLISH_INTERVAL_SEC environment variable not defined, using default."); } else { publishIntervalSec = Convert.ToInt32(publishIntervalStr); } Console.WriteLine("Message publish interval is {0} s", publishIntervalSec); int publishInterval = publishIntervalSec * 1000; int port = 5672; string portStr = Environment.GetEnvironmentVariable("RABBITMQ_NODE_PORT"); if (portStr != null) { port = Convert.ToInt32(portStr); } var factory = new ConnectionFactory() { HostName = "localhost", Port = port }; if (Environment.GetEnvironmentVariable("VCAP_SERVICES") != null) { // Running on PCF IServiceCollection services = new ServiceCollection(); var config = new ConfigurationBuilder() .AddEnvironmentVariables() .AddCloudFoundry() .Build(); services.AddRabbitConnection(config); factory = services.BuildServiceProvider().GetService <ConnectionFactory>(); } taskQueueName = Environment.GetEnvironmentVariable("QUEUE_NAME"); if (taskQueueName == null) { taskQueueName = "task_queue"; } Console.WriteLine("Setting queue name to {0}", taskQueueName); // No need to explicitly set this value, default is already true // factory.AutomaticRecoveryEnabled = true; // Since we have a durable queue anyways, there should be no need to recreate it on a connection failure. // Otherwise this currently can result in exceptions (if the durable queue home node is down), that // hangs the RMQ client. factory.TopologyRecoveryEnabled = false; // Reduce the heartbeat interval so that bad connections are detected sooner than the default of 60s factory.RequestedHeartbeat = heartbeatInterval; using (var connection = factory.CreateConnection()) using (var channel = connection.CreateModel()) { channel.QueueDeclare(queue: taskQueueName, durable: true, exclusive: false, autoDelete: false, arguments: null); var message = "Happy Birthday!!"; var body = Encoding.UTF8.GetBytes(message); var properties = channel.CreateBasicProperties(); properties.Persistent = true; while (true) { channel.BasicPublish(exchange: "", routingKey: taskQueueName, basicProperties: properties, body: body); Console.WriteLine("Published {0} messages", numMsgsPublished++); Thread.Sleep(publishInterval); } } }