文件内容 EventActionHandler.cs 9 KB 8913 字符
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using PasteApeart.Application.Contracts;
using PasteApeart.Handler.eventmodels;
using System.Collections.Concurrent;
using System.Reflection;
using System.Text.Json;

namespace PasteApeart.Handler
{
    /// <summary>
    /// 队列处理 可以被RabbitMQ或者Channel的消费者调用
    /// </summary>
    public class EventActionHandler : ISingletonDependency
    {

        private readonly ILogger<EventActionHandler> _logger;
        private readonly IServiceProvider _serviceProvider;
        private readonly ChannelHelper _channelHelper;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="logger"></param>
        /// <param name="serviceProvider"></param>
        /// <param name="channelHelper"></param>
        public EventActionHandler(ILogger<EventActionHandler> logger, IServiceProvider serviceProvider, ChannelHelper channelHelper)
        {
            _logger = logger;
            _serviceProvider = serviceProvider;
            _channelHelper = channelHelper;
        }


        private readonly ConcurrentDictionary<string, Type> _eventTypeCache = new();
        private readonly ConcurrentDictionary<Type, (Type HandlerType, MethodInfo HandleMethod)> _handlerCache = new();

        /// <summary>
        /// 
        /// </summary>
        /// <param name="msg"></param>
        /// <returns></returns>
        public async Task HandlerEventMessage(string msg)
        {
            if (string.IsNullOrWhiteSpace(msg))
            {
                return;
            }
            object input = null;
            try
            {
                // 1. 只反序列化一次,使用 System.Text.Json 性能更好
                using var jsonDoc = JsonDocument.Parse(msg);
                var root = jsonDoc.RootElement;
                //if (!root.TryGetProperty("EventName", out var eventNameProperty) ||
                //    eventNameProperty.GetString() is not string eventName)
                //{
                //    _logger.LogError($"消息缺少 EventName 字段: {msg}");
                //    return;
                //}
                JsonElement eventNameProperty;
                // 使用不区分大小写的匹配,更健壮
                if (!root.TryGetProperty("eventName", out eventNameProperty))
                {
                    root.TryGetProperty("EventName", out eventNameProperty);
                }
                // 获取字符串值并验证
                string eventName = eventNameProperty.GetString();
                if (string.IsNullOrEmpty(eventName))
                {
                    _logger.LogError($"EventName 字段值为空: {msg}");
                    return;
                }
                // 2. 获取事件类型(带缓存)
                var modelType = _eventTypeCache.GetOrAdd(eventName, name =>
                {
                    return typeof(AbsEventModel).Assembly.GetTypes()
                        .FirstOrDefault(t => t.Name == name);
                });
                //&& typeof(EventBaseModel).IsAssignableFrom(t)
                if (modelType == null)
                {
                    _logger.LogError($"未找到事件类型: {eventName}");
                    return;
                }
                // 3. 反序列化为具体类型
                //var input = JsonSerializer.Deserialize(msg, modelType, new JsonSerializerOptions
                //{
                //    PropertyNameCaseInsensitive = true
                //});
                //input = JsonConvert.DeserializeObject(msg, modelType);
                input = JsonSerializer.Deserialize(msg, modelType, JsonConfig.Options);
                //var aaa = Newtonsoft.Json.JsonConvert.DeserializeObject(msg,);
                if (input == null)
                {
                    _logger.LogError($"无法将消息反序列化为类型 {eventName}: {msg}");
                    return;
                }
                using var scope = _serviceProvider.CreateScope();
                if (input is IEventModel tryModel)
                {
                    if (tryModel.ExpireSecond > 0)
                    {
                        //var _channelHandler = scope.ServiceProvider.GetRequiredService<ChannelHelper>();
                        await _channelHelper.WriteAutoQueueAsync(tryModel);
                        return;
                    }
                }
                //EventTryHandler
                // 4. 获取处理器信息(带缓存)
                var (handlerType, handleMethod) = _handlerCache.GetOrAdd(modelType, type =>
                {
                    var hType = typeof(IEventHandler<>).MakeGenericType(type);
                    var method = hType.GetMethod("HandleEventAsync");
                    return (hType, method);
                });
                if (handleMethod == null)
                {
                    _logger.LogError($"处理器 {handlerType.Name} 没有 HandleEventAsync 方法");
                    return;
                }
                var handler = scope.ServiceProvider.GetRequiredService(handlerType);
                if (handler == null)
                {
                    _logger.LogError($"没有找到 {eventName} 的 IEventHandler 实现");
                    return;
                }
                try
                {
                    // 5. 执行处理
                    var task = handleMethod.Invoke(handler, new[] { input }) as Task;
                    if (task != null)
                    {
                        await task;
                    }
                    else
                    {
                        _logger.LogError($"无法调用 {eventName} 的处理方法");
                    }
                }
                catch (Exception handlerExl)
                {
                    _logger.LogException(handlerExl);
                }
                finally
                {
                    if (handler is IDisposable disposable)
                    {
                        disposable.Dispose();
                    }
                    if (handler is IAsyncDisposable disposable1)
                    {
                        await disposable1.DisposeAsync();
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"处理消息时发生错误: {msg}");
                if (input != null)
                {
                    //if (input is EventRetryModel emodel)
                    //{
                    //    if (emodel.TryMaxTime > 0 && emodel.CurrentTime < emodel.TryMaxTime)
                    //    {
                    //        emodel.CurrentTime++;
                    //        emodel.ExpireSecond = EventHandlerExtensions.NextSecond(emodel.CurrentTime);
                    //        await _channelHelper.WriteAutoMQAsync(emodel);
                    //    }
                    //}
                }
            }
        }

        private readonly ConcurrentDictionary<Type, Type> _eventHandlerCache = new();
        private readonly ConcurrentDictionary<Type, MethodInfo> _handleMethodCache = new();

        /// <summary>
        /// 
        /// </summary>
        /// <param name="read"></param>
        /// <returns></returns>
        public async Task HanlderEventMessage(IEventModel read)
        {
            _logger.LogWarning($"Event Msg:{read.EventName}");
            //read是一个IEventModel
            var typeName = read.GetType().Name;
            var eventType = read.GetType();
            using var _scope = _serviceProvider.CreateScope();
            var handlerType = _eventHandlerCache.GetOrAdd(eventType, t => typeof(IEventHandler<>).MakeGenericType(t));
            var handler = _scope.ServiceProvider.GetService(handlerType);
            // 通过依赖注入获取处理器实例
            if (handler == null)
            {
                _logger.LogError($"没有找到 {typeName} 的 IEventHandler 实现!");
                return;
            }
            // 获取处理方法(带缓存)
            var handleMethod = _handleMethodCache.GetOrAdd(eventType, t =>
                handlerType.GetMethod("HandleEventAsync"));
            if (handleMethod == null)
            {
                _logger.LogError($"无法找到 {typeName} 的 HandleEventAsync 方法");
                return;
            }
            try
            {
                var task = handleMethod.Invoke(handler, new[] { read }) as Task;
                if (task != null)
                {
                    await task;
                }
                _logger.LogInformation($"执行了 {typeName} 的 HandleEventAsync 函数");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"处理事件 {eventType.Name} 时发生错误");
            }
            finally
            {
                if (handler is IDisposable disposable)
                {
                    disposable.Dispose();
                }
                if (handler is IAsyncDisposable disposable1)
                {
                    await disposable1.DisposeAsync();
                }
            }
        }

    }
}
​ ​