RabbitMQ如何发送与接收数据

本文运行环境:rabbitmq-server-3.8.3,客户端使用RabbitMQ.Client 3.6.14 开发工具vs2015。

安装好rabbitmq之后,接下来学习一下如何使用,先来添加一个队列并发送一个消息进队列。新建一个发送端的工程并引用RabbitMQ.Client.dll

CS文件中添加如下引用

本文过程分为连接操作和发送操作

连接操作代码:

private void btnConnect_Click(object sender, EventArgs e)
        {
            if (btnConnect.Text.Equals("连接"))
            {
                factory.HostName = txtIp.Text;//Rabbit server所在地址
                int port = 5672;//默认端口
                int.TryParse(txtPort.Text, out port);
                factory.Port = port;
                factory.UserName = txtLoginID.Text;//登录用户,同登录Rabbit web管理工具
                factory.Password = txtPwd.Text;//登录密码,同登录Rabbit web管理工具
                factory.RequestedHeartbeat = 60;

                connection = factory.CreateConnection();
                channel = connection.CreateModel();
                if (connection.IsOpen && channel.IsOpen)
                {
                    btnConnect.Text = "断开连接";
                    btnConnect.BackColor = Color.Green;
                    //channel.QueueDeclare(txtQueueName.Text, false, false, false, null);//创建一个名称为txtQueueName.Text的消息队列,非持久化的队列
                    channel.QueueDeclare(txtQueueName.Text, true, false, false, null);//创建一个名称为txtQueueName.Text的消息队列,持久化的队列

                }
                else
                {
                    btnConnect.Text = "连接";
                    btnConnect.BackColor = Color.Red;
                }
            }
            else
            {
                if (!channel.IsOpen)
                {
                    channel.Close();
                    channel.Dispose();
                }
                if(!connection.IsOpen)
                {
                    connection.Close();
                    connection.Dispose();
                }
                if (!connection.IsOpen && !channel.IsOpen) btnConnect.Text = "连接";
            }
        }

发送操作代码:

private void btnSend_Click(object sender, EventArgs e)
        {
            if(txtMessage.Text != "")
            {
                var properties = channel.CreateBasicProperties();
                properties.DeliveryMode = 1;
                properties.Persistent = true;
                channel.BasicPublish("", "scott", properties, Encoding.UTF8.GetBytes(txtMessage.Text));
            }
        }

以下是运行结果

可以在web管理工具界面看到新增的队列及发送出去的消息。在上述代码中,使用了队列持久化参数durable = true,channel.QueueDeclare(txtQueueName.Text, true, false, false, null); QueueDeclare第二个参数,该队列在服务端关机重启后还会存在。

队列和消息都已经产生了,接近来新建一个用于接收消息的工程,需要的引用同上。RabbitMQ接收消息分为两种情况,主动获取和等待推送。主动获取的方法:var result = channel.BasicGet("scott", true);  主动获取需要定时去请求数据,这种操作比较耗资源,性能不高,试想一下,如果一天新消息并不多,程序要产生大量的请求然而多数情况下是一无所获,所以并非首选。本文使用等待推送的方式。

先在接收消息窗体文件中添加全局变量

ConnectionFactory factory = new ConnectionFactory();
IConnection connection;
IModel channel;
EventingBasicConsumer consumer;

连接操作代码

private void btnConnect_Click(object sender, EventArgs e)
        {
            if (btnConnect.Text.Equals("连接"))
            {
                factory.HostName = txtIp.Text;//主机名,Rabbit会拿这个IP生成一个endpoint,就是socket绑定的那个终结点。
                int port = 5672;
                int.TryParse(txtPort.Text, out port);
                factory.Port = port;
                factory.UserName = txtLoginID.Text;//默认用户名,用户可以在服务端自定义创建,有相关命令行
                factory.Password = txtPwd.Text;//默认密码
                factory.RequestedHeartbeat = 60;

                connection = factory.CreateConnection();
                channel = connection.CreateModel();
                if (connection.IsOpen && channel.IsOpen)
                {
                    btnConnect.Text = "断开连接";
                    btnConnect.BackColor = Color.Green;
                    btnReceiving.Enabled = true;
                }
                else
                {
                    btnConnect.Text = "连接";
                    btnConnect.BackColor = Color.Red;
                    btnReceiving.Enabled = false;
                }
            }
            else
            {
                if (channel.IsOpen)
                {
                    channel.Close();
                    channel.Dispose();
                }
                if (connection.IsOpen)
                {
                    connection.Close();
                    connection.Dispose();
                }
                if (!connection.IsOpen && !channel.IsOpen) btnConnect.Text = "连接";
            }
        }

接收操作代码

private void btnReceiving_Click(object sender, EventArgs e)
        {
            btnReceiving.Enabled = false;
            try
            {
                channel.QueueDeclare(txtQueueName.Text, true, false, false, null);
                channel.BasicQos(0, 1, false);
                consumer = new EventingBasicConsumer(channel);//消费者
                consumer.Received += (model, ea) =>
                {

                    var body = ea.Body;
                    var message = Encoding.UTF8.GetString(body);
                    Action act = delegate () {
                        lstMsg.Items.Add(message);
                    };
                    this.Invoke(act);
                    channel.BasicAck(ea.DeliveryTag,true);
                };
                channel.BasicConsume("scott", false, consumer);//消费消息
            }
            catch
            { }
            finally
            {
                
            }
        }

接收新消息后显示添加到list显示

可以看到队列scott中的消息已经被获取到了,也就是被消费了,确认消费代码 channel.BasicAck(ea.DeliveryTag,true);

在接收消息测试中,网上包括官网提供的代码,以下是官网代码来自于https://www.rabbitmq.com/tutorials/tutorial-one-dotnet.html

using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System;
using System.Text;

class Receive
{
    public static void Main()
    {
        var factory = new ConnectionFactory() { HostName = "localhost" };
        using(var connection = factory.CreateConnection())
        using(var channel = connection.CreateModel())
        {
            channel.QueueDeclare(queue: "hello",
                                 durable: false,
                                 exclusive: false,
                                 autoDelete: false,
                                 arguments: null);

            var consumer = new EventingBasicConsumer(channel);
            consumer.Received += (model, ea) =>
            {
                var body = ea.Body;
                var message = Encoding.UTF8.GetString(body.ToArray());
                Console.WriteLine(" [x] Received {0}", message);
            };
            channel.BasicConsume(queue: "hello",
                                 autoAck: true,
                                 consumer: consumer);

            Console.WriteLine(" Press [enter] to exit.");
            Console.ReadLine();
        }
    }
}

 以下是网上查到的部分写法

using (var connection = factory.CreateConnection())
            {
                using (var channel = connection.CreateModel())
                {
                    channel.QueueDeclare("scott", true, false, false, null);
            
                    var consumer = new EventingBasicConsumer(channel);//消费者
                    
                    consumer.Received += (model, ea) =>
                    {
                        var body = ea.Body;
                        var message = Encoding.UTF8.GetString(body);
                        Console.WriteLine($"Received:{message}");
                    };
            }
}

上面这两种写法在我本机环境下测试不会触发推送事件,也就是using (var connection = factory.CreateConnection())和 using (var channel = connection.CreateModel())这种模式影响了接收事件consumer.Received,因为这里using作用域结束后,connection和channel已经被释放掉了。所以我在本文中测试中将它们都定义为全局的了,至于官网和网上这种写法目前还是有疑问,也不知道是不是版本问题呢。

文中代码位置: https://github.com/ScottFan/RabbitMQ_DEMO

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值