RabbitMQ学习-ASP.NET Core中使用RabbitMQ

Posted on 2022-01-03 15:15  樱木007  阅读(1008)  评论(13编辑  收藏  举报

代码参考连接:https://www.bilibili.com/video/BV1GU4y1w7Yq?p=9&spm_id_from=pageDriver

1.项目结构

项目类型为ASP.NET Core Web API

 

 

   

   

2.Infrastructure类库代码 

nuget添加RabbitMQ.Client的引用

 (1) RabbitConnection.cs代码

 1 using RabbitMQ.Client;
 2 using System;
 3 using System.Collections.Generic;
 4 using System.Text;
 5 
 6 namespace Infrastructure.Config
 7 {
 8     public class RabbitConnection
 9     {
10         private readonly RabbitOption _config;
11         private IConnection _connection = null;
12         public RabbitConnection(RabbitOption rabbitOption)
13         {
14             _config = rabbitOption;
15         }
16 
17         public IConnection GetConnection()
18         {
19             if (_connection == null)
20             {
21                 if (string.IsNullOrEmpty(_config.Address))
22                 {
23                     ConnectionFactory factory = new ConnectionFactory();
24                     factory.HostName = _config.HostName;
25                     factory.Port = _config.Port;
26                     factory.UserName = _config.UserName;
27                     factory.Password = _config.Password;
28                     factory.VirtualHost = _config.VirtualHost;
29                     _connection = factory.CreateConnection();
30                 }
31                 else
32                 {
33                     ConnectionFactory factory = new ConnectionFactory();
34                     factory.UserName = _config.UserName;
35                     factory.Password = _config.Password;
36                     factory.VirtualHost = _config.VirtualHost;
37 
38                     var address = _config.Address;
39                     List<AmqpTcpEndpoint> endpoints = new List<AmqpTcpEndpoint>();
40                     foreach (var endpoint in address.Split(","))
41                     {
42                         endpoints.Add(new AmqpTcpEndpoint(endpoint.Split(":")[0],int.Parse(endpoint.Split(":")[1])));
43                     }
44                     _connection = factory.CreateConnection(endpoints);
45                 }
46             }
47             return _connection;
48         }
49     }
50 }

(2)RabbitConstant.cs代码

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Text;
 4 
 5 namespace Infrastructure.Config
 6 {
 7     public class RabbitConstant
 8     {
 9         public const string TEST_EXCHANGE = "test.exchange";
10         public const string TEST_QUEUE = "test.queue";
11     }
12 }

(3)RabbitOption.cs代码

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Text;
 4 
 5 namespace Infrastructure.Config
 6 {
 7     public class RabbitOption
 8     {
 9         /// <summary>
10         /// 主机名称
11         /// </summary>
12         public string HostName { get; set; }
13         public string Address { get; set; }
14         /// <summary>
15         /// 端口号
16         /// </summary>
17         public int Port { get; set; }
18         public string UserName { get; set; }
19         public string Password { get; set; }
20 
21         public string VirtualHost { get; set; }
22     }
23 }

(4) QueueInfo.cs

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Text;
 4 
 5 namespace Infrastructure.Consumer
 6 {
 7     public class QueueInfo
 8     {
 9         /// <summary>
10         /// 队列名称
11         /// </summary>
12         public string Queue { get; set; }
13         /// <summary>
14         /// 路由名称
15         /// </summary>
16         public string RoutingKey { get; set; }
17         /// <summary>
18         /// 交换机类型
19         /// </summary>
20         public string ExchangeType { get; set; }
21         /// <summary>
22         /// 交换机名称
23         /// </summary>
24         public string Exchange { get; set; }
25         public IDictionary<string, object> props { get; set; } = null;
26         public Action<RabbitMessageEntity> OnRecevied { get; set; }
27     }
28 }

(5)RabbitChannelConfig.cs

 1 using RabbitMQ.Client;
 2 using RabbitMQ.Client.Events;
 3 using System;
 4 using System.Collections.Generic;
 5 using System.Text;
 6 
 7 namespace Infrastructure.Consumer
 8 {
 9     public class RabbitChannelConfig
10     {
11         public string ExchangeTypeName { get; set; }
12         public string ExchangeName { get; set; }
13         public string QueueName { get; set; }
14         public string RoutingKeyName { get; set; }
15         public IConnection Connection { get; set; }
16         public EventingBasicConsumer Consumer { get; set; }
17 
18         /// <summary>
19         /// 外部订阅消费者通知委托
20         /// </summary>
21         public Action<RabbitMessageEntity> OnReceivedCallback { get; set; }
22 
23         public RabbitChannelConfig(string exchangeType,string exchange,string queue,string routingKey)
24         {
25             this.ExchangeTypeName = exchangeType;
26             this.ExchangeName = exchange;
27             this.QueueName = queue;
28             this.RoutingKeyName = routingKey;
29         }
30 
31         public void Receive(object sender,BasicDeliverEventArgs args)
32         {
33             RabbitMessageEntity body = new RabbitMessageEntity();
34             try
35             {
36                 string content = Encoding.UTF8.GetString(args.Body.ToArray());
37                 body.Content = content;
38                 body.Consumer =(EventingBasicConsumer)sender;
39                 body.BasicDeliver = args;
40             }
41             catch (Exception e)
42             {
43                 body.ErrorMessage = $"订阅出错{e.Message}";
44                 body.Exception = e;
45                 body.Error = true;
46                 body.Code = 500;
47             }
48             OnReceivedCallback?.Invoke(body);
49         }
50     }
51 }

(6)RabbitChannelManager.cs

 1 using Infrastructure.Config;
 2 using RabbitMQ.Client;
 3 using RabbitMQ.Client.Events;
 4 using System;
 5 using System.Collections.Generic;
 6 using System.Text;
 7 
 8 namespace Infrastructure.Consumer
 9 {
10     public class RabbitChannelManager
11     {
12         public RabbitConnection Connection { get; set; }
13 
14         public RabbitChannelManager(RabbitConnection connection)
15         {
16             this.Connection = connection;
17         }
18 
19         /// <summary>
20         /// 创建接收消息的通道
21         /// </summary>
22         /// <param name="exchangeType"></param>
23         /// <param name="exchange"></param>
24         /// <param name="queue"></param>
25         /// <param name="routingKey"></param>
26         /// <param name="arguments"></param>
27         /// <returns></returns>
28         public RabbitChannelConfig CreateReceiveChannel(string exchangeType,string exchange,string queue,string routingKey,
29             IDictionary<string,object>arguments = null)
30         {
31             IModel model = this.CreateModel(exchangeType,exchange,queue,routingKey,arguments);
32             EventingBasicConsumer consumer = this.CreateConsumer(model,queue);
33             RabbitChannelConfig channel = new RabbitChannelConfig(exchangeType,exchange,queue,routingKey);
34             consumer.Received += channel.Receive;
35             return channel;
36         }
37 
38       
39         /// <summary>
40         /// 创建一个通道,包含交换机/队列/路由,并建立绑定关系
41         /// </summary>
42         /// <param name="exchangeType">交换机类型:Topic,Direct,Fanout</param>
43         /// <param name="exchange">交换机名称</param>
44         /// <param name="queue">队列名称</param>
45         /// <param name="routingKey">路由名称</param>
46         /// <param name="arguments"></param>
47         /// <returns></returns>
48         private IModel CreateModel(string exchangeType, string exchange, string queue, string routingKey, IDictionary<string, object> arguments)
49         {
50             exchangeType = string.IsNullOrEmpty(exchangeType) ? "default" : exchangeType;
51             IModel model = this.Connection.GetConnection().CreateModel();
52             model.BasicQos(0,1,false);
53             model.QueueDeclare(queue,true,false,false,arguments);
54             model.ExchangeDeclare(exchange, exchangeType);
55             model.QueueBind(queue, exchange, routingKey);
56             return model;
57         }
58 
59         /// <summary>
60         /// 创建消费者
61         /// </summary>
62         /// <param name="model"></param>
63         /// <param name="queue"></param>
64         /// <returns></returns>
65         private EventingBasicConsumer CreateConsumer(IModel model, string queue)
66         {
67             EventingBasicConsumer consumer = new EventingBasicConsumer(model);
68             model.BasicConsume(queue, false, consumer);
69             return consumer;
70         }
71     }
72 }

(7)RabbitMessageEntity.cs

 1 using RabbitMQ.Client.Events;
 2 using System;
 3 using System.Collections.Generic;
 4 using System.Text;
 5 
 6 namespace Infrastructure.Consumer
 7 {
 8     public class RabbitMessageEntity
 9     {
10         public string Content { get; set; }
11         public EventingBasicConsumer Consumer { get; set; }
12         public BasicDeliverEventArgs BasicDeliver { get; set; }
13         public string ErrorMessage { get; set; }
14         public Exception Exception { get; set; }
15         public bool Error { get; set; }
16         public int Code { get; set; }
17     }
18 }

(8)IRabbitProducer.cs

 1 using System;
 2 using System.Collections.Generic;
 3 
 4 namespace Infrastructure.Producer
 5 {
 6     public interface IRabbitProducer
 7     {
 8         public void Publish(string exchange,string routingKey,IDictionary<string,object> props,string content);
 9     }
10 }

(9)RabbitProducer.cs

 1 using Infrastructure.Config;
 2 using System;
 3 using System.Collections.Generic;
 4 using System.Text;
 5 
 6 namespace Infrastructure.Producer
 7 {
 8     public class RabbitProducer : IRabbitProducer
 9     {
10         private readonly RabbitConnection _connection;
11         public RabbitProducer(RabbitConnection connection)
12         {
13             _connection = connection;
14         }
15         public void Publish(string exchange, string routingKey, IDictionary<string, object> props, string content)
16         {
17             var channel = _connection.GetConnection().CreateModel();
18             var prop = channel.CreateBasicProperties();
19             if (props.Count > 0)
20             {
21                 var delay = props["x-delay"];
22                 prop.Expiration = delay.ToString();
23             }
24             channel.BasicPublish(exchange, routingKey, false, prop, Encoding.UTF8.GetBytes(content));
25         }
26     }
27 }

3.RabbitMQ.Services类库代码

添加Infrastructure的项目引用

(1)IOrderService.cs

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Text;
 4 
 5 namespace RabbitMQ.Services
 6 {
 7     public interface IOrderService
 8     {
 9         void SendOrderMessage();
10         void SendTestMessage(string message);
11     }
12 }

(2) OrderService.cs

 1 using Infrastructure.Config;
 2 using Infrastructure.Producer;
 3 using System;
 4 using System.Collections.Generic;
 5 using System.Text;
 6 
 7 namespace RabbitMQ.Services
 8 {
 9     public class OrderService : IOrderService
10     {
11         private readonly IRabbitProducer _rabbitProducer;
12         public OrderService(IRabbitProducer rabbitProducer)
13         {
14             _rabbitProducer = rabbitProducer;
15         }
16         public void SendOrderMessage()
17         {
18             throw new NotImplementedException();
19         }
20 
21         public void SendTestMessage(string message)
22         {
23             Console.WriteLine($"send message:{message}");
24             _rabbitProducer.Publish(RabbitConstant.TEST_EXCHANGE,"",new Dictionary<string,object>(),message);
25         }
26     }
27 }

4. RabbitMQ.Test控制台代码

添加RabbitMQ.WebApi.Order项目引用

复制项目RabbitMQ.WebApi.Order下的appsettings.json到此项目中

(1)ProcessTest.cs

 1 using Infrastructure.Config;
 2 using Infrastructure.Consumer;
 3 using Microsoft.Extensions.Hosting;
 4 using RabbitMQ.Client;
 5 using System;
 6 using System.Collections.Generic;
 7 using System.Text;
 8 using System.Threading;
 9 using System.Threading.Tasks;
10 
11 namespace RabbitMQ.Test
12 {
13     public class ProcessTest : IHostedService
14     {
15         private readonly RabbitConnection _connection;
16         public List<QueueInfo> Queues { get; } = new List<QueueInfo>();
17         public ProcessTest(RabbitConnection connection)
18         {
19             _connection = connection;
20             Queues.Add(new QueueInfo()
21             { 
22                ExchangeType = ExchangeType.Fanout,
23                Exchange = RabbitConstant.TEST_EXCHANGE,
24                Queue = RabbitConstant.TEST_QUEUE,
25                RoutingKey = "",
26                OnRecevied = this.Receive
27             });
28         }
29 
30         private void Receive(RabbitMessageEntity message)
31         {
32             Console.WriteLine($"Test Receive Message:{message.Content}");
33             message.Consumer.Model.BasicAck(message.BasicDeliver.DeliveryTag,true);
34         }
35 
36         public Task StartAsync(CancellationToken cancellationToken)
37         {
38             Console.WriteLine("RabbitMQ测试消息接收处理服务正在启动");
39             RabbitChannelManager channelManager = new RabbitChannelManager(_connection);
40             foreach (var queueInfo in Queues)
41             {
42                 RabbitChannelConfig channel = channelManager.CreateReceiveChannel(queueInfo.ExchangeType,
43                     queueInfo.Exchange,queueInfo.Queue,queueInfo.RoutingKey);
44                 channel.OnReceivedCallback = queueInfo.OnRecevied;
45             }
46             Console.WriteLine("RabbitMQ测试消息接收处理服务已经启动");
47             return Task.CompletedTask;
48         }
49 
50         public Task StopAsync(CancellationToken cancellationToken)
51         {
52             return Task.CompletedTask;
53         }
54     }
55 }

(2) Program.cs

 1 using Infrastructure.Config;
 2 using Microsoft.Extensions.Configuration;
 3 using Microsoft.Extensions.DependencyInjection;
 4 using Microsoft.Extensions.Hosting;
 5 using System;
 6 
 7 namespace RabbitMQ.Test
 8 {
 9     class Program
10     {
11         static void Main(string[] args)
12         {
13             var section = new ConfigurationBuilder()
14                 .AddJsonFile("appsettings.json")
15                 .Build()
16                 .GetSection("RabbitMQ");
17             var host = new HostBuilder()
18                 .ConfigureServices(services =>
19                  services.AddSingleton(new RabbitConnection(section.Get<RabbitOption>()))
20                          .AddSingleton<IHostedService,ProcessTest>())
21                 .Build();
22              host.Run();
23         }
24     }
25 }

5. RabbitMQ.WebApi.Order代码

nuget添加Swashbuckle.AspNetCore引用

添加项目Infrastructure、RabbitMQ.Services引用

(1) OrderController.cs

 1 using Microsoft.AspNetCore.Http;
 2 using Microsoft.AspNetCore.Mvc;
 3 using RabbitMQ.Services;
 4 using System;
 5 using System.Collections.Generic;
 6 using System.Linq;
 7 using System.Threading.Tasks;
 8 
 9 namespace RabbitMQ.WebApi.Order.Controllers
10 {
11     [Route("api/[controller]")]
12     [ApiController]
13     public class OrderController : ControllerBase
14     {
15         private readonly IOrderService _orderService;
16 
17         public OrderController(IOrderService orderService)
18         {
19             _orderService = orderService;
20         }
21 
22         //[HttpGet]
23         //public IActionResult Order()
24         //{
25         //    _orderService.SendOrderMessage();
26         //    return Ok();
27         //}
28         [HttpGet("test")]
29         public IActionResult Test(string message)
30         {
31             _orderService.SendTestMessage(message);
32             return Ok();
33         }
34 
35     }
36 }

(2) ServiceExtensions.cs

 1 using Infrastructure.Config;
 2 using Microsoft.Extensions.Configuration;
 3 using Microsoft.Extensions.DependencyInjection;
 4 using System;
 5 using System.Collections.Generic;
 6 using System.Linq;
 7 using System.Threading.Tasks;
 8 
 9 namespace RabbitMQ.WebApi.Order.Extensions
10 {
11     public static class ServiceExtensions
12     {
13         public static void ConfigureCors(this IServiceCollection services)
14         {
15             services.AddCors(options=>
16             {
17                 options.AddPolicy("AnyPolicy",
18                     builder=>builder.AllowAnyOrigin()
19                                     .AllowAnyMethod()
20                                     .AllowAnyHeader());
21             });
22         }
23         public static void ConfigureRabbitContext(this IServiceCollection services,IConfiguration config)
24         {
25             var section = config.GetSection("RabbitMQ");
26             services.AddSingleton(
27                   new RabbitConnection(section.Get<RabbitOption>())); 
28         }
29     }
30 }

(3) Startup.cs

 1 using Microsoft.AspNetCore.Builder;
 2 using Microsoft.AspNetCore.Hosting;
 3 using Microsoft.AspNetCore.Mvc;
 4 using Microsoft.Extensions.Configuration;
 5 using Microsoft.Extensions.DependencyInjection;
 6 using Microsoft.Extensions.Hosting;
 7 using Microsoft.Extensions.Logging;
 8 using System;
 9 using System.Collections.Generic;
10 using System.Linq;
11 using System.Threading.Tasks;
12 using RabbitMQ.WebApi.Order.Extensions;
13 using Microsoft.OpenApi.Models;
14 using RabbitMQ.Services;
15 using Infrastructure.Producer;
16 
17 namespace RabbitMQ.WebApi.Order
18 {
19     public class Startup
20     {
21         public Startup(IConfiguration configuration)
22         {
23             Configuration = configuration;
24         }
25 
26         public IConfiguration Configuration { get; }
27 
28         // This method gets called by the runtime. Use this method to add services to the container.
29         public void ConfigureServices(IServiceCollection services)
30         {
31             services.AddControllers();
32             services.AddSwaggerGen(c=>
33             {
34                 c.SwaggerDoc("v1",new OpenApiInfo { Title="RabbitMQ.WebApi.Order",Version="v1"});
35             });
36             services.AddScoped<IOrderService, OrderService>();
37             services.AddScoped<IRabbitProducer,RabbitProducer>();
38             services.ConfigureCors();
39             services.ConfigureRabbitContext(Configuration);
40         }
41 
42         // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
43         public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
44         {
45             if (env.IsDevelopment())
46             {
47                 app.UseDeveloperExceptionPage();
48                 app.UseSwagger();
49                 app.UseSwaggerUI(c=>c.SwaggerEndpoint("/swagger/v1/swagger.json","RabbitMQ.WebApi.Order v1"));
50             }
51 
52             app.UseRouting();
53 
54             app.UseAuthorization();
55 
56             app.UseEndpoints(endpoints =>
57             {
58                 endpoints.MapControllers();
59             });
60         }
61     }
62 }

(4) appsettings.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "RabbitMQ": {
    "HostName": "127.0.0.1",
    "Address": "",
    "Port": 5672,
    "UserName": "guest",
    "Password": "guest",
    "VirtualHost": "/"
  },

  "AllowedHosts": "*"
}

6.运行

(1)  powershell管理员模式运行RabbitMQ.Test项目

PS D:\DotNetProject\RabbitMQ.WebApiDemo\RabbitMQ.Test> dotnet run

 (2)  powershell管理员模式运行RabbitMQ.WebApi.Order项目 

PS D:\DotNetProject\RabbitMQ.WebApiDemo\RabbitMQ.WebApi.Order> dotnet run

 (3) 浏览器运行http://localhost:5000/swagger/index.html

 (4) 测试接口Test 

 (9)运行结果

 如需要项目源码,请留下邮箱,会将项目整个发送

IRabbitProducer

Copyright © 2024 樱木007
Powered by .NET 8.0 on Kubernetes