本例asp.net 使用rabbitmq需求背景:为了提升用户体验,用户点击下单按钮,后台先做一些简单必要的操作,返回给用户一个友好提示(比如提示处理中,或者订单状态为处理中),然后发通过发消息给队列,把耗时久的操作留给rabbitmq队列处理。

1、生产者封装类:

public class Publisher
{
private readonly string _exchange;
private readonly string _hostName;
private readonly string _password;
private readonly Uri _uri;
private readonly string _userName;
private readonly string _virtualHost; /// <param name="exchange"></param>
/// <param name="hostName"></param>
/// <param name="userName"></param>
/// <param name="password"></param>
/// <param name="virtualHost"></param>
/// <param name="uri">AMQP Address</param>
public Publisher(string exchange, string hostName, string userName, string password, string virtualHost, Uri uri)
{
_hostName = hostName;
_exchange = exchange;
_userName = userName;
_password = password;
_virtualHost = virtualHost;
_uri = uri; Factory = new ConnectionFactory
{
HostName = _hostName,
UserName = _userName,
Password = _password,
VirtualHost = _virtualHost,
Endpoint = new AmqpTcpEndpoint(_uri),
RequestedHeartbeat =
};
Factory.RequestedHeartbeat = ;
} public string HostName
{
get { return _hostName; }
} public string Exchange
{
get { return _exchange; }
} public string UserName
{
get { return _userName; }
} public string Password
{
get { return _password; }
} public string VirtualHost
{
get { return _virtualHost; }
} public Uri Uri
{
get { return _uri; }
} public ConnectionFactory Factory { get; private set; } /// <summary>
/// 直连式交换机,发消息
/// </summary>
/// <param name="queueName">队列名</param>
/// <param name="message">消息</param>
/// <param name="durable">消息是否持久化</param>
public void PublishDirectMessage(string queueName, string message, bool durable=false)
{
if (null == Factory)
{
throw new ArgumentException("connection factory initialization error");
} if (string.IsNullOrWhiteSpace(message))
{
throw new ArgumentNullException("message can not be null.");
} if (string.IsNullOrWhiteSpace(Exchange))
{
throw new ArgumentNullException("exchange can not be null.");
} try
{
using (var connection = Factory.CreateConnection())
{
//通道 (Channel),在C#客户端里叫Model(不明白为什么这么取名字),其他客户端基本都叫Channel
using (var channel = connection.CreateModel())
{
//定义交换机
channel.ExchangeDeclare(Exchange, ExchangeType.Direct, durable: durable,
autoDelete: false, arguments: null); //定义队列,如果名称相同不会重复创建
channel.QueueDeclare(queueName, durable: durable, exclusive: false,
autoDelete: false, arguments: null); //绑定
channel.QueueBind(queueName, Exchange, routingKey: queueName); //消息可持久化
IBasicProperties props = null;
if (durable) {
props = channel.CreateBasicProperties();
props.SetPersistent(true);
} //发送消息到队列
var msgBody = Encoding.UTF8.GetBytes(message);
channel.BasicPublish(Exchange, routingKey: queueName, basicProperties: props,
body: msgBody);
}
}
}
catch (Exception ex)
{
LogHelper.Log(LogCategory.Error, ex.Message, ex);
}
} /// <summary>
/// Fanout(广播)式交换机
/// </summary>
/// <param name="message"></param>
public void PublishFanoutMessage(string message)
{
if (null == Factory)
{
throw new ArgumentException("connection factory initialization error");
} if (string.IsNullOrWhiteSpace(message))
{
throw new ArgumentNullException("message can not be null.");
} if (string.IsNullOrWhiteSpace(Exchange))
{
throw new ArgumentNullException("exchange can not be null.");
} try
{
using (var connection = Factory.CreateConnection())
{
using (var channel = connection.CreateModel())
{
channel.ExchangeDeclare(Exchange, ExchangeType.Fanout);
byte[] body = Encoding.UTF8.GetBytes(message);
channel.BasicPublish(Exchange, "", null, body);
}
}
}
catch (Exception ex)
{
LogHelper.Log(LogCategory.Error, ex.Message, ex);
}
}
}

生产者

2、消费者封装类:

