.net Rabbitmq 封装 包含 直连交换机 死信队列(十一)

 

Connector 文件夹 代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public interface IConnectors : IDisposable
   {
       /// <summary>
       /// 初始化交换机队列
       /// </summary>
       /// <param name="definition"></param>
       /// <returns></returns>
       Task InitExchangeAndQueueAsync(ExchangeAndQueueDefinition definition);     
       /// <summary>
       /// 获取缓存中的key 将已经初始化的交换机队列的信道IChannel存入
       /// 缓存中提高性能
       /// </summary>
       /// <param name="definition">交换机队列的声明对象</param>
       /// <returns></returns>
       string GetMemoryCacheKey(ExchangeAndQueueDefinition definition);    
 
       /// <summary>
       /// 信道
       /// </summary>
       IChannel Channel { get; }
   }

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
using Microsoft.Extensions.Options;
using RabbitCustorm.Message;
using RabbitCustorm.RabbitMQExtends;
using RabbitMQ.Client;
using System;
using System.Collections.Generic;
using System.Diagnostics.Metrics;
using System.Linq;
using System.Reflection.Metadata.Ecma335;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
 
namespace RabbitCustorm.Connection.Connectors
{
    /// <summary>
    /// 此类需要单例模式
    /// </summary>
    public class Connectors : IConnectors
    {
        private IConnection conn;
        private IChannel channel;
        private ConnectionFactory factory;
        private readonly RabbitOptions rabbitOptions;
        public Connectors(IOptions<RabbitOptions> rabbitOptions)
        {
            this.rabbitOptions = rabbitOptions.Value;
            //初始化
            Init();
        }
        /// <summary>
        /// 初始化
        /// </summary>
        private void Init()
        {
            factory = new ConnectionFactory()
            {
                UserName = rabbitOptions.UserName,
                Password = rabbitOptions.Password,
                VirtualHost = rabbitOptions.VirtualHost,
                HostName = rabbitOptions.HostName,
                Port = rabbitOptions.Port,
                DispatchConsumersAsync = true//开启异步消费者
            };          
            this.conn = factory.CreateConnection();
            this.channel = conn.CreateChannel();
        }
        /// <summary>
        /// 信道
        /// </summary>
        public IChannel Channel => this.channel;
 
        /// <summary>
        /// 初始化 交换机
        /// </summary>
        /// <param name="definition"></param>
        /// <returns></returns>
        public async Task InitExchangeAndQueueAsync(ExchangeAndQueueDefinition definition)
        {
            if (!this.channel.IsOpen)
            {
                throw new Exception("信道(channel)未开启!!!");
            }
 
            //如果包含 死信 定义
            if (definition.Arguments != null && definition.Arguments.Keys.Contains("x-dead-letter-exchange"))
            {
                //死信交换机
                string deadLetterExchange = definition.Arguments["x-dead-letter-exchange"].ToString();
                //死信队列
                string deadLetterQueue = definition.Arguments["x-dead-letter-queue"].ToString();
                //死信路由key
                string deadletterRoutingKey = definition.Arguments["x-dead-letter-routing-key"].ToString();
                await channel.ExchangeDeclareAsync(exchange: deadLetterExchange, type: ExchangeType.Direct, passive: false, durable: true, autoDelete: false, arguments: null);
                await channel.QueueDeclareAsync(queue: deadLetterQueue, passive: false, durable: true, exclusive: false, autoDelete: false, arguments: null);
                await channel.QueueBindAsync(queue: deadLetterQueue, exchange: deadLetterExchange, routingKey: deadletterRoutingKey, arguments: null);
            }
            await channel.ExchangeDeclareAsync(exchange: definition.ExchangeName, type: ExchangeType.Direct, passive: false, durable: true, autoDelete: false, arguments: definition.Arguments);
            await channel.QueueDeclareAsync(queue: definition.QueueName, passive: false, durable: true, exclusive: false, autoDelete: false, arguments: definition.Arguments);
            await channel.QueueBindAsync(queue: definition.QueueName, exchange: definition.ExchangeName, routingKey: definition.RouteKey, arguments: definition.Arguments);
        }
 
