Location>code7788 >text

Based on EventBus EventBus to realize the email push function

Popularity:588 ℃/2024-08-27 00:09:48

Sometimes, someone leaves a comment on my site, but I have to open my site (/So I decided to add an email push function to my website, so that I can be the first to know. So, according to my own thinking, at the same time, in order to learn to understand rabbitmq and EventBus concept, I designed a set of mail push function, here to share out, may not be a very good program, we do not like do not spray.

What is the Event Bus

    An event bus is an implementation of the publish-subscribe pattern. It is a centralized event handling mechanism that allows different components to communicate with each other without being dependent on each other for decoupling purposes.

There are many explanations of this concept on the Internet, and here I recommend one of the better ones (How much do you know about the event bus?)

What is RabbitMQ

RabbitMQ this needless to say, I think to home know.

crude flow chart

The simple way to explain it is:

1. Define an event abstract class

public abstract class EventData
    {
        /// <summary>
        /// Unique identification
        /// </summary>
        public string Unique { get; set; }
        /// <summary>
        /// Successful or not
        /// </summary>
        public bool Success { get; set; }
        /// <summary>
        /// Results
        /// </summary>
        public string Result { get; set; }
    }

 2, the definition of an event processing abstract class, as well as a corresponding queue message execution of a record

public abstract class EventHandler<T> where T : EventData
    {
        public async Task Handler(T eventData)
        {
            await BeginHandler();
            eventData = await ProcessingHandler(eventData);
            if ()
                await FinishHandler(eventData);
        }
        /// <summary>
        /// Start processing
        /// </summary>
        /// <param name="unique"></param>
        /// <returns></returns>
        protected abstract Task BeginHandler(string unique);
        /// <summary>
        /// Processing
        /// </summary>
        /// <param name="eventData"></param>
        /// <returns></returns>
        protected abstract Task<T> ProcessingHandler(T eventData);
        /// <summary>
        /// Processing complete
        /// </summary>
        /// <param name="eventData"></param>
        /// <returns></returns>
        protected abstract Task FinishHandler(T eventData);
    }
   
   [Table("Sys_TaskRecord")]
    public class TaskRecord : Entity<long>
    {
        /// <summary>
        /// Task type
        /// </summary>
        public TaskRecordType TaskType { get; set; }
        /// <summary>
        /// Task status
        /// </summary>
        public int TaskStatu { get; set; }
        /// <summary>
        /// Task value
        /// </summary>
        public string TaskValue { get; set; }
        /// <summary>
        /// Results of the mission
        /// </summary>
        public string TaskResult { get; set; }
        /// <summary>
        /// Task start time
        /// </summary>
        public DateTime TaskStartTime { get; set; }
        /// <summary>
        /// Task completion time
        /// </summary>
        public DateTime? TaskFinishTime { get; set; }
        /// <summary>
        /// Mandate last updated
        /// </summary>
        public DateTime? LastUpdateTime { get; set; }
        /// <summary>
        /// Task name
        /// </summary>
        public string TaskName { get; set; }
        /// <summary>
        /// Additional data
        /// </summary>
        public string AdditionalData { get; set; }
    }

3, define a mail event message class, inherited from EventData, and a mail processing Hanler inherited from EventHandler

 public class EmailEventData:EventData
    {
        /// <summary>
        /// Content of the message
        /// </summary>
        public string Body { get; set; }
        /// <summary>
        /// Receiver
        /// </summary>
        public string Reciver { get; set; }
    }

 public class CreateEmailHandler<T> : <T> where T : EventData
    {
        private IEmailService emailService;
        private IUnitOfWork unitOfWork;
        private ITaskRecordService taskRecordService;
        public CreateEmailHandler(IEmailService emailService, IUnitOfWork unitOfWork, ITaskRecordService taskRecordService)
        {
             = emailService;
             = unitOfWork;
             = taskRecordService;
        }
        protected override async Task BeginHandler(string unique)
        {
            await (Convert.ToInt64(unique), (int));
            await ();
        }

        protected override async Task<T> ProcessingHandler(T eventData)
        {
            try
            {
                EmailEventData emailEventData = eventData as EmailEventData;
                await (, , , "[Idle Egg] received a message.");
                 = true;
            }
            catch (Exception ex)
            {
                await (Convert.ToInt64(), (int),);
                await ();
                 = false;
            }
            return eventData;

        }

        protected override async Task FinishHandler(T eventData)
        {
            await (Convert.ToInt64(), (int),"");
            await ();
        }

4, then how to event message and event Hanler associated, then I think here is the type of EmailEventData and CreateEmailHandler type first registered to the dictionary inside, so I can find the corresponding handler according to EmailEventData, looking for types is not enough, how to create instances, here you also need to register CreateEmailHandler to the DI container, so that you can get the object according to the container, as follows

  public void AddSub<T, TH>()
             where T : EventData
             where TH : EventHandler<T>
        {
            Type eventDataType = typeof(T);
            Type handlerType = typeof(TH);
            if (!(typeof(T)))
                (eventDataType, handlerType);
            _serviceDescriptors.AddScoped(handlerType);
        }
-------------------------------------------------------------------------------------------------------------------
 public Type FindEventType(string eventName)
        {
            if (!(eventName))
                throw new ArgumentException(("eventTypesClass name does not exist{0}(used form a nominal expression)key", eventName));
            return eventTypes[eventName];
        }
------------------------------------------------------------------------------------------------------------------------------------------------------------
  public object FindHandlerType(Type eventDataType)
        {
            if (!(eventDataType))
                throw new ArgumentException(("eventhandlersType not present{0}(used form a nominal expression)key", ));
            var obj = _buildServiceProvider(_serviceDescriptors).GetService(eventhandlers[eventDataType]);
            return obj;
        }
----------------------------------------------------------------------------------------------------------------------------------
 private static IServiceCollection AddEventBusService(this IServiceCollection services)
        {
            string exchangeName = ("EventBusOption:ExchangeName").Value;
            (("").GetTypes())
                .AddSubscribe<EmailEventData, CreateEmailHandler<EmailEventData>>(exchangeName, , );
            return services;
        }

5, send a message, the code here is simple, it is simple to send a message, here with ().Name as the message RoutingKey, so that consumption of this can be based on this key call FindEventType, and then find the corresponding handling procedures

 using (IModel channel = ())
{
     string routeKey = ().Name;
     string message = (eventData);
     byte[] body = Encoding.(message);
     (exchangeName, exchangeType, true, false, null);
     (queueName, true, false, false, null);
     (exchangeName, routeKey, null, body);
}

6, subscribe to the message, the core is this paragraph

  Type eventType = _eventBusManager.FindEventType(eventName);
  var eventData = (T)(body, eventType);
  EventHandler<T> eventHandler = _eventBusManager.FindHandlerType(eventType)  as       EventHandler<T>;

 public void Subscribe<T, TH>(string exchangeName, string exchangeType, string queueName)
            where T : EventData
            where TH : EventHandler<T>
        {
            try
            {
                _eventBusManager.AddSub<T, TH>();
                IModel channel = ();
                (queueName, true, false, false, null);
                (exchangeName, exchangeType, true, false, null);
                (queueName, exchangeName, typeof(T).Name, null);
                var consumer = new EventingBasicConsumer(channel);
                 += async (model, ea) =>
                {
                    string eventName = ;
                    byte[] resp = ();
                    string body = Encoding.(resp);
                    try
                    {
                        Type eventType = _eventBusManager.FindEventType(eventName);
                        var eventData = (T)(body, eventType);
                        EventHandler<T> eventHandler = _eventBusManager.FindHandlerType(eventType) as EventHandler<T>;
                        await (eventData);
                    }
                    catch (Exception ex)
                    {
                        (ex, "EventBusRabbitMQ", );
                    }
                    finally
                    {
                        (, false);
                    }
                  

                };
                (queueName, autoAck: false, consumer: consumer);
            }
            catch (Exception ex)
            {
                (ex, "", );
            }

        }

  Note, here I use a small pit, is the beginning of the use of using wrap this IModel channel = ();; resulting in the final program can not be received after the start of the message, and then go to rabbitmq management interface found that there is no channel connected to the queue is also no consumer, and finally found that may be the use of the implementation of the completion of the release of the use, remove the I'll remove the using and I'll be fine.

   Well, at this point, I'm about done with my thoughts, and now I can get emails for my website messages, so many test emails, hahahahahaha

 

Anyone interested can go to my website (/The first thing you need to do is to step on it and add friends to each other, thank you, don't spray it!