配置:

1.1RabbitMQ集群环境搭建和环境变量:

每台服务器安装RabbitMQ,下载地址:https://www.rabbitmq.com/docs/install-windows#installer

环境变量Path 值 添加:rabbitmq安装目录的sbin目录

1.2安装Erlang和配置环境变量

每台服务器安装Erlang,下载地址:https://www.erlang.org/downloads

环境变量Path值添加:Erlang安装目录的bin目录

1.3安装Rabbitmq服务

运行cmd窗体输入 rabbitmq-plugins enable rabbitmq_management 命令进行安装

1.4集群配置

绑定ip计算机名称 (C:\Windows\System32\drivers\etc)

ip1 计算机名1

ip2 计算机名2

ip3 计算机名3

拷贝其中一台服务器上的 C:\Windows和C:\Users\Administrator\.erlang.cookie 文件复制到另外几台服务器上

分别在几个服务器上运行 rabbitmq-server -detached,启动 rabbit 节点服务。

在 rabbit@rabbit1 节点服务器上运行 rabbitmqctl stop_app,停止 rabbit 节点程序。

在 rabbit@rabbit1 节点服务器上运行 rabbitmqctl join_cluster rabbit@rabbit2,将节点 rabbit@rabbit1 和 rabbit@rabbit2 组成集群。

在 rabbit@rabbit1 节点服务器上运行 rabbitmqctl join_cluster rabbit@rabbit3,将节点 rabbit@rabbit1 和 rabbit@rabbit3 组成集群。

分别在服务器上运行 rabbitmqctl start_app,启动 rabbit 节点程序。

运行 rabbitmqctl  cluster_status 查看集群的运行状态。

访问http://localhost:15672/ 默认帐号:guest 密码:guest 

使用镜像队列

 

策略名随便填

正则表达式:^

Apply to:Queues

Definition:ha-mode:exactly、ha-params:2、ha-sync-mode:automatic

2.添加RabbitMQ包

3.配置类:

public class RabbitMq
{
  private readonly IHubContext<XXHub> _hubContext;
  private const string ExchangeName = "SignalRExchange";
  private const string QueueAName = "ServerAQueue";
  private const string QueueBName = "ServerBQueue";
  private const string QueueCName = "ServerCQueue";
  private const string RoutingKey = "ServerQueueKey";

  public RabbitMq(IHubContext<XXHub> hubContext)
  {
    _hubContext = hubContext;
  }

  public static void SetupExchangeAndQueues()
  {
    var factory = new ConnectionFactory() { HostName = "localhost", UserName = "guest", Password = "guest" };
    using (var connection = factory.CreateConnection())
    using (var channel = connection.CreateModel())
    {
      //channel.ExchangeDeclare(ExchangeName, ExchangeType.Direct);//创建Direct类型的交换机

      //channel.QueueDeclare(QueueAName, false, false, false, null);//创建队列A
      //channel.QueueBind(QueueAName, ExchangeName, RoutingKey);//将队列A绑定到交换机

      //channel.QueueDeclare(QueueBName, false, false, false, null);//创建队列B
      //channel.QueueBind(QueueBName, ExchangeName, RoutingKey);//将队列B绑定到交换机

      //channel.QueueDeclare(QueueCName, false, false, false, null);//创建队列C
      //channel.QueueBind(QueueCName, ExchangeName, RoutingKey);//将队列C绑定到交换机
    }
  }

  public void SendMessageToExchange(string message)
  {
    var factory = new ConnectionFactory() { HostName = "localhost", UserName = "guest", Password = "guest" };
    using (var connection = factory.CreateConnection())
    using (var channel = connection.CreateModel())
    {
      var body = Encoding.UTF8.GetBytes(message);

      channel.BasicPublish(exchange: ExchangeName, routingKey: RoutingKey, basicProperties: null, body: body);//发送消息到队列
    }
  }

  public async Task ConsumeMessageFromQueue()
  {
    var factory = new ConnectionFactory() { HostName = "localhost", UserName = "guest", Password = "guest" };
    using (var connection = factory.CreateConnection())
    using (var channel = connection.CreateModel())
    {
      var consumer = new EventingBasicConsumer(channel);
      consumer.Received += async (model, ea) =>
      {
        var body = ea.Body.ToArray();
        var message = Encoding.UTF8.GetString(body);

        try
        {
          ReciveData reciveData = JsonConvert.DeserializeObject<ReciveData>(message);
          if (reciveData != null)
          {
            foreach (var item in reciveData.ConnectionIds)
            {
              await _hubContext.Clients.Client(item).SendAsync("ReceiveData", JsonConvert.SerializeObject(reciveData));//将队列数据返回
            }
          }
        }
        catch (Exception ex)
        {
          //await _hubContext.Clients.All.SendAsync("Msg", "错误:" + ex.ToString());
        }

        //channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false);
      };

      await Task.Delay(0);
      channel.BasicConsume(queue: QueueBName, autoAck: true, consumer: consumer);//消费服务器A队列的消息
      channel.BasicConsume(queue: QueueBName, autoAck: true, consumer: consumer);//消费服务器B队列的消息
      channel.BasicConsume(queue: QueueCName, autoAck: true, consumer: consumer);//消费服务器C队列的消息
    }
  }
}