由于公司业务需求,最近想上RabbitMQ,之前我研究了一段时间微软的MSMQ。开源队列有很多,各有优劣。就先拿RabbitMQ练练手吧。本篇着重代码部分,至于怎么安装,怎么配置不在赘述。而且代码是在RabbitMQ.NET Client 类库基础上实现。

  假设阅读本文的人已经安装好RabbitMQ并且做了相应的用户配置。而且项目中已经从nuget安装了rabbitmq.client.dll.我们开始做一个简单的队列发送和接收消息。

  1. 将需要配置的东西放在配置文件里,例如主机地址,端口,用户名,密码等。
  2. 实现消息发送端:Product
  3. 实现消息接收端:Customer
  4. Demo测试

  将以下内容作为可配置部分放在配置文件中

<appSettings>
<!--RabbitMQ-->
<add key="RabbitMQ_HostUri" value="amqp://192.168.1.119:5672/"/>
<add key="RabbitMQ_HostName" value="192.168.1.119"/>
<add key="RabbitMQ_UserName" value="test_user"/>
<add key="RabbitMQ_Password" value=""/>
<add key="RabbitMQ_VirtualHost" value="ms_mq"/>
</appSettings>

  由于只是对RabbitMQ.Client.dll中的又一次封装,所以代码不过多解释,其中要注意的就是某些配置问题,例如是否持久化,消息处理模式是怎么样的等等。

  首先我们创建一个连接工厂:

 public ConnectionFactory CreateFactory()
{
if (_factory == null) { const ushort heartbeat = ;
//主机地址
Uri uri = new Uri(RabbitMQConfig.HostUri); _factory = new ConnectionFactory();
//_factory.HostName = RabbitMQConfig.HostName;
//用户名
_factory.UserName = RabbitMQConfig.UserName;
//密码
_factory.Password = RabbitMQConfig.PassWord;
//虚拟主机名
_factory.VirtualHost = RabbitMQConfig.VirtualHost;
//连接终端
_factory.Endpoint = new AmqpTcpEndpoint(uri); _factory.RequestedHeartbeat = heartbeat;
//自动重连
_factory.AutomaticRecoveryEnabled = true;
}
return _factory;
}

  一个简单的消息发布:(对代码研究不够透彻,只能一切从简~~)

 public void Publish(string message, string queueName=null)
{
if (queueName == null) {
queueName = _queueName;
} var factory = RabbitMQFactory.Instance.CreateFactory();
using (var connection = factory.CreateConnection())
{
using (var model = connection.CreateModel())
{
//消息持久化,防止丢失
model.QueueDeclare(queueName, RabbitMQConfig.IsDurable, false, false, null);
var properties = model.CreateBasicProperties();
properties.Persistent = RabbitMQConfig.IsDurable;
properties.DeliveryMode = ; //消息转换为二进制
var msgBody = Encoding.UTF8.GetBytes(message);
//消息发出到队列
model.BasicPublish("", queueName, properties, msgBody);
}
}
}

  消息接收:

 public void Consume() {
var factory = RabbitMQFactory.Instance.CreateFactory(); var connection = factory.CreateConnection(); connection.ConnectionShutdown += Connection_ConnectionShutdown; ListenChannel = connection.CreateModel(); bool autoDeleteMessage = false;
var queue = ListenChannel.QueueDeclare(_queueName, RabbitMQConfig.IsDurable, false, false, null); //公平分发,不要同一时间给一个工作者发送多于一个消息
ListenChannel.BasicQos(, , false);
//创建事件驱动的消费者类型,不要用下边的死循环来消费消息
var consumer = new EventingBasicConsumer(ListenChannel);
consumer.Received += Consumer_Received;
//消费消息
ListenChannel.BasicConsume(_queueName, autoDeleteMessage, consumer);
}

  我在Customer中定义了一个 ReceiveMessageCallback Func回调,这里就是当客户端从队列接收到消息之后,怎么处理由客户端来决定

  public Func<string, bool> ReceiveMessageCallback { get; set; }

  处理消息:

 private void Consumer_Received(object sender, BasicDeliverEventArgs args) {
try {
var body = args.Body;
var message = Encoding.UTF8.GetString(body);
//将消息业务处理交给外部业务
bool result = ReceiveMessageCallback(message);
if (result) {
if (ListenChannel != null && !ListenChannel.IsClosed) {
ListenChannel.BasicAck(args.DeliveryTag, false);
}
}
else { } }
catch (Exception ex) {
throw ex;
}
}

  基本代码已经完成,我们写一个测试,消息发送端:

    static void Main(string[] args)
{
var testQueueName = "test";
IMessageProduct product = new MessageProduct(testQueueName);
for (int i = ; i < ; i++)
{
Console.WriteLine("正在发送第" + i + "条消息...");
product.Publish("消息体" + i);
} Console.Read();
}

  消息接收端:(开多个口接收)

    static void Main(string[] args)
{ Parallel.For(, RabbitMQConfig.ThreadCount, i =>
{
IMessageCustomer customer = new MessageCustomer("test");
         //开始监听
customer.StartListening();
customer.ReceiveMessageCallback = message =>
{
            //客户端处理消息(打印)
Console.WriteLine("接收到消息:" + message);
return true;
};
});
Console.Read();
}

  打开发送消息端:

  打开消息接收端:

  到此为止,RabbitMQ队列的简单测试就完成了,没有介绍什么新知识,基本就是套DLL中的方法,不过也有很多不合理的地方,如果真正应用到项目中,还需要多加测试和修改。

  DEMO地址:https://github.com/fanpan26/RabbitMQ.NETClient

