.NET Core中使用RabbitMQ正确方式

首先甩官网:http://www.rabbitmq.com/

然后是.NET Client链接:http://www.rabbitmq.com/dotnet.html

GitHub仓库:https://github.com/rabbitmq/rabbitmq-dotnet-client

下面直接进入正文,一共是两个主题:消费者怎么写?生产者怎么写?

消费者

在dotnet core mvc中,消费者肯定不能通过API或者其他的东西启动,理应是跟着程序一起启动的.

所以...

在dotnet core 2.0以上版本,我们直接用 IHostedService 接口实现.

直接上代码.

  1. // RabbitListener.cs 这个是基类,只实现注册RabbitMQ后到监听消息,然后每个消费者自己去重写RouteKey/QueueName/消息处理函数Process
  2. using System;
  3. using System.Text;
  4. using System.Threading;
  5. using System.Threading.Tasks;
  6. using Microsoft.Extensions.DependencyInjection;
  7. using Microsoft.Extensions.Hosting;
  8. using Microsoft.Extensions.Logging;
  9. using Microsoft.Extensions.Options;
  10. using RabbitMQ.Client;
  11. using RabbitMQ.Client.Events;
  12. namespace Test.Listener
  13. {
  14. public class RabbitListener : IHostedService
  15. {
  16. private readonly IConnection connection;
  17. private readonly IModel channel;
  18. public RabbitListener(IOptions<AppConfiguration> options)
  19. {
  20. try
  21. {
  22. var factory = new ConnectionFactory()
  23. {
  24. // 这是我这边的配置,自己改成自己用就好
  25. HostName = options.Value.RabbitHost,
  26. UserName = options.Value.RabbitUserName,
  27. Password = options.Value.RabbitPassword,
  28. Port = options.Value.RabbitPort,
  29. };
  30. this.connection = factory.CreateConnection();
  31. this.channel = connection.CreateModel();
  32. }
  33. catch (Exception ex)
  34. {
  35. Console.WriteLine($"RabbitListener init error,ex:{ex.Message}");
  36. }
  37. }
  38. public Task StartAsync(CancellationToken cancellationToken)
  39. {
  40. Register();
  41. return Task.CompletedTask;
  42. }
  43. protected string RouteKey;
  44. protected string QueueName;
  45. // 处理消息的方法
  46. public virtual bool Process(string message)
  47. {
  48. throw new NotImplementedException();
  49. }
  50. // 注册消费者监听在这里
  51. public void Register()
  52. {
  53. Console.WriteLine($"RabbitListener register,routeKey:{RouteKey}");
  54. channel.ExchangeDeclare(exchange: "message", type: "topic");
  55. channel.QueueDeclare(queue:QueueName, exclusive: false);
  56. channel.QueueBind(queue: QueueName,
  57. exchange: "message",
  58. routingKey: RouteKey);
  59. var consumer = new EventingBasicConsumer(channel);
  60. consumer.Received += (model, ea) =>
  61. {
  62. var body = ea.Body;
  63. var message = Encoding.UTF8.GetString(body);
  64. var result = Process(message);
  65. if (result)
  66. {
  67. channel.BasicAck(ea.DeliveryTag, false);
  68. }
  69. };
  70. channel.BasicConsume(queue: QueueName, consumer: consumer);
  71. }
  72. public void DeRegister()
  73. {
  74. this.connection.Close();
  75. }
  76. public Task StopAsync(CancellationToken cancellationToken)
  77. {
  78. this.connection.Close();
  79. return Task.CompletedTask;
  80. }
  81. }
  82. }
  83. // 随便贴一个子类
  84. using System;
  85. using System.Text;
  86. using Microsoft.Extensions.Options;
  87. using Newtonsoft.Json.Linq;
  88. using RabbitMQ.Client;
  89. using RabbitMQ.Client.Events;
  90. using Microsoft.Extensions.DependencyInjection;
  91. using Microsoft.EntityFrameworkCore;
  92. using Microsoft.Extensions.Logging;
  93. namespace Test.Listener
  94. {
  95. public class ChapterLister : RabbitListener
  96. {
  97. private readonly ILogger<RabbitListener> _logger;
  98. // 因为Process函数是委托回调,直接将其他Service注入的话两者不在一个scope,
  99. // 这里要调用其他的Service实例只能用IServiceProvider CreateScope后获取实例对象
  100. private readonly IServiceProvider _services;
  101. public ChapterLister(IServiceProvider services, IOptions<AppConfiguration> options,
  102. ILogger<RabbitListener> logger) : base(options)
  103. {
  104. base.RouteKey = "done.task";
  105. base.QueueName = "lemonnovelapi.chapter";
  106. _logger = logger;
  107. _services = services;
  108. }
  109. public override bool Process(string message)
  110. {
  111. var taskMessage = JToken.Parse(message);
  112. if (taskMessage == null)
  113. {
  114. // 返回false 的时候回直接驳回此消息,表示处理不了
  115. return false;
  116. }
  117. try
  118. {
  119. using (var scope = _services.CreateScope())
  120. {
  121. var xxxService = scope.ServiceProvider.GetRequiredService<XXXXService>();
  122. return true;
  123. }
  124. }
  125. catch (Exception ex)
  126. {
  127. _logger.LogInformation($"Process fail,error:{ex.Message},stackTrace:{ex.StackTrace},message:{message}");
  128. _logger.LogError(-1, ex, "Process fail");
  129. return false;
  130. }
  131. }
  132. }
  133. }

