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 ...
随机推荐
- Linux中使用iptables开放特定端口
禁止其他主机对该特定主机进行访问和远程连接控制,所以只开放特定端口 只控制INPUT链就可达到控制其他主机对该主机的访问. 1.首先关闭INPUT链 iptables -P INPUT DROP 使用 ...
- CC2640R2F&TI-RTOS 拿到 TI CC2640R2F 开发板 第二件事就是 LED 驱动 ,点个灯
/* * board_led.c * * Created on: 2018年7月3日 * Author: admin */ #include "board_uart.h" #inc ...
- 我的QT5学习之路(二)——第一个程序
一.前言 “工欲善其事,必先利其器”,上一节,我介绍了Qt的安装和配置方法,搭建了基本的开发平台.这一节,来通过一个简单的例子来了解Qt的编程样式和规范,开始喽~~~ 二.第一个程序——Hello W ...
- Centos 7安装Grafana 4及结合Zabbix3.2实现可视化监控图形
上一篇介绍了如何在Centos 7环境下安装zabbix监控,本章继续介绍在Centos 7环境下安装Grafana,并结合Zabbix实现可视化监控图形! 简介: Grafana 是 Graphit ...
- iOS之Custom UIViewController Transition
本文学习下自定义ViewController的切换,从无交互的到交互式切换. (本文已同步到我的小站:icocoa,欢迎访问.) iOS7中定义了3个协议: UIViewControllerTrans ...
- throws、throw和try catch
在学习代理模式的时候,编写动态生成代理类.java文件时,用try{}catch(){}捕获异常发现catch(Exception e)报错,得换成catch(Throwable e),然后又查了查两 ...
- 关于DP
关于DP 似乎摸到了门槛呢,学着学着Dijkstra突然有了感觉. 我们遍历的时候会遍历整张图的每个点每条边,然后与已知的对比大小,如果比现在方案好,就放入数组 那么,DP岂不是同样的思想? 在背包问 ...
- ztz11的noip模拟赛T3:评分系统
代码: #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> ...
- 【Linux】文件、目录权限及归属
访问权限: 可读(read):允许查看文件内容.显示目录列表 可写(write):允许修改文件内容,允许在目录中新建.移动.删除文件或子目录 可执行(execute):允许运行程序.切换目录 归属: ...
- Tomcat 或JBOSS java.lang.ArrayIndexOutOfBoundsException: 8192原因及其解决方法
2018-04-02 09:24:55 org.apache.catalina.connector.CoyoteAdapter service 严重: An exception or error oc ...