コード例 #1
0
        public void Receive()
        {
            var conn = new GetConnection();

            conn.MqHandle((connection, channel) =>
            {
                //声明一个名为hello的队列
                QueueDeclare.QueueDeclareByName("hello", connection, channel);

                //接下来我们通知服务器可以将消息从队列里发送过来了。由于服务器会异步地将消息推送给我们,所以我们这里提供一个回调方法。这就是EventingBasicConsumer.Receivedevent所做的工作。
                var consumer       = new EventingBasicConsumer(channel);
                consumer.Received += (conn, ea) =>
                {
                    ///Thread.Sleep(2000);
                    var body    = ea.Body.Span;
                    var message = Encoding.UTF8.GetString(body);
                    Console.WriteLine(" [x] Received {0}", message);
                };

                ///param1:消费哪个队列的消息 队列名称
                ///param2:开始消息的自动确认机制
                ///param3;消费时的回调接口
                channel.BasicConsume(queue: "hello",
                                     autoAck: true,
                                     consumer: consumer);

                Console.WriteLine(" Press [enter] to exit.");
                Console.ReadLine();
            });
        }
コード例 #2
0
ファイル: SingleSend.cs プロジェクト: inderted/RabbitMqTest
        public void Send()
        {
            var conn = new GetConnection();

            conn.MqHandle((connection, channel) =>
            {
                //声明一个名为hello的队列
                QueueDeclare.QueueDeclareByName("hello", connection, channel);

                for (int i = 0; i < 1000; i++)
                {
                    var body = Encoding.UTF8.GetBytes(i.ToString());

                    //消息写入到hello队列中

                    ///param1:交换机名称
                    ///param2:队列名称
                    ///param3:传递消息额外设置
                    ///param4:消息具体内容
                    channel.BasicPublish(exchange: "",
                                         routingKey: "hello",
                                         basicProperties: null,
                                         body: body);
                    Console.WriteLine(" [x] Sent {0}", i);
                }
            });

            Console.WriteLine(" Press [enter] to exit.");
            Console.ReadLine();
        }
コード例 #3
0
        public void Receive()
        {
            var conn = new GetConnection();

            conn.MqHandle((connection, channel) =>
            {
                //声明一个名为hello的队列
                QueueDeclare.QueueDeclareByName("task_query", connection, channel);

                #region BasicQos
                //你可能注意到了,调度依照我们希望的方式运行。例如在有两个工作者的情况下,当所有的奇数任务都很繁重而所有的偶数任务都很轻松的时候,其中一个工作者会一直处于忙碌之中而另一个几乎无事可做。RabbitMQ并不会对此有任何察觉,仍旧会平均分配消息。

                //这种情况发生的原因是由于当有消息进入队列时,RabbitMQ只负责将消息调度的工作,而不会检查某个消费者有多少未经确认的消息。它只是盲目的将第n个消息发送给第n个消费者而已。

                //img

                //要改变这种行为的话,我们可以在BasicQos方法中设置prefetchCount = 1。这样会告诉RabbitMQ一次不要给同一个worker提供多于一条的信息。话句话说,在一个工作者还没有处理完消息,并且返回确认标志之前,不要再给它调度新的消息。取而代之,它会将消息调度给下一个不再繁忙的工作者
                #endregion
                channel.BasicQos(prefetchSize: 0, prefetchCount: 1, global: false);
                Console.WriteLine(" [*] Waiting for messages.");

                //接下来我们通知服务器可以将消息从队列里发送过来了。由于服务器会异步地将消息推送给我们,所以我们这里提供一个回调方法。这就是EventingBasicConsumer.Receivedevent所做的工作。
                var consumer       = new EventingBasicConsumer(channel);
                consumer.Received += (conn, ea) =>
                {
                    var body    = ea.Body.Span;
                    var message = Encoding.UTF8.GetString(body);
                    Console.WriteLine(" [x] Received {0}", message);
                    Thread.Sleep(1000);
                    Console.WriteLine(" [x] Done");

                    //忘记使用BasicAck是一个常见的错误。虽然是个简单的错误,但是后果严重。消息会在客户端退出后重新投送(就像是随机进行的重新投送),但是由于RabbitMQ无法释放任何未经确认的消息,内存占用会越来越严重。

                    //手动确认消息完成
                    channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false);
                };

                ///param1:消费哪个队列的消息 队列名称
                ///param2:开始消息的自动确认机制
                ///param3;消费时的回调接口
                channel.BasicConsume(queue: "task_query",
                                     autoAck: false,
                                     consumer: consumer);

                Console.WriteLine(" Press [enter] to exit.");
                Console.ReadLine();
            });
        }
コード例 #4
0
        public void Send()
        {
            var conn = new GetConnection();

            conn.MqHandle((connection, channel) =>
            {
                //声明一个名为hello的队列
                QueueDeclare.QueueDeclareByName("task_query", connection, channel);

                //IBasicProperties.SetPersistent设置为true,用来将我们的消息标示成持久化的。
                var properties        = channel.CreateBasicProperties();
                properties.Persistent = true;

                #region 关于消息持久化的注释

                //消息持久化的注释
                //将消息标示为持久化并不能完全保证消息不会丢失。尽管它会告诉RabbitMQ将消息存储到硬盘上,但是在RabbitMQ接收到消息并将其进行存储两个行为之间仍旧会有一个窗口期。同样的,RabbitMQ也不会对每一条消息执行fsync(2),所以消息获取只是存到了缓存之中,而不是硬盘上。虽然持久化的保证不强,但是应对我们简单的任务队列已经足够了

                #endregion

                for (int i = 0; i < 1000; i++)
                {
                    var body = Encoding.UTF8.GetBytes(i.ToString());

                    //消息写入到hello队列中

                    ///param1:交换机名称
                    ///param2:队列名称
                    ///param3:传递消息额外设置
                    ///param4:消息具体内容
                    channel.BasicPublish(exchange: "",
                                         routingKey: "task_query",
                                         basicProperties: properties,
                                         body: body);
                    Console.WriteLine(" [x] Sent {0}", i);
                }
            });

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