然后,记住....

注入到Startup.cs的时候,使用AddHostedService

  1. services.AddHostedService<ChapterLister>();

消费者就这样玩了.

生产者咋玩呢?

这个其实更简单.


  1. using System;
  2. using System.Net;
  3. using Newtonsoft.Json.Linq;
  4. using RestSharp;
  5. using Microsoft.Extensions.Logging;
  6. using Microsoft.Extensions.Options;
  7. using RabbitMQ.Client;
  8. using Newtonsoft.Json;
  9. using System.Text;
  10. namespace Test.SDK
  11. {
  12. public class RabbitMQClient
  13. {
  14. private readonly IModel _channel;
  15. private readonly ILogger _logger;
  16. public RabbitMQClient(IOptions<AppConfiguration> options, ILogger<RabbitMQClient> logger)
  17. {
  18. try
  19. {
  20. var factory = new ConnectionFactory()
  21. {
  22. HostName = options.Value.RabbitHost,
  23. UserName = options.Value.RabbitUserName,
  24. Password = options.Value.RabbitPassword,
  25. Port = options.Value.RabbitPort,
  26. };
  27. var connection = factory.CreateConnection();
  28. _channel = connection.CreateModel();
  29. }
  30. catch (Exception ex)
  31. {
  32. logger.LogError(-1, ex, "RabbitMQClient init fail");
  33. }
  34. _logger = logger;
  35. }
  36. public virtual void PushMessage(string routingKey, object message)
  37. {
  38. _logger.LogInformation($"PushMessage,routingKey:{routingKey}");
  39. _channel.QueueDeclare(queue: "message",
  40. durable: false,
  41. exclusive: false,
  42. autoDelete: false,
  43. arguments: null);
  44. string msgJson = JsonConvert.SerializeObject(message);
  45. var body = Encoding.UTF8.GetBytes(msgJson);
  46. _channel.BasicPublish(exchange: "message",
  47. routingKey: routingKey,
  48. basicProperties: null,
  49. body: body);
  50. }
  51. }
  52. }

切记注入实例的时候用单例模式.

services.AddSingleton<RabbitMQClient, RabbitMQClient>();

全文完...