public delegate void ReceiveMessageHandle(string inputStr);
public delegate bool ReceiveAnswerMessageHandle(string inputStr); /// <typeparam name="T">要接收的数据类型</typeparam>
public class Subscriber<T> : IDisposable
{
private readonly string _exchange;
private readonly string _hostName;
private readonly string _password;
private readonly Uri _uri;
private readonly string _userName;
private readonly string _virtualHost; /// <param name="exchange"></param>
/// <param name="hostName"></param>
/// <param name="userName"></param>
/// <param name="password"></param>
/// <param name="virtualHost"></param>
/// <param name="uri">AMQP Address</param>
public Subscriber(string exchange, string hostName, string userName, string password, string virtualHost,
Uri uri)
{
_hostName = hostName;
_exchange = exchange;
_userName = userName;
_password = password;
_virtualHost = virtualHost;
_uri = uri; Factory = new ConnectionFactory
{
HostName = _hostName,
UserName = _userName,
Password = _password,
VirtualHost = _virtualHost,
Endpoint = new AmqpTcpEndpoint(_uri),
RequestedHeartbeat =
}; Connection = Factory.CreateConnection();
Channel = Connection.CreateModel();
} public string HostName
{
get { return _hostName; }
} public string Exchange
{
get { return _exchange; }
} public string UserName
{
get { return _userName; }
} public string Password
{
get { return _password; }
} public string VirtualHost
{
get { return _virtualHost; }
} public Uri Uri
{
get { return _uri; }
} public ConnectionFactory Factory { get; private set; } public IModel Channel { get; private set; }
public IConnection Connection { get; private set; }
public EventingBasicConsumer Consumer { get; private set; } private string QueueName { get; set; } public string Message { get; set; } //public delegate string MessageHandle(); /// <summary>
/// 手动释放
/// </summary>
void IDisposable.Dispose()
{
if (Channel != null)
{
Consumer = null;
Channel.Close();
Channel.Dispose();
} if (Connection != null)
{
Consumer = null;
Connection.Close();
Connection.Dispose();
} GC.SuppressFinalize(this);
} /// <summary>
/// 托管释放
/// </summary>
~Subscriber()
{
if (Channel != null)
{
Consumer = null;
Channel.Close();
Channel.Dispose();
} if (Connection != null)
{
Consumer = null;
Connection.Close();
Connection.Dispose();
}
} public ReceiveMessageHandle ReceiveMessageHandler { get; set; }
public ReceiveAnswerMessageHandle ReceiveAnswerMessageHandle { get; set; } /// <summary>
/// 接受广播消息
/// <param name="tryTimes">消费失败后,继续尝试消费的次数</param>
/// </summary>
public void ReceiveFanoutMessage(int tryTimes = )
{
try
{
//Channel.ExchangeDeclare(Exchange, ExchangeType.Fanout);
//QueueName = Channel.QueueDeclare().QueueName;
//Channel.QueueBind(QueueName, Exchange, "");
//Consumer = new EventingBasicConsumer(Channel);
//Consumer.Received += (model, dlvrArgs) =>
//{
// byte[] body = dlvrArgs.Body;
// Message = Encoding.UTF8.GetString(body);
// ReceiveMessageHandler(Message);
//};
//Channel.BasicConsume(QueueName, true, Consumer); Channel.ExchangeDeclare(Exchange, ExchangeType.Fanout);
QueueName = Channel.QueueDeclare().QueueName;
Channel.QueueBind(QueueName, Exchange, "");
Consumer = new EventingBasicConsumer(Channel);
Consumer.Received += (model, dlvrArgs) =>
{
byte[] body = dlvrArgs.Body;
if (body != null && body.Length > )
{
Message = Encoding.UTF8.GetString(body);
if (!string.IsNullOrWhiteSpace(Message))
{
bool isConsumeSuccess = false;// 是否消费成功
int consumeCount = ;//尝试消费次数
while (!isConsumeSuccess)
{
consumeCount++;
isConsumeSuccess = ReceiveAnswerMessageHandle(Message);
if (isConsumeSuccess || consumeCount >= tryTimes)
{
Channel.BasicAck(dlvrArgs.DeliveryTag, false);//将队列里面的消息进行释放
isConsumeSuccess = true;
}
else
{
//重新放入队列,等待再次消费
Channel.BasicAck(dlvrArgs.DeliveryTag, true);
}
}
}
}
};
Channel.BasicConsume(QueueName, false, Consumer);
}
catch (Exception ex)
{
LogHelper.Log(LogCategory.Error, ex.Message, ex);
}
} /// <summary>
/// 接受直连交换机消息
/// </summary>
/// <param name="queueName">队列名</param>
/// <param name="durable">消息是否持久化</param>
/// <param name="tryTimes">消费失败后,继续尝试消费的次数</param>
/// <returns></returns>
public void ReceiveDirectMessage(string queueName, bool durable = false, int tryTimes = )
{
try
{
Channel.ExchangeDeclare(Exchange, ExchangeType.Direct, durable: durable, autoDelete: false, arguments: null);
Channel.QueueDeclare(queueName, durable: durable, exclusive: false, autoDelete: false, arguments: null);
Channel.QueueBind(queueName, Exchange, routingKey: queueName);
//订阅模式 (有消息到达将被自动接收) 消费者
Consumer = new EventingBasicConsumer(Channel);
//绑定消息接收后的事件委托
Consumer.Received += (model, dlvrArgs) =>
{
byte[] body = dlvrArgs.Body;
if (body != null && body.Length > )
{
Message = Encoding.UTF8.GetString(body);
if (!string.IsNullOrWhiteSpace(Message))
{
bool isConsumeSuccess = false;// 是否消费成功
int consumeCount = ;//尝试消费次数
while (!isConsumeSuccess)
{
consumeCount++;
isConsumeSuccess = ReceiveAnswerMessageHandle(Message);
if (isConsumeSuccess || consumeCount >= tryTimes)
{
Channel.BasicAck(dlvrArgs.DeliveryTag, false);//将队列里面的消息进行释放
isConsumeSuccess = true;
}
else
{
//重新放入队列,等待再次消费
Channel.BasicAck(dlvrArgs.DeliveryTag, true);
}
}
}
}
};
Channel.BasicConsume(queueName, false, Consumer);
} catch (Exception ex)
{
LogHelper.Log(LogCategory.Error, ex.Message, ex);
}
} public T ToJson()
{
return JsonConvert.DeserializeObject<T>(Message);
}
}

