关于RabbitMQ消息队列中广播消息监听服务的抽象类以及实现

16 篇文章 0 订阅

关于RabbitMQ消息队列中广播消息监听服务的抽象类的定义,应该包含以下方法:

1.消息队列的名称

2.接收消息的数量

3.帮定的交换机(exchange)的名称

4.接收到消息后的自定义处理方法

5.消息过滤方法

实现代码如下,基于Net5实现:

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using JuCheap.Core.MQ;
using JuCheap.Models.Enum;
using JuCheap.Models.MQMessage;
using Newtonsoft.Json;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace JuCheap.Core
{
    /// <summary>
    /// 广播消息队列监听抽象类
    /// </summary>
    public abstract class JuCheapMQBaseListner
    {
        private ManualResetEvent _manualResetEvent = new(false);
        private readonly ILogger<MTalkMQBaseListner> _logger;
        private readonly IConfiguration _config;

        public JuCheapMQBaseListner(ILoggerFactory loggerFactory, IConfiguration config)
        {
            _logger = loggerFactory.CreateLogger<MTalkMQBaseListner>();
            _config = config;
        }

        /// <summary>
        /// 获取RabbitMQ队列名称
        /// </summary>
        /// <returns></returns>
        public abstract string GetQueueName();

        /// <summary>
        /// 获取交换机名称
        /// </summary>
        /// <returns></returns>
        public abstract string GetExchangeName();

        /// <summary>
        /// 获取接收消息的条数(小于等于0为不限制)
        /// </summary>
        /// <returns></returns>
        public abstract ushort GetReceiveMessageNumber();

        /// <summary>
        /// 订阅的消息类型
        /// </summary>
        public abstract List<MQMessageType> GetSubscribeMessageTypes();

        /// <summary>
        /// 接收消息自定义处理方法
        /// </summary>
        /// <param name="messageType">报文消息类型</param>
        /// <param name="message">报文Json数据</param>
        /// <returns></returns>
        public abstract Task OnMessageReceived(MQMessageType messageType, string message);

        /// <summary>
        /// 接收消息处理方法
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public async void OnBaseMessageReceived(object sender, BasicDeliverEventArgs e)
        {
            try
            {
                var channel = ((IBasicConsumer)sender).Model;

                var message = Encoding.UTF8.GetString(e.Body.ToArray());

                Console.WriteLine($"接收到消息队列的消息({GetQueueName()}) -> {message}");
                Console.WriteLine(Environment.NewLine);

                var eventMessage = JsonConvert.DeserializeObject<MQMessageDTO>(message);
                var isSubscribe = GetSubscribeMessageTypes().Contains(eventMessage.Type);
                if (!string.IsNullOrWhiteSpace(eventMessage.Message) && isSubscribe)
                {
                    await OnMessageReceived(eventMessage.Type, eventMessage.Message);
                }

                //确认消息消费完毕
                channel.BasicAck(e.DeliveryTag, multiple: false);

            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"报文数据入库失败({GetQueueName()})");
                Console.WriteLine($"报文数据入库失败({GetQueueName()}):{ex}");
                Console.WriteLine(Environment.NewLine);
            }
        }

        /// <summary>
        /// 开始监听
        /// </summary>
        public void StartListenerMessage()
        {
            new TaskFactory().StartNew(() =>
            {
                try
                {
                    //rabbitmq 用户名
                    var userName = _config.GetValue<string>("MQ:UserName");
                    //rabbitmq 密码
                    var password = _config.GetValue<string>("MQ:Password");
                    //rabbitmq 服务地址
                    var hostName = _config.GetValue<string>("MQ:Host");
                    //rabbitmq exchange名称
                    var exchangeName = GetExchangeName();

                    using (var connection = RabbitMqClientFactory.CeateConnection(userName, password, hostName))
                    {
                        using (var channel = connection.CreateModel())
                        {
                            //申明交换机
                            channel.ExchangeDeclare(exchangeName, "fanout", true);
                            //设置消息发送的数量
                            var number = GetReceiveMessageNumber();
                            if (number > 0)
                            {
                                channel.BasicQos(0, number, false);
                            }
                            //定义队列名称
                            var queueName = channel.QueueDeclare(GetQueueName(), true, false, false, null).QueueName;
                            //将消息队列和交换机绑定
                            channel.QueueBind(queueName, exchangeName, string.Empty);
                            var consumer = new EventingBasicConsumer(channel);
                            consumer.Received += OnBaseMessageReceived;
                            channel.BasicConsume(queueName, false, consumer);

                            _logger.LogInformation($"---------------------MQ消息队列监听服务启动成功({GetQueueName()})---------------------{Environment.NewLine}");
                            _manualResetEvent.WaitOne();
                        }
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogError($"MQ Consumer {GetQueueName()} Start Failed", ex);
                }
            }, TaskCreationOptions.LongRunning);
        }
    }
}

子类的实现如下:

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using JuCheap.Core;
using JuCheap.Models.Enum;
using JuCheap.MQTT.Gather;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace JuCheap.Core.BackMessageService.MQ
{
    /// <summary>
    /// 流量计实时数据报警处理
    /// </summary>
    public class RealDataAlarmMQListner : JuCheapMQBaseListner
    {
        private readonly IServiceScopeFactory _factory;

        public RealDataAlarmMQListner(IServiceScopeFactory factory, ILoggerFactory loggerFactory, IConfiguration config) : 
            base(loggerFactory, config)
        {
            _factory = factory;
        }

        /// <summary>
        /// 设置队列名称
        /// </summary>
        /// <returns></returns>
        public override string GetQueueName()
        {
            return "JuCheap_RealDataAlarm";
        }

        /// <summary>
        /// 设置交换机名称
        /// </summary>
        /// <returns></returns>
        public override string GetExchangeName()
        {
            return MQContants.DeviceExchangeName;
        }

        /// <summary>
        /// 同时处理消息的最大条数
        /// </summary>
        /// <returns></returns>
        public override ushort GetReceiveMessageNumber()
        {
            return 1;
        }

        /// <summary>
        /// 订阅消息类型
        /// </summary>
        /// <returns></returns>
        public override List<MQMessageType> GetSubscribeMessageTypes()
        {
            return new List<MQMessageType> 
            {
                MQMessageType.RealData
            };
        }

        /// <summary>
        /// 接收消息处理方法
        /// </summary>
        /// <param name="messageType">消息类型</param>
        /// <param name="message">json消息</param>
        /// <returns></returns>
        public override async Task OnMessageReceived(MQMessageType messageType, string message)
        {
            using (var scope = _factory.CreateScope())
            {
                await Task.CompletedTask;
            }
        }
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值