.NET Core中使用RabbitMQ正确方式的更多相关文章

  1. 在ABP core中使用RabbitMq

    距上一篇博客的更新一集很久了,主要是最近做的事情比较杂,中间也有一个难点,就是在ABP中加入APP扫码登录,本来想些的,但是觉得这个写出来会不会让我们的系统被破解-_-||,所以想了想,就没有写. 这 ...

  2. WSL2+Docker部署RabbitMQ以及在Asp.net core 中使用RabbitMQ示例(1)

    本文主要在于最近因疫情不能外出,在家研究的一些技术积累. 主要用到的技术以及知识点: WSL 2 WSL 2+Docker Docker+RabbitMQ 在ASP.NET Core中使用Rabbit ...

  3. asp.net core 中灵活的配置方式

    asp.net core支持外部文件和命令行参数方式来配置系统运行所需要的配置信息,我们从下面两个常用场景来具体说下具体使用方法. 一.监听地址及端口配置 1,命令行方式 asp.net core系统 ...

  4. Asp.Net Core中HttpClient的使用方式

    在.Net Core应用开发中,调用第三方接口也是常有的事情,HttpClient使用人数.使用频率算是最高的一种了,在.Net Core中,HttpClient的使用方式随着版本的升级也发生了一些变 ...

  5. 在Asp.Net Core中使用DI的方式使用Hangfire构建后台执行脚本

    最近项目中需要用到后台Job,原有在Windows中我们会使用命令行程序结合计划任务或者直接生成Windows Service,现在.Net Core跨平台了,虽然Linux下也有计划任务,但跟原有方 ...

  6. 学习在.NET Core中使用RabbitMQ进行消息传递之持久化(二)

    前言 上一节我们简单介绍了RabbitMQ和在安装后启动所出现的问题,本节我们开始正式进入RabbitMQ的学习,对于基本概念请从官网或者其他前辈博客上查阅,我这里不介绍基础性东西,只会简单提一下,请 ...

  7. DotNet Core中使用RabbitMQ

    上一篇随笔记录到RabbitMQ的安装,安装完成,我们就开始使用吧. RabbitMQ简介 AMQP,即Advanced Message Queuing Protocol,高级消息队列协议,是应用层协 ...

  8. 细聊.Net Core中IServiceScope的工作方式

    前言 自从.Net Core引入IOC相关的体系之后,关于它的讨论就从来没有停止过,因为它是.Net Core体系的底层框架,你只要使用了.Net Core的时候就必然会用到它.当然关于使用它的过程中 ...

  9. .Net Core中使用RabbitMQ

    (1).引入依赖 RabbitMQ.Client (2).编写发布者代码 var connectionFactory = new ConnectionFactory() { HostName=&quo ...

随机推荐

  1. Python读取Json字典写入Excel表格的方法

    需求: 因需要将一json文件中大量的信息填入一固定格式的Excel表格,单纯的复制粘贴肯定也能完成,但是想偷懒一下,于是借助Python解决问题. 环境: Windows7 +Python2.7 + ...

  2. 死磕salt系列-salt 故障汇总

    这里将salt使用过程中遇到的所有的故障进行一个汇总. grains 匹配后多了一个列表 salt-master中配置jinja模板来匹配自定义的grins. vim /etc/salt/minion ...

  3. Django中模型(四)

    Django中模型(四) 五.创建对象 1.目的 向数据库中添加数据.当创建对象时,Django不会对数据库进行读写操作,当调用save()方法时,才与数据库交互,将对象保存到数据库中 2.注意 __ ...

  4. FRM一级备考感想

    作为金融小白,工作四年多,边边角角有了些许的最直观认识,决定深入了解下金融相关123. 曾经尝试CFA失败,转战FRM安慰下失败的灵魂. 2018.11.17 FRM Part I 考试结束,自7月初 ...

  5. 测试用例组合--PICT

    测试用例组合 一原理 1.配对组合原理(两两组合原理),应用工具PICT自动输出组合 name=a,b value=1,2 key=m,n 如果自己组合那么有2*2*2=8条用例 a1m a2m a1 ...

  6. Linux 下让终端走代理的方法

    转载: https://blog.fazero.me/2015/09/15/%E8%AE%A9%E7%BB%88%E7%AB%AF%E8%B5%B0%E4%BB%A3%E7%90%86%E7%9A%8 ...

  7. OC字符串处理

    接到一个需求, 现有多个品牌的商品,使用字符串保存已选中的品牌,使用','隔开,可以反选. 分析问题可知: 1. 字符串由多个品牌名字组成,由 ',' 隔开. 2.如果选中的品牌不在字符串内,则拼接到 ...

  8. Web | Webpack快速上手

    概述 Webpack 是一个前端资源加载/打包工具.它将根据模块的依赖关系进行静态分析,然后将这些模块按照指定的规则生成对应的静态资源. 一般我们在开发中都是使用终端去进行安装,使用npm,关于npm ...

  9. ubuntu 16.04(Windows 10双系统+grub引导)无法进入tt1~tt6(NVIDIA驱动安装相关-黑屏,login loop,分辨率)

    目录 前言回顾 最终解决: 0.关闭x服务 1.禁用nouveau 2.加入 3.更新 4.查找匹配驱动 5.选择推荐版本 6.等待安装后重启,nvidia-smi查看是否安装成功,或者lsmod | ...

  10. 怎样获取最新版的javascript文件,解决被浏览器缓存的问题

    假设有一个js文件(以jquery为例),在服务器上的URL地址为:../js/jquery.js . 当某天jquery版本更新了,用最新版的jquery文件覆盖了原来旧版的jquery文件. 这时 ...