RabbitMQ .NET Client 实战实验的更多相关文章

  1. RabbitMQ 整合 SpringCloud实战

    RabbitMQ 整合 SpringCloud实战RabbitMQ 整合 SpringCloud实战rabbitmq-common 子项目rabbitmq-springcloud-consumer 子 ...

  2. C# RabbitMQ优先级队列实战项目演练

    一.需求背景 当用户在商城上进行下单支付,针对客户等级的不同和订单金额的大小划分客户级别,需要优先处理给标识为大订单的客户发送一份订单邮件提醒.那么我们应用程序如何解决这样的需求场景呢?今天阿笨给大家 ...

  3. 译:1. RabbitMQ Java Client 之 "Hello World"

    这些教程介绍了使用RabbitMQ创建消息传递应用程序的基础知识.您需要安装RabbitMQ服务器才能完成教程 1. 打造第一个Hello World 程序 RabbitMQ是一个消息代理:它接受和转 ...

  4. 五、RabbitMQ Java Client基本使用详解

    Java Client的5.x版本系列需要JDK 8,用于编译和运行.在Android上,仅支持Android 7.0或更高版本.4.x版本系列支持7.0之前的JDK 6和Android版本. 加入R ...

  5. rabbitmq - java client lib一二事

    由于不可抗因素, 需要给对接方撸一个client的demo.基于比较老的jdk. 所幸找到了这里:http://www.rabbitmq.com/releases/rabbitmq-java-clie ...

  6. 译:2. RabbitMQ Java Client 之 Work Queues (工作队列)

    在上篇揭开RabbitMQ的神秘面纱一文中,我们编写了程序来发送和接收来自命名队列的消息. 本篇我们将创建一个工作队列,工作队列背后的假设是每个任务都交付给一个工作者 本篇是译文,英文原文请移步:ht ...

  7. 译:3.RabbitMQ Java Client 之 Publish/Subscribe(发布和订阅)

    在上篇 RabbitMQ 之Work Queues (工作队列)教程中,我们创建了一个工作队列,工作队列背后的假设是每个任务都交付给一个工作者. 在这一部分,我们将做一些完全不同的事情 - 我们将向多 ...

  8. 译:4.RabbitMQ Java Client 之 Routing(路由)

    在上篇博文 译:3.RabbitMQ 之Publish/Subscribe(发布和订阅)  我们构建了一个简单的日志系统 我们能够向许多接收者广播日志消息. 在本篇博文中,我们将为其添加一个功能 - ...

  9. 译:5.RabbitMQ Java Client 之 Topics (主题)

    在 上篇博文 译:4.RabbitMQ 之Routing(路由) 中,我们改进了日志系统. 我们使用的是direct(直接交换),而不是使用只能进行虚拟广播的 fanout(扇出交换) ,并且有可能选 ...

随机推荐

  1. 【CAD】自定义实体的步骤(转)

    本文介绍了构造自定义实体的步骤.必须继承的函数和必须注意的事项 1.新建一个从AcDbEntity继承的类,如EntTest,必须添加的头文件: "stdarx.h"," ...

  2. TOJ 3488 Game Dice

    描述 In the game of Dungeons & Dragons, players often roll multi-sided dice to generate random num ...

  3. 飞檐走壁navMesh

    http://www.manew.com/thread-106030-1-1.html

  4. [Verilog] parameter

    parameter和localparam的作用范围均为本模块,区别在于前者可用于在实例化模块的时候进行参数的传递. 用已定义的参数对变量赋值时,按照补码的方式处理,若出现溢出的情况,则截取低位.

  5. React.js 小书 Lesson10 - 组件的 state 和 setState

    作者:胡子大哈 原文链接:http://huziketang.com/books/react/lesson10 转载请注明出处,保留原文链接和作者信息. state 我们前面提到过,一个组件的显示形态 ...

  6. 1.Vue.js的常用指令

      Vue.js介绍 Vue.js是当下很火的一个JavaScript MVVM库,它是以数据驱动和组件化的思想构建的.相比于Angular.js,Vue.js提供了更加简洁.更易于理解的API,使得 ...

  7. javascript模块化是什么及其优缺点介绍

    模块化是一种将系统分离成独立功能部分的方法,可将系统分割成独立的功能部分,严格定义模块接口.模块间具有透明性 如今backbone.emberjs.spinejs.batmanjs 等MVC框架侵袭而 ...

  8. vue路由配置

    1.安装 npm install vue-router --save / cnpm install vue-router --save 2.引入并 Vue.use(VueRouter) (main.j ...

  9. lua_nginx_module用例

    content_by_lua server { listen ; server_name lua.luckybing.top; location / { default_type 'text/plai ...

  10. artDialog组件应用学习(二)

    一.没有操作选项的对话框 预览: html前台引入代码:(之后各种效果对话框引入代码致,调用方法也一样,就不一一写入) <script type="text/javascript&qu ...