        /// <summary>
        /// 获取 MemoryCache Key
        /// </summary>
        /// <param name="definition"></param>
        /// <returns></returns>
        public string GetMemoryCacheKey(ExchangeAndQueueDefinition definition)
        {
            string key = $"{definition.ExchangeName}_{definition.QueueName}_{definition.RouteKey}";
            //如果是死信队列
            if (definition.Arguments != null && definition.Arguments.ContainsKey("x-dead-letter-exchange"))
            {
                //死信交换机
                string deadLetterExchange = definition.Arguments["x-dead-letter-exchange"].ToString();
                //死信队列
                string deadLetterQueue = definition.Arguments["x-dead-letter-queue"].ToString();
                //死信路由key
                string deadletterRoutingKey = definition.Arguments["x-dead-letter-routing-key"].ToString();
                return key += $"{deadLetterExchange}_{deadLetterQueue}_{deadletterRoutingKey}";
            }
            return $"{definition.ExchangeName}_{definition.QueueName}_{definition.RouteKey}";
        }
        public async void Dispose()
        {
            if (conn != null)
            {
                await conn.CloseAsync();
            }
            if (channel != null)
            {
                await channel.CloseAsync();
            }
        }
    }
}

  

Consumer 文件夹代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
using RabbitCustorm.Message;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace RabbitCustorm
{
    /// <summary>
    /// 消费者接口
    /// </summary>
    public interface IConsumer
    {
        /// <summary>
        /// 接收消息
        /// </summary>
        /// <param name="definition"><交换机队列声明/param>
        /// <param name="func">消息处理委托,返回是否处理成功</param>
        void Received(ExchangeAndQueueDefinition definition, Func<string, bool> func);
    }
}

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using RabbitCustorm.Connection.Connectors;
using RabbitCustorm.Message;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Channels;
using System.Threading.Tasks;
 
namespace RabbitCustorm
{
    /// <summary>
    /// 消费者
    /// </summary>
    public class Consumer : IConsumer
    {
        private readonly IConnectors connectors;
        private readonly ILogger<Producer> logger;
        private readonly IMemoryCache memoryCache;
 
        public Consumer(IConnectors connectors, ILogger<Producer> logger, IMemoryCache memoryCache)
        {
            this.connectors = connectors;
            this.logger = logger;
            this.memoryCache = memoryCache;
        }
 
        /// <summary>
        /// 接收消息
        /// </summary>
        /// <param name="definition">交换机和队列定义</param>
        /// <param name="func">消息处理函数</param>
        public async void Received(ExchangeAndQueueDefinition definition, Func<string, bool> func)
        {
            //获取 memoryCache Key
            string memoryCacheKey = this.connectors.GetMemoryCacheKey(definition);
            //判断 内存缓存中是否存在 channel 如果不存在 就存进去
            if (!this.memoryCache.TryGetValue<IChannel>(memoryCacheKey, out IChannel channel))
            {
                //初始化交换机
                await this.connectors.InitExchangeAndQueueAsync(definition);
                channel = this.connectors.Channel;
                this.memoryCache.Set<IChannel>(memoryCacheKey, channel);
            }
            //var consumer = new EventingBasicConsumer(channel);
            //异步消费
            var consumer = new AsyncEventingBasicConsumer(channel);
            consumer.Received += async (ch, ea) =>
            {
                // channel.BasicQos(0, 1, false);
                string str = Encoding.UTF8.GetString(ea.Body.ToArray(), 0, ea.Body.Length);
                if (func(str))
                {
                    //应答
                    await channel.BasicAckAsync(ea.DeliveryTag, false);
                }
                else
                {
                    //拒绝消息
                    await channel.BasicRejectAsync(ea.DeliveryTag, false);
                }
            };
            string consumerTag = this.connectors.Channel.BasicConsume(definition.QueueName, false, consumer);
        }
    }
}

  

