本例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. python使用stomp连接activemq

    一.安装ActiveMQ服务 1. 当使用windows时,安装参考:https://blog.csdn.net/WuLex/article/details/78323811 启动:运行activem ...

  2. noj算法 8皇后打印 回溯法

    描述: 输出8皇后问题所有结果. 输入: 没有输入. 输出: 每个结果第一行是No n:的形式,n表示输出的是第几个结果:下面8行,每行8个字符,‘A’表示皇后,‘.’表示空格.不同的结果中,先输出第 ...

  3. eclipse格式化代码快捷键失效

    原因是与搜狗输入法的“简繁切换”快捷键冲突(取消搜狗输入法的简繁切换快捷键,即可解决)

  4. Source Code Review

    1.berfore we talking abnout the Source Code review,here's what we want to know about the most popula ...

  5. python实现简单的登录管理

    import json,timeusername=[]userpasswd=[]def login_success_file(name): try: f=open(r"F:/login_su ...

  6. Hive SemanticException

    hive, sex='boy'); FAILED: SemanticException Line : Invalid path ''/root/data/hdata.txt'': No files m ...

  7. 利用fastjson解析json并通过js&ajax实现页面的无跳转刷新

    1.json是一种优秀的数据格式,在移动开发和web开发中经常用到,本例中通过一个小案例讲解如何通过alibaba的开源框架fastjson来解析jason数据格式并通过js实现无跳转刷新 2,新建一 ...

  8. H5测试与PC端测试不同的点

    1.通过H5网页(非手机的返回功能)的返回功能可以返回,不会出现无法返回的情况. 2.横屏竖屏相互切换,能自适应,并且布局不会乱掉: 3.为能在不同分辨率的手机上能更好的展示,建议采用响应式设计(如: ...

  9. DWM1000 测距原理简单分析 之 SS-TWR代码分析2 -- [蓝点无限]

    蓝点DWM1000 模块已经打样测试完毕,有兴趣的可以申请购买了,更多信息参见 蓝点论坛 正文: 首先将SS 原理介绍中的图片拿过来,将图片印在脑海里. 对于DeviceA 和 DeviceB来说,初 ...

  10. Selenium 2自动化测试实战

    Selenium 2自动化测试实战 百度网盘 链接:https://pan.baidu.com/s/1aiP3d8Y1QlcHD3fAlEj4sg 提取码:jp8e 复制这段内容后打开百度网盘手机Ap ...