消费者

3、新建控制台程序,发送消息:

 class Program
{
public static string MqUri = ConfigHelper.GetConfig("RabbitMQ", "MqUri");
public static string MqExchange = ConfigHelper.GetConfig("RabbitMQ", "MqExchange");
public static string MqHostName = ConfigHelper.GetConfig("RabbitMQ", "MqHostName");
public static string MqUserName = ConfigHelper.GetConfig("RabbitMQ", "MqUserName");
public static string MqPassword = ConfigHelper.GetConfig("RabbitMQ", "MqPassword"); static void Main(string[] args)
{
string userCommand = "";
while (userCommand != "exit")
{
Console.WriteLine("请输入:");
userCommand = Console.ReadLine(); //发送消息
var publisher = new Publisher(MqExchange, MqHostName,
MqUserName, MqPassword, "/", new Uri(MqUri)); publisher.PublishFanoutMessage(userCommand);
}
}
}

发送消息控制台应用

4、新建控制台程序,接受消息:

internal class Program
{
public static string MqUri = ConfigHelper.GetConfig("RabbitMQ", "MqUri");
public static string MqExchange = ConfigHelper.GetConfig("RabbitMQ", "MqExchange");
public static string MqHostName = ConfigHelper.GetConfig("RabbitMQ", "MqHostName");
public static string MqUserName = ConfigHelper.GetConfig("RabbitMQ", "MqUserName");
public static string MqPassword = ConfigHelper.GetConfig("RabbitMQ", "MqPassword"); static void Main(string[] args)
{
Console.WriteLine("Start process data {0}", DateTime.Now);
try
{
var subscriber = new Subscriber<string>(
MqExchange, MqHostName, MqUserName, MqPassword, "/",
new Uri(MqUri))
{
ReceiveAnswerMessageHandle = SubscriberHandler1
}; subscriber.ReceiveFanoutMessage(); }
catch (Exception ex)
{
Console.WriteLine(ex);
}
} private static bool SubscriberHandler1(string msg)
{
Console.WriteLine(msg);
return true;
}
}

接受消息控制台应用

5、配置文件:

上面两个控制台的配置文件一样,如下:

<RabbitMQ>
<add key="MqUri" value="amqp://localhost/" />
<add key="MqExchange" value="MyExchange" />
<add key="MqHostName" value="localhost" />
<add key="MqUserName" value="root" />
<add key="MqPassword" value="root" />
</RabbitMQ>

6、结果图:

