Exemple #1
0
    public IConnection Create(ConnectionType type)
    {
        var endpoints = _hostNames
                        .Select(node =>
        {
            var parts = node.Split(":", StringSplitOptions.RemoveEmptyEntries);

            var hostName = parts[0];

            if (parts.Length == 1)
            {
                return(new AmqpTcpEndpoint(hostName));
            }

            var port = int.Parse(parts[1]);

            return(new AmqpTcpEndpoint(hostName, port));
        }).ToArray();

        var endpointResolver = new DefaultEndpointResolver(endpoints);

        var identity = type.ToString().ToLower();
        var id       = $"{_serviceId}/{identity}";

        if (_connectionFactory == null)
        {
            lock (this)
            {
                _connectionFactory ??= CreateConnectionFactory(_userName, _password, _virtualHost, id, type);
            }
        }

        return(_connectionFactory.CreateConnection(endpointResolver, id));
    }
        protected void Connect()
        {
            try
            {
                /*
                 * When you create a new vhost on a cluster - don't forget to enable a HA-policy for that vhost (even if you don’t have
                 * a HA setup, you will need it for plan changes). Messages will not be synced between nodes without an HA-policy.
                 */

                IEndpointResolver endpointResolver = new DefaultEndpointResolver(_connectionConfig.EndPoints);

                // Builds up url in the format
                // "amqp://*****:*****@192.168.1.1:5672/virtual-host"
                var factory = new ConnectionFactory
                {
                    UserName    = _connectionConfig.UserName,
                    Password    = _connectionConfig.Password,
                    VirtualHost = _connectionConfig.VirtualHost,
                    HandshakeContinuationTimeout = new TimeSpan(TimeSpan.TicksPerSecond * 5),
                    RequestedConnectionTimeout   = 3000
                };

                _logger.LogInformation($"Connecting...");

                _connection = factory.CreateConnection(endpointResolver, "this is my client name");

                _logger.LogInformation(
                    $"Connected to {_connection.Endpoint.HostName}:{_connection.Endpoint.Port}"); // successful and unsuccessful client connection events can be observed in server node logs

                _channel = _connection.CreateModel();

                /*
                 * ExchangeType.Direct  - A message goes to the queue(s) whose binding key exactly matches the routing key of the message.
                 *
                 * ExchangeType.Fanout  - The fanout copies and routes a received message to all queues that are bound to it regardless of
                 *                        routing keys or pattern matching as with direct and topic exchanges. Keys provided will simply be ignored.
                 *                        Fanout exchanges can be useful when the same message needs to be sent to one or more queues with
                 *                        consumers who may process the same message in different ways.
                 *
                 * ExchangeType.Headers - Headers exchanges route based on arguments containing headers and optional values. Headers exchanges
                 *                        are very similar to topic exchanges, but it routes based on header values instead of routing keys.
                 *                        A message is considered matching if the value of the header equals the value specified upon binding.
                 *
                 * ExchangeType.Topic   - Topic exchanges route messages to queues based on wildcard matches between the routing key and
                 *                        the routing pattern specified by the queue binding. Messages are routed to one or many queues based
                 *                        on a matching between a message routing key and this pattern.
                 *                        eg;  crypro.gdax.btc.usd.hour-1    stock.lse.gsk.gbp.hour-24
                 *
                 * Dead Letter Exchange - If no matching queue can be found for the message, the message is silently dropped. RabbitMQ provides
                 *                        an AMQP extension known as the "Dead Letter Exchange" - the dead letter exchange provides functionality
                 *                        to capture messages that are not deliverable.
                 */
                _channel.ExchangeDeclare(_channelConfig.ExchangeName, ExchangeType.Direct);
                _channel.ModelShutdown += Channel_ModelShutdown;

                // Persistent messages and durable queues for a message to survive a server restart = resilient / lower performance
                // for high throughput send transient messages to non-lazy queues

                // Limit queue size with TTL or max-length (queue will discard messages from the head of queue to keep within mex-length)
                _channel.QueueDeclare(_channelConfig.QueueName, true, false, false, null);
                _channel.QueueBind(_channelConfig.QueueName, _channelConfig.ExchangeName,
                                   _channelConfig.RoutingKey, null);

                // https://rabbitmq.github.io/rabbitmq-dotnet-client/api/RabbitMQ.Client.IModel.html
                _logger.LogInformation(
                    $"Using channel {_channel.ChannelNumber}, which has timeout of {_channel.ContinuationTimeout.TotalSeconds} seconds");

                _isConnected = true;
            }
            catch (BrokerUnreachableException)
            {
                _logger.LogError("Coinbase.Application.RabbitMq.Client.Connect() None of the specified endpoints were reachable; endpoints: {EndPoints} vhost: {VirtualHost}",
                                 string.Join(',', _connectionConfig.EndPoints.Select(i => $"{i.HostName}:{i.Port}")),
                                 _connectionConfig.VirtualHost);
            }
            catch (Exception e)
            {
                _logger.LogError(e, "Unhandled exception during Coinbase.Application.RabbitMq.Client.Connect");
            }
        }