Message 文件夹 代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace RabbitCustorm.Message
{
    /// <summary>
    /// 交换机 队列 定义
    /// </summary>
    public class ExchangeAndQueueDefinition
    {
        /// <summary>
        /// 交换机名称
        /// </summary>
        public string ExchangeName { get; set; }
        /// <summary>
        /// 队列名称
        /// </summary>
        public string QueueName { get; set; }
 
        /// <summary>
        /// 路由key
        /// </summary>
        public string RouteKey { get; set; }
 
        /// <summary>
        /// 参数
        /// </summary>
        public Dictionary<string, object> Arguments { get; set; } = null;
    }  
}

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace RabbitCustorm.Message
{
    /// <summary>
    ///  声明 交换机名称 队列名称 便于复用
    /// </summary>
    public static class ExchangeAndQueueStatement
    {
        public static readonly object lockProducer = new object();
 
        #region 交换机类型 direct 的交换机和队列声明
        public const string TestDirectExchange = "TestDirectExchange";
        public const string TestDirectQueue = "TestDirectQueue";
        public const string TestDirectKey = "TestDirectKey";
        #endregion
 
 
        #region 死信交换机和队列,routekey声明
        /// <summary>
        /// 死信交换机
        /// </summary>
        public const string ExchangeDeadLetter = "ExchangeDeadLetter";
        /// <summary>
        /// 死信队列
        /// </summary>
        public const string QueueDeadLetter = "QueueDeadLetter";
        /// <summary>
        /// 死信route key
        /// </summary>
        public const string RouteDeadLetter = "RouteDeadLetter";
        /// <summary>
        /// 死信中 正常交换机
        /// </summary>
        public const string TestExchange = "TestExchange";
        /// <summary>
        /// 死信中 正常队列
        /// </summary>
        public const string TestQueue = "TestQueue";
        /// <summary>
        /// 死信中 正常路由Key
        /// </summary>
        public const string TestKey = "TestKey";
 
        #endregion
    }
}

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace RabbitCustorm.Message
{
    /// <summary>
    /// 消息传输类
    /// </summary>
    public class MessageTrans
    {
        /// <summary>
        /// 交换机 队列 定义
        /// </summary>
        public ExchangeAndQueueDefinition Definition { get; set; }
        /// <summary>
        /// 消息体
        /// </summary>
        public object Body { get; set; }
    }
}

  

Producer 文件夹代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
using RabbitCustorm.Message;
using RabbitMQ.Client;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace RabbitCustorm
{
    /// <summary>
    /// 生产者接口
    /// </summary>
    public interface IProducer
    {
        /// <summary>
        /// 发消息
        /// </summary>
        /// <param name="message">消息传输对象</param>
        /// <returns></returns>
        Task SendMessageAsync(MessageTrans message);
    }
}

  

复制代码
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using RabbitCustorm.Connection.Connectors;
using RabbitCustorm.Message;
using RabbitMQ.Client;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;