asp.net 使用rabbitmq事例的更多相关文章

  1. DotNet 资源大全中文版(Awesome最新版)

    Awesome系列的.Net资源整理.awesome-dotnet是由quozd发起和维护.内容包括:编译器.压缩.应用框架.应用模板.加密.数据库.反编译.IDE.日志.风格指南等. 算法与数据结构 ...

  2. 【资源大全】.NET资源大全中文版(Awesome最新版)

    算法与数据结构(Algorithms and Data structures) 应用程序接口(API) 应用程序框架(Application Frameworks) 模板引擎(Application ...

  3. ASP.NET Core Web API下事件驱动型架构的实现(三):基于RabbitMQ的事件总线

    在上文中,我们讨论了事件处理器中对象生命周期的问题,在进入新的讨论之前,首先让我们总结一下,我们已经实现了哪些内容.下面的类图描述了我们已经实现的组件及其之间的关系,貌似系统已经变得越来越复杂了. 其 ...

  4. ASP.NET Core2利用MassTransit集成RabbitMQ

    在ASP.NET Core上利用MassTransit来集成使用RabbitMQ真的很简单,代码也很简洁.近期因为项目需要,我便在这基础上再次进行了封装,抽成了公共方法,使得使用RabbitMQ的调用 ...

  5. 如何从40亿整数中找到不存在的一个 webservice Asp.Net Core 轻松学-10分钟使用EFCore连接MSSQL数据库 WPF实战案例-打印 RabbitMQ与.net core(五) topic类型 与 headers类型 的Exchange

    如何从40亿整数中找到不存在的一个 前言 给定一个最多包含40亿个随机排列的32位的顺序整数的顺序文件,找出一个不在文件中的32位整数.(在文件中至少确实一个这样的数-为什么?).在具有足够内存的情况 ...

  6. ExpandoObject与DynamicObject的使用 RabbitMQ与.net core(一)安装 RabbitMQ与.net core(二)Producer与Exchange ASP.NET Core 2.1 : 十五.图解路由(2.1 or earler) .NET Core中的一个接口多种实现的依赖注入与动态选择看这篇就够了

    ExpandoObject与DynamicObject的使用   using ImpromptuInterface; using System; using System.Dynamic; names ...

  7. 简述C#中IO的应用 RabbitMQ安装笔记 一次线上问题引发的对于C#中相等判断的思考 ef和mysql使用(一) ASP.NET/MVC/Core的HTTP请求流程

    简述C#中IO的应用   在.NET Framework 中. System.IO 命名空间主要包含基于文件(和基于内存)的输入输出(I/O)服务的相关基础类库.和其他命名空间一样. System.I ...

  8. ASP.NET Core2基于RabbitMQ对Web前端实现推送功能

    在我们很多的Web应用中会遇到需要从后端将指定的数据或消息实时推送到前端,通常的做法是前端写个脚本定时到后端获取,或者借助WebSocket技术实现前后端实时通讯.因定时刷新的方法弊端很多(已不再采用 ...

  9. 重温.NET下Assembly的加载过程 ASP.NET Core Web API下事件驱动型架构的实现(三):基于RabbitMQ的事件总线

    重温.NET下Assembly的加载过程   最近在工作中牵涉到了.NET下的一个古老的问题:Assembly的加载过程.虽然网上有很多文章介绍这部分内容,很多文章也是很久以前就已经出现了,但阅读之后 ...

随机推荐

  1. SQLAlchemy 使用(一)创建单一model

    前言 最近项目等待前端接接口,比较空闲.就想学习一些新东西.学啥呢?考虑到ORM的易用性,还是学习一下ORM.那么与Flask搭配的ORM有 flask-sqlalchemy 但是该组件专为Flask ...

  2. js——图片懒加载

    <img class="js-lazy-image centered" src="./img/dog-running.svg" width="4 ...

  3. centos6.5环境下的web项目mysql编码方式导致的中文乱码问题

    最近在centos6.5下部署web项目时网页出现中文乱码的问题,在排除掉php之后,把问题锁定在mysql的编码方式上. 解决方法如下: 首先进入mysql命令行,输入命令:SHOW VARIABL ...

  4. Win10安装java环境

    window系统安装java 一.下载JDK 1.首先需要下载java开发工具包JDK,下载地址:http://www.oracle.com/technetwork/java/javase/downl ...

  5. Spring Boot MongoDB 查询操作 (BasicQuery ,BSON)

    MongoDB 查询有四种方式:Query,TextQuery,BasicQuery 和 Bson ,网上太多关于 Query 的查询方式,本文只记录 BasicQuery和Bson 的方式,Basi ...

  6. spring security 简单应用

    Pom <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http:// ...

  7. kuangbin带你飞dp专题-基础dp

    dp HDU - 1257 最少拦截系统 最长递增子序列 #include<iostream> using namespace std; const int maxn=1e7; int a ...

  8. C# 调用百度地图 Web 服务 API

    最近公司项目中需要根据两个地点的交通路径和距离做一些数据推荐,为了程序的稳定和用户体验所以想从百度地图 API 采集数据保存到数据库中,经过一翻研究之后选定了百度地图 Web 服务 API 中的 Di ...

  9. sklearn交叉验证3-【老鱼学sklearn】

    在上一个博文中,我们用learning_curve函数来确定应该拥有多少的训练集能够达到效果,就像一个人进行学习时需要做多少题目就能拥有较好的考试成绩了. 本次我们来看下如何调整学习中的参数,类似一个 ...

  10. 动态规划——Best Time to Buy and Sell Stock III

    题意:用一个数组表示股票每天的价格,数组的第i个数表示股票在第i天的价格. 如果最多进行两次交易,但必须在买进一只股票前清空手中的股票,求最大的收益. 示例 1:Input: [3,3,5,0,0,3 ...