使用RabbitMQ时使用MemoryPack序列化和反序列化对象

发布时间 2023-11-29 23:23:59作者: ayatip
  [MemoryPackable]
    public partial class UserEto
    {
        public String Name { get; set; }
    }

 

发送端

public class EventBus : IEventBus
{
    public void Publish(string exchangeName, object eventData)
    {
        using var connection = RabbitMQHelper.GetConnection();
        var channel = connection.CreateModel();

        // 序列化对象
         var message = MemoryPackSerializer.Serialize(eventData.GetType(),eventData);

        channel.BasicPublish(exchangeName, "", null,message);
    }
}

 

 

接收端

public class ConsumerBackgroundWorker : BackgroundService
    {
        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
             var connection = RabbitMQHelper.GetConnection();

            var channel = connection.CreateModel();

            // 声明交换机
            channel.ExchangeDeclare("MyExchange", "direct");

            // 声明队列
            channel.QueueDeclare("QueueOne", false, false, false, null);

            // 绑定队列到交换机
            channel.QueueBind("QueueOne", "MyExchange", "");

            // 基于channel生成监听
            var consumer = new EventingBasicConsumer(channel);
            consumer.Received += (object? sender, BasicDeliverEventArgs e) =>
            {
               
               // 反序列化对象
                var obj =  MemoryPackSerializer.Deserialize<UserEto>(e.Body.Span);

                foreach (var handler in WebApplicationExtensions.EventHandlerList)
                {
                     ((IEventHandler)Activator.CreateInstance(handler)).HandleEvent(channel,  obj);
                }
            };

            channel.BasicConsume("QueueOne", true, consumer);
        }
    }

 

在反序列化时,RabbitMQ接收到的 BasicDeliverEventArgs 的 Body 类型为"System.ReadOnlyMemory<Byte>" ,常规使用Json序列化时只需要使用

Encoding.Default.GetString(e.Body.ToArray());
即可,而在这里,要先将ReadOnlyMemory转换为ReadOnlySpan。