namespace RabbitCustorm
{
    /// <summary>
    /// exchange direct 直连 类型
    /// </summary>
    public class Producer : IProducer
    {
        private readonly IConnectors connectors;
        private readonly ILogger<Producer> logger;
        private readonly IMemoryCache memoryCache;
        public Producer(IConnectors connectors, ILogger<Producer> logger, IMemoryCache memoryCache)
        {
            this.connectors = connectors;
            this.logger = logger;
            this.memoryCache = memoryCache;
        }
        public async Task SendMessageAsync(MessageTrans message)
        {
            try
            {
                //获取 memoryCache key
                string memoryCacheKey = connectors.GetMemoryCacheKey(message.Definition);
                //判断 内存缓存中是否存在 channel 如果不存在 就存进去
                if (!memoryCache.TryGetValue(memoryCacheKey, out IChannel channel))
                {
                    //初始化交换机
                    await connectors.InitExchangeAndQueueAsync(message.Definition);
                    channel = connectors.Channel;
                    memoryCache.Set(memoryCacheKey, channel);
                }
                //发送消息
                string body = JsonConvert.SerializeObject(message.Body);
                byte[] messageBodyBytes = Encoding.UTF8.GetBytes(body);
                //开启事务
                await connectors.Channel.TxSelectAsync();
                await channel.BasicPublishAsync(message.Definition.ExchangeName, message.Definition.RouteKey, messageBodyBytes);
                //事务提交
                await connectors.Channel.TxCommitAsync();
                logger.LogInformation($"发送消息{body}");
            }
            catch (Exception ex)
            {
                //事务回滚
                await connectors.Channel.TxRollbackAsync();
                logger.LogError($"发送消息失败{ex.Message}", ex);
            }
        }
    }
}
复制代码

 

RabbitMQExtends 文件夹代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace RabbitCustorm.RabbitMQExtends
{
    /// <summary>
    /// rabbit 配置类
    /// </summary>
    public class RabbitOptions
    {
        /// <summary>
        /// 用户名
        /// </summary>
        public string UserName { get; set; }
        /// <summary>
        /// 密码
        /// </summary>
        public string Password { get; set; }
        /// <summary>
        /// 虚拟机主机 例如 center
        /// </summary>
        public string VirtualHost { get; set; }
        /// <summary>
        /// rabbitmq 主机 例如 192.168.0.168
        /// </summary>
        public string HostName { get; set; }
        /// <summary>
        /// 端口号 5672
        /// </summary>
        public int Port { get; set; } = 5672;
    }
}

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using RabbitCustorm.Connection.Connectors;
using RabbitCustorm;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace RabbitCustorm.RabbitMQExtends
{
    public static class RabbitMQExtend
    {
        /// <summary>
        /// 添加 生产者 和 消费者
        /// </summary>
        /// <param name="services"></param>
        /// <param name="config"></param>
        /// <returns></returns>
        public static IServiceCollection AddRabbitMQ(this IServiceCollection services, IConfiguration config)
        {
            services.Configure<RabbitOptions>(config.GetSection("RabbitOptions"));
            //增加内从缓存注入
            services.AddMemoryCache();
            services.AddSingleton<IConnectors, Connectors>();
            services.AddScoped<IProducer, Producer>();
            services.AddScoped<IConsumer, Consumer>();
            return services;
        }
        /// <summary>
        /// 添加 rabbit 只有 生产者
        /// </summary>
        /// <param name="services"></param>
        /// <param name="config"></param>
        /// <returns></returns>
        public static IServiceCollection AddRabbitMQProducer(this IServiceCollection services, IConfiguration config)
        {
            services.Configure<RabbitOptions>(config.GetSection("RabbitOptions"));
            //增加内从缓存注入
            services.AddMemoryCache();
            services.AddSingleton<IConnectors, Connectors>();
            services.AddScoped<IProducer, Producer>();
            return services;
        }
        /// <summary>
        /// 添加 rabbit 只有 消费者
        /// </summary>
        /// <param name="services"></param>
        /// <param name="config"></param>
        /// <returns></returns>
        public static IServiceCollection AddRabbitMQConsumer(this IServiceCollection services, IConfiguration config)
        {
            services.Configure<RabbitOptions>(config.GetSection("RabbitOptions"));
            //增加内从缓存注入
            services.AddMemoryCache();
            services.AddSingleton<IConnectors, Connectors>();
            services.AddScoped<IConsumer, Consumer>();
            return services;
        }
    }
}

  

以上是rabbitmq 封装类库代码

下面 是测试webapi 

appsettings.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "RabbitOptions": {
    "HostName": "192.168.0.168",
    "Port": "5672",
    "UserName": "test",
    "Password": "test",
    "VirtualHost": "center"
  }
}

  

Program.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
using RabbitCustorm.RabbitMQExtends;
using RabbitMqWebAPI;
using System.Runtime.CompilerServices;
 
var builder = WebApplication.CreateBuilder(args);
 
// Add services to the container.
 
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddRabbitMQ(builder.Configuration);
//测试直连交换机
builder.Services.AddHostedService<TestDirectService>();
//测试私信队列交换机
builder.Services.AddHostedService<TestDeadLetterService>();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}
 
app.UseHttpsRedirection();
 
app.UseAuthorization();
 
app.MapControllers();
 
app.Run();

  

TestDeadLetterService

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi.Writers;
using RabbitCustorm;
using RabbitCustorm.Message;
using RabbitMqWebAPI.Controllers;
 
namespace RabbitMqWebAPI
{
    /// <summary>
    /// 测试私信队列
    /// </summary>
    public class TestDeadLetterService : BackgroundService
    {
        private readonly ILogger<RabbitConsumerController> logger;
        private readonly IServiceScopeFactory scopeFactory;
        public TestDeadLetterService(ILogger<RabbitConsumerController> logger, IServiceScopeFactory scopeFactory)
        {
            this.logger = logger;
            this.scopeFactory = scopeFactory;
        }
        protected override Task ExecuteAsync(CancellationToken stoppingToken)
        {
            using IServiceScope scope = this.scopeFactory.CreateScope();
            IConsumer consumer = scope.ServiceProvider.GetRequiredService<IConsumer>();
            Task.Factory.StartNew(() =>
             {
                 consumer.Received(
                     new ExchangeAndQueueDefinition
                     {
                         ExchangeName = ExchangeAndQueueStatement.ExchangeDeadLetter,
                         QueueName = ExchangeAndQueueStatement.QueueDeadLetter,
                         RouteKey = ExchangeAndQueueStatement.RouteDeadLetter,                      
                     }, body =>
                     {
                         this.logger.LogInformation($"收到死信消息{body}");
                         return true;
                     });
             }, TaskCreationOptions.LongRunning);
            return Task.CompletedTask;
        }
    }
}

  

TestDirectService

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
using RabbitCustorm;
using RabbitCustorm.Message;
using RabbitMqWebAPI.Controllers;
 
namespace RabbitMqWebAPI
{
    /// <summary>
    /// 测试直连交换机
    /// </summary>
    public class TestDirectService : IHostedService
    {
        private readonly ILogger<RabbitConsumerController> logger;
        private readonly IServiceScopeFactory scopeFactory;
        public TestDirectService(ILogger<RabbitConsumerController> logger, IServiceScopeFactory scopeFactory)
        {
            this.logger = logger;
            this.scopeFactory = scopeFactory;
        }
        public Task StartAsync(CancellationToken cancellationToken)
        {
            using AsyncServiceScope asyncService = scopeFactory.CreateAsyncScope();
            IConsumer consumer = asyncService.ServiceProvider.GetRequiredService<IConsumer>();
            Task.Factory.StartNew(() =>
            {
                consumer.Received(
                 new ExchangeAndQueueDefinition
                 {
                     ExchangeName = ExchangeAndQueueStatement.TestDirectExchange,
                     QueueName = ExchangeAndQueueStatement.TestDirectQueue,
                     RouteKey = ExchangeAndQueueStatement.TestDirectKey,
                 }, body =>
                 {
                     this.logger.LogInformation($"收到消息{body}");
                     return true;
                 });
            }, TaskCreationOptions.LongRunning);
            return Task.CompletedTask;
        }
 
        public Task StopAsync(CancellationToken cancellationToken)
        {
            throw new NotImplementedException();
        }
    }
}

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using RabbitCustorm;
using RabbitCustorm.Message;
namespace RabbitMqWebAPI.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class RabbitProducerController : ControllerBase
    {
        private readonly ILogger<RabbitProducerController> logger;
        private readonly IProducer producer;
        private readonly static object lockobj = new object();
        //一次访问资源的线程数量 1个
        private static SemaphoreSlim _semaphore = new SemaphoreSlim(1);
        public RabbitProducerController(ILogger<RabbitProducerController> logger, IProducer producer)
        {
            this.logger = logger;
            this.producer = producer;
        }
        /// <summary>
        /// 发送直连消息
        /// </summary>
        /// <param name="body"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ActionResult> SendMessage([FromBody] string body)
        {
            await producer.SendMessageAsync(new MessageTrans
            {
                Definition = new ExchangeAndQueueDefinition
                {
                    ExchangeName = ExchangeAndQueueStatement.TestDirectExchange,
                    QueueName = ExchangeAndQueueStatement.TestDirectQueue,
                    RouteKey = ExchangeAndQueueStatement.TestDirectKey
                },
                Body = body
            });
            return Ok("发送成功!");
        }
 
        /// <summary>
        /// 发送延迟消息
        /// </summary>
        /// <param name="body"></param>
        /// <returns></returns>
        [HttpPost("SendDelayMessage")]
        public async Task<ActionResult> SendDelayMessage([FromBody] Student body)
        {
            if (await _semaphore.WaitAsync(1000))
            {
                await producer.SendMessageAsync(new MessageTrans
                {
                    Definition = new ExchangeAndQueueDefinition
                    {
                        ExchangeName = ExchangeAndQueueStatement.TestExchange,
                        QueueName = ExchangeAndQueueStatement.TestQueue,
                        RouteKey = ExchangeAndQueueStatement.TestKey,
                        Arguments = new Dictionary<string, object>
                        {
                            ["x-message-ttl"] = 12000,
                            ["x-dead-letter-exchange"] = ExchangeAndQueueStatement.ExchangeDeadLetter,
                            ["x-dead-letter-queue"] = ExchangeAndQueueStatement.QueueDeadLetter,
                            ["x-dead-letter-routing-key"] = ExchangeAndQueueStatement.RouteDeadLetter,
                        }
                    },
                    Body = body
                });
            }
            _semaphore.Release();
            return Ok("发送成功!");
        }
    }
}

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using RabbitCustorm;
using RabbitCustorm.Message;
namespace RabbitMqWebAPI.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class RabbitConsumerController : ControllerBase
    {
        private readonly ILogger<RabbitConsumerController> logger;
        private readonly IConsumer consumer;
 
        public RabbitConsumerController(ILogger<RabbitConsumerController> logger, IConsumer consumer)
        {
            this.logger = logger;
            this.consumer = consumer;
        }
 
        [HttpGet]
        public  ActionResult Received()
        {
            this.consumer.Received(
                new ExchangeAndQueueDefinition
                {
                    ExchangeName = ExchangeAndQueueStatement.TestDirectExchange,
                    QueueName = ExchangeAndQueueStatement.TestDirectQueue,
                    RouteKey = ExchangeAndQueueStatement.TestDirectKey,
                }, body =>
                {
                    this.logger.LogInformation($"收到消息{body}");
                    return true;
                });
            return Ok();
        }
 
        /// <summary>
        /// 接收死信队列消息
        /// </summary>
        /// <returns></returns>
        [HttpGet("ReceivedDeadLetter")]
        public ActionResult ReceivedDeadLetter()
        {
            this.consumer.Received(
                new ExchangeAndQueueDefinition
                {
                    ExchangeName = ExchangeAndQueueStatement.ExchangeDeadLetter,
                    QueueName = ExchangeAndQueueStatement.QueueDeadLetter,
                    RouteKey = ExchangeAndQueueStatement.RouteDeadLetter
                }, body =>
                {
                    this.logger.LogInformation($"收到死信消息{body}");
                    return true;
                });
            return Ok();
        }
    }
}

  

 

posted on   是水饺不是水饺  阅读(67)  评论(1编辑  收藏  举报

编辑推荐:
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示