C# 如何使用 RabbitMQ 实现消息收发
本文是基于http://www.cnblogs.com/cheng-lei/articles/7274513.html的项目结构进行搭建的,了解之前请先阅读http://www.cnblogs.com/cheng-lei/category/1047427.html中的前四篇文章。
工具 — Nuget包管理器 —程序包管理器控制台
PM> Install-Package RabbitMQ.Client -Version 5.1.0
PM> Install-Package EasyNetQ -Version 3.2.0
一、项目搭建
1. Weiz.MQ 项目,消息队列的通用处理类库,用于正在的订阅和发布消息。
1、在BusBuilder.cs中添加了对CreateAdvancedBus函数的实现。
public static IAdvancedBus CreateAdvancedBus()
{
// 消息服务器连接字符串
string connString = "host=dev.corp.wingoht.com:5672;virtualHost=cd;username=ishowfun;password=123456";
if (connString == null || connString == string.Empty)
{
throw new Exception("messageserver connection string is missing or empty");
} return RabbitHutch.CreateBus(connString).Advanced;
}
2、在MQHelper.cs中添加了对Send、Receive函数的实现。
public static void Send(MyMessage msg)
{
// 创建消息bus
IBus bus = BusBuilder.CreateMessageBus(); try
{
bus.Send(msg.MessageRouter, msg);
}
catch (EasyNetQException ex)
{
//处理连接消息服务器异常
Console.WriteLine("Send Error!!!");
} bus.Dispose();//与数据库connection类似,使用后记得销毁bus对象
} public static void Receive(MyMessage msg, IProcessMessage ipro)
{
// 创建消息bus
IBus bus = BusBuilder.CreateMessageBus(); try
{
bus.Receive<MyMessage>(msg.MessageRouter, message => ipro.ProcessMsg(message));
}
catch (EasyNetQException ex)
{
//处理连接消息服务器异常
Console.WriteLine("Receive Error!!!");
}
}
3、在MQHelper.cs中添加了对采用Fanout、Direct、Topic交换机类型进行消息收发功能的实现。
public static void ProducerFanoutMessage(MyMessage msg, string exchangeName = "chending.fanout")
{
var advancedBus = BusBuilder.CreateAdvancedBus(); if (advancedBus.IsConnected)
{
var exchange = advancedBus.ExchangeDeclare(exchangeName, ExchangeType.Fanout); advancedBus.Publish(exchange, "", false, new Message<MyMessage>(msg));
}
else
{
Console.WriteLine("Can't connect");
} } public static void ConsumeFanoutMessage(string exchageName = "chending.fanout", string queueName = "chending.fanout.queue")
{
var advancedBus = BusBuilder.CreateAdvancedBus();
var exchange = advancedBus.ExchangeDeclare(exchageName, ExchangeType.Fanout); var queue = advancedBus.QueueDeclare(queueName);
advancedBus.Bind(exchange, queue, queueName);
advancedBus.Consume(queue, registration =>
{
registration.Add<MyMessage>((message, info) => { Console.WriteLine("Fanout Content: {0}", message.Body.MessageBody); });
});
} public static void ProducerDirectMessage(MyMessage msg, string queueName = "chending.direct.queue")
{
var advancedBus = BusBuilder.CreateAdvancedBus(); if (advancedBus.IsConnected)
{
var queue = advancedBus.QueueDeclare(queueName); advancedBus.Publish(Exchange.GetDefault(), queue.Name, false, new Message<MyMessage>(msg));
}
else
{
Console.WriteLine("Can't connect");
} } public static void ConsumeDirectMessage(string exchageName = "chending.direct", string queueName = "chending.direct.queue")
{
var advancedBus = BusBuilder.CreateAdvancedBus();
var exchange = advancedBus.ExchangeDeclare(exchageName, ExchangeType.Direct); var queue = advancedBus.QueueDeclare(queueName);
advancedBus.Bind(exchange, queue, queueName);
advancedBus.Consume(queue, registration =>
{
registration.Add<MyMessage>((message, info) => { Console.WriteLine("Direct Content: {0}", message.Body.MessageBody); });
});
} public static void ProducerTopicMessage(MyMessage msg)
{
//// 创建消息bus
IBus bus = BusBuilder.CreateMessageBus(); try
{
bus.Publish(msg, x => x.WithTopic(msg.MessageRouter));
}
catch (EasyNetQException ex)
{
//处理连接消息服务器异常
} bus.Dispose();//与数据库connection类似,使用后记得销毁bus对象
} public static void ConsumeTopicMessage(MyMessage msg)
{
//// 创建消息bus
IBus bus = BusBuilder.CreateMessageBus(); try
{
bus.Subscribe<MyMessage>(msg.MessageRouter, message => Console.WriteLine("Topic Content: {0}", message.MessageBody), x => x.WithTopic(msg.MessageRouter));
}
catch (EasyNetQException ex)
{
//处理连接消息服务器异常
}
}
4、在ProduceThread.cs中添加了消息发布线程对前面实现的功能进行测试(也可以不作为线程直接调用)。
public class ProduceThread
{
public static void ProduceMessage() {
MyMessage msg1 = new MyMessage();
msg1.MessageID = "0-1";
msg1.MessageBody = DateTime.Now.ToString();
msg1.MessageRouter = "chending.fanout";
msg1.MessageTitle = "0-1";
MyMessage msg2 = new MyMessage();
msg2.MessageID = "0-2";
msg2.MessageBody = DateTime.Now.ToString();
msg2.MessageRouter = "chending.direct";
msg2.MessageTitle = "0-2";
MyMessage msg3 = new MyMessage();
msg3.MessageID = "0-3";
msg3.MessageBody = DateTime.Now.ToString();
msg3.MessageRouter = "chending.topic.a.b";
msg3.MessageTitle = "0-3"; //MQHelper.Send(msg1);
MQHelper.ProducerFanoutMessage(msg1);
MQHelper.ProducerDirectMessage(msg2);
MQHelper.ProducerTopicMessage(msg3); for (int i = ; i < ; i++) {
MyMessage msg = new MyMessage();
msg.MessageID = (i+).ToString();
msg.MessageBody = DateTime.Now.ToString();
if (i % == )
msg.MessageRouter = "cd.test.demo.a.b";
else
msg.MessageRouter = "cd.test.demo.a";
msg.MessageTitle = (i+).ToString(); MQHelper.Publish(msg);
//Console.WriteLine("Message{0} is published!!!", i + 1);
Thread.Sleep();
}
}
2. Weiz.Producer(生成者)已弃用(改用ProduceThread.cs)
3. Weiz.Consumer 就是Consumer(消费者)
1、修改OrderProcessMessage.cs,实现不同的消息处理方式。
public class OrderProcessMessage : MQ.IProcessMessage
{
public void ProcessMsg(MQ.MyMessage msg)
{
Console.WriteLine("ID: {0}, Title: {1}, Router: {2}, Content: {3}", msg.MessageID, msg.MessageTitle, msg.MessageRouter, msg.MessageBody);
}
}
public class OrderProcessMessage1:MQ.IProcessMessage
{
public void ProcessMsg(MQ.MyMessage msg)
{
Console.WriteLine("Process1 ID: {0}, Title: {1}, Router: {2}, Content: {3}", msg.MessageID, msg.MessageTitle, msg.MessageRouter, msg.MessageBody);
}
} public class OrderProcessMessage2 : MQ.IProcessMessage
{
public void ProcessMsg(MQ.MyMessage msg)
{
Console.WriteLine("Process2 ID: {0}, Title: {1}, Router: {2}, Content: {3}", msg.MessageID, msg.MessageTitle, msg.MessageRouter, msg.MessageBody);
}
}
2、对Program.cs中的Main调用进行了修改。
class Program
{
static void Main(string[] args)
{
//OrderProcessMessage order = new OrderProcessMessage();
OrderProcessMessage1 order1 = new OrderProcessMessage1();
OrderProcessMessage2 order2 = new OrderProcessMessage2(); //MyMessage msg = new MyMessage();
MyMessage msg1 = new MyMessage();
MyMessage msg2 = new MyMessage();
MyMessage msg3 = new MyMessage(); //msg.MessageRouter = "cd.test.demo";
msg1.MessageRouter = "cd.test.demo.*";
msg2.MessageRouter = "cd.test.demo.#";
msg3.MessageRouter = "chending.topic.#"; //MQHelper.Receive(msg, order);
MQHelper.ConsumeFanoutMessage();
MQHelper.ConsumeDirectMessage();
MQHelper.ConsumeTopicMessage(msg3);
MQHelper.Subscribe(msg1, order1);
//MQHelper.Subscribe(msg1, order2);
MQHelper.Subscribe(msg2, order2); Console.WriteLine("Listening for messages."); ProduceThread.ProduceMessage(); //ThreadStart threadStart = ProduceThread.ProduceMessage;
//Thread thread = new Thread(threadStart);
//thread.Start();
}
}
二、项目运行
启动 Weiz.Consumer (消费者),启动消费者,会自动在RabbitMQ 服务器上创建相关的exchange 和 queue ,同时调用的ProduceThread.ProduceMessage函数会发送消息,接收到的信息会在Console命令行中进行显示。
项目源码:百度云链接:https://pan.baidu.com/s/1sCJqY2fKphXV0ntMIytcVw 密码:hfz5
C# 如何使用 RabbitMQ 实现消息收发的更多相关文章
- 通过集群的方式解决基于MQTT协议的RabbitMQ消息收发
在完成了基于AMQP协议的RabbitMQ消息收发后,我们要继续实现基于MQTT协议的RabbitMQ消息收发. 由于C#的RabbitMQ.Client包中只实现了基于AMQP协议的消息收发功能的封 ...
- 第五节 RabbitMQ在C#端的应用-消息收发
原文:第五节 RabbitMQ在C#端的应用-消息收发 版权声明:未经本人同意,不得转载该文章,谢谢 https://blog.csdn.net/phocus1/article/details/873 ...
- RabbitMQ入门-消息订阅模式
消息派发 上篇<RabbitMQ入门-消息派发那些事儿>发布之后,收了不少反馈,其中问的最多的还是有关消息确认以及超时等场景的处理. 楼主,有遇到消费者后台进程不在,但consumer连接 ...
- rabbitmq(中间消息代理)在python中的使用
在之前的有关线程,进程的博客中,我们介绍了它们各自在同一个程序中的通信方法.但是不同程序,甚至不同编程语言所写的应用软件之间的通信,以前所介绍的线程.进程队列便不再适用了:此种情况便只能使用socke ...
- 整合Spring Cloud Stream Binder与RabbitMQ进行消息发送与接收
我最新最全的文章都在南瓜慢说 www.pkslow.com,欢迎大家来喝茶! 1 前言 Spring Cloud Stream专门用于事件驱动的微服务系统,使用消息中间件来收发信息.使用Spring ...
- RabbitMQ:消息丢失 | 消息重复 | 消息积压的原因+解决方案+网上学不到的使用心得
前言 首先说一点,企业中最常用的实际上既不是RocketMQ,也不是Kafka,而是RabbitMQ. RocketMQ很强大,但主要是阿里推广自己的云产品而开源出来的一款消息队列,其实中小企业用Ro ...
- twsited(5)--不同模块用rabbitmq传递消息
上一章,我们讲到,用redis共享数据,以及用redis中的队列来实现一个简单的消息传递.其实在真实的过程中,不应该用redis来传递,最好用专业的消息队列,我们python中,用到最广泛的就是rab ...
- 如何在项目中引入MetaQ消息收发机制
当需要异步发送和接收大量消息时,需要在Crystal项目中引入MetaQ消息收发机制. 关于MetaQ使用的官方例子可参考:https://github.com/killme2008/Metamorp ...
- RabbitMQ分布式消息队列服务器(一、Windows下安装和部署)
RabbitMQ消息队列服务器在Windows下的安装和部署-> 一.Erlang语言环境的搭建 RabbitMQ开源消息队列服务是使用Erlang语言开发的,因此我们要使用他就必须先进行Erl ...
随机推荐
- 奇妙的CSS3—导航栏下划线跟随效果
先来看一下效果: 1.基本效果就是这样的 ,鼠标悬停,下划线划入.鼠标离开,下划线划出 2.下划线的划入是有方向的,从左侧划入悬停,下划线由左向右伸长.从右侧划入,下划线由又往左伸长 实现思路 1.导 ...
- Spring Boot 构建一个 RESTful Web Service
1 项目目标: 构建一个 web service,接收get 请求 http://localhost:8080/greeting 响应一个json 结果: {"id":1,&qu ...
- 原生js创建模态框
1.效果图如下: 2.代码如下: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"& ...
- 生成Html 测试报告
1.引入HTMLTestRunner 下载HTMLTestRunner.py 从http://tungwaiyip.info/software/HTMLTestRunner.html 将下载的HTML ...
- Vcenter虚拟化三部曲----VMWare ESXi 5.5安装及配置
VMWare ESXi 5.5安装大概过程如下:制作虚拟化ESXi系统的USB启动盘,安装ESXi系统到USB,用USB启动ESXi系统.比较难理解,下面图解过程. 下载UNetbootin (下 ...
- 『ACM C++』 PTA 天梯赛练习集L1 | 025-026
满课一天,做25的时候还疯狂WA,进度可以说是很慢了 哭泣 ------------------------------------------------L1-025---------------- ...
- mac 装5.6版本mysql 设置密码
最的mysql在装的时候就可以设置 ,但是低版本的好像不行,需要在装了以后才能设置. mac下,mysql5.7.18连接出错,错误信息为:Access denied for user 'root'@ ...
- Linux下onvif客户端获取ipc摄像头 GetProfiles:获取h265媒体信息文件
GetProfiles:获取媒体信息文件 鉴权:但是在使用这个接口之前是需要鉴权的.ONVIF协议规定,部分接口需要鉴权,部分接口不需要鉴权,在调用需要鉴权的接口时不使用鉴权,会导致接口调用失败.实现 ...
- $.post({})请求springmvc -5.x 的方法,没有 返回数据的情况
转载请注明出处,毕竟调试了一天 今天用$.post({})传递参数,账号和密码来验证登录,验证成功返回1,验证不成功返回0,结果,$.post({}),的回调函数一直无法执行,但是原来是可以的,不重大 ...
- Oracle之子程序(存储过程、方法、包)
.过程[存储过程] CREATE [OR REPLACE] PROCEDURE <procedure name> [(<parameter list>)] IS|AS < ...