WinForm实现Rabbitmq官网6个案例-Work Queues
代码:
namespace RabbitMQDemo
{
public partial class WorkQueues : Form
{
private string queueName = "WorkQueues_queue";
Action<string, TextBox> SetText;
private readonly static WorkQueues _WorkQueues;
static WorkQueues()
{
_WorkQueues = new WorkQueues();
}
/// <summary>
/// 单例模式
/// </summary>
public static WorkQueues SingleForm { get { return _WorkQueues; } }
private WorkQueues()
{
CheckForIllegalCrossThreadCalls = false;
InitializeComponent();
ReceiveMsg(txtConsumer1);//消费者1
ReceiveMsg(txtConsumer2);//消费者2
SetText += OnSetText;
} private void btnSendMsg_Click(object sender, EventArgs e)
{
SendMsg();
}
/// <summary>
/// 发送消息
/// </summary>
private void SendMsg()
{
string message = txtPublisher.Text;
if (message.Trim().Length <= )
{
MessageBox.Show("请输入要发送的消息");
}
var factory = new ConnectionFactory() { HostName = "localhost" };
using (var connection = factory.CreateConnection())
using (var channel = connection.CreateModel())
{
//durable-队列持久化,为true的时候告诉rabbitmq不管服务器停止运行还是崩溃或重启都不能丢失队列queue(已经声明过的队列无法再重新定义durable的值,如果这样做了,服务器会返回一个错误)
channel.QueueDeclare(queue: queueName,
durable: true,
exclusive: false,
autoDelete: false,
arguments: null); var body = Encoding.UTF8.GetBytes(message); //消息持久化-为true的时候告诉rabbitmq不管服务器停止运行还是崩溃或重启都不能丢失队列queue,这种消息持久化方式不能保证消息永不丢失,它告诉rabbitmq将消息保存到磁盘,但是当rabbitmq接收到消息但是还没有保存的时候有一个很短的时间窗口.此外,rabbitmq不会为每个消息执行fsync(2)-它可能只是保存到缓存中,而不是真正的写入磁盘.这种消息持久化方式保证不强,用于要求不那么严格的任务队列,已经足够,如果要更完善的消息持久化,可以使用publisher confirms
var properties = channel.CreateBasicProperties();
properties.Persistent = true; channel.BasicPublish(exchange: "",
routingKey: queueName,
basicProperties: properties,
body: body);
}
}
/// <summary>
/// 接收消息
/// </summary>
private void ReceiveMsg(TextBox box)
{
try
{
var factory = new ConnectionFactory() { HostName = "localhost" };
var connection = factory.CreateConnection();
var channel = connection.CreateModel(); channel.QueueDeclare(
queue: queueName,
durable: true,
exclusive: false,
autoDelete: false,
arguments: null); //公平分发
//默认情况下rabbitmq会将消息平均地发给消费者,不管消费者是否正在处理消息,也不会考虑消费者是否返回未确认消息,这会造成资源浪费.假如队列中有10条消息,有2个消费者,那么每个消费者会收到5条消息,如果说其中5条消息是要花费大量时间的,并且这5条消息都刚好发送给了第一个消费者,那么第1个消费者将会一直处于忙碌状态,而第二个消费者假如处理的另外5条消息都不花费多少时间那么第二个消费者就会闲置.prefetchCount=1告诉rabbitmq不要向我发送新的消息,直到我处理并确认了前一个消息,然后rabbitmq将会把消息发给下一个消费者
//假如所有的消费者都处于忙碌状态(没有反馈消息确认给rabbitmq)那么消息将在队列中排队等待,这可能造成queue存储空间不足,需要采取预防措施
channel.BasicQos(
prefetchSize: ,
prefetchCount: ,
global: false); var consumer = new EventingBasicConsumer(channel);
consumer.Received += (model, ea) =>
{
var msg = Encoding.UTF8.GetString(ea.Body); //要求发送的消息包含'.',每个'.'让线程花1秒时间处理,10个花10秒
int dots = msg.Split('.').Length - ;
Thread.Sleep(dots * ); //将消息显示在界面上
box.Invoke(SetText, msg, box); //手动想rabbitmq发送消息确认
channel.BasicAck(
deliveryTag: ea.DeliveryTag,
multiple: false);
}; //消息确认
//noAck-自动回复消息 为true的时候consumer收到了一个消息就会立刻返回一个标记给rabbitmq告诉它这个消息我已经拿到了,你可以自由的删除掉它,至于consumer怎么处理这个消息或者处理的过程中出错了在rabbitmq中将找不回这个消息(使用这种方式要确保consumer不会挂掉,否则消息容易丢失)
channel.BasicConsume(
queue: queueName,
noAck: false,
consumer: consumer);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
} private void OnSetText(string text, TextBox box)
{
box.Text += string.Format("{0}\r\n", text);
}
}
}
界面:

大概流程:
生产者发送一条消息,如果消息包含英文句点'.',那么每一个句点标识消费者处理这条消息要花费的时间,这个时候该消费者就不再接收来自rabbitmq的消息,rabbitmq将会把消息发给下一个消费者以保证不会有消费者要么一直忙碌要么一直闲置的bug,同时要注意的是,一旦一个消息发送给了一个消费者另一个消费者就得不到这条消息,只能拿到下一条
测试结果:




WinForm实现Rabbitmq官网6个案例-Work Queues的更多相关文章
- WinForm实现Rabbitmq官网6个案例-RPC
获取源码 客户端代码: namespace RabbitMQDemo { public partial class RPC : Form { private readonly static RPC _ ...
- WinForm实现Rabbitmq官网6个案例-Publishe/Subscribe
代码: namespace RabbitMQDemo { public partial class PublishSubscribe : Form { private string exchangeN ...
- WinForm实现Rabbitmq官网6个案例-Hello World
先上代码 namespace RabbitMQDemo { public partial class HelloWorld : Form { string queueName1 = "hel ...
- WinForm实现Rabbitmq官网6个案例-Topics
代码: namespace RabbitMQDemo { public partial class Topics : Form { private string exchangeName = &quo ...
- WinForm实现Rabbitmq官网6个案例-Routing
代码: namespace RabbitMQDemo { public partial class Routing : Form { private string exchangeName = &qu ...
- 官网英文版学习——RabbitMQ学习笔记(一)认识RabbitMQ
鉴于目前中文的RabbitMQ教程很缺,本博主虽然买了一本rabbitMQ的书,遗憾的是该书的代码用的不是java语言,看起来也有些不爽,且网友们不同人学习所写不同,本博主看的有些地方不太理想,为此本 ...
- 2022年官网下安装RabbitMQ最全版与官网查阅方法
目录 一.Erlang环境部署 1.百度搜索"Erlang",或者访问网址:https://www.erlang.org/,找到DOWNLOAD双击进入. 2.找到支持的windo ...
- Yeoman 官网教学案例:使用 Yeoman 构建 WebApp
STEP 1:设置开发环境 与yeoman的所有交互都是通过命令行.Mac系统使用terminal.app,Linux系统使用shell,windows系统可以使用cmder/PowerShell/c ...
- MXNet官网案例分析--Train MLP on MNIST
本文是MXNet的官网案例: Train MLP on MNIST. MXNet所有的模块如下图所示: 第一步: 准备数据 从下面程序可以看出,MXNet里面的数据是一个4维NDArray. impo ...
随机推荐
- 46.ActiveMQ开篇(Hello World、安全认证、Connection、Session、MessageProducer、MessageConsumer)
要给有能力的人足够的发挥空间,公司可以养一些能力平平甚至是混日子的人,但绝不能让这些人妨碍有能力的人,否则这样的环境不留也罢. 一.背景介绍 CORBA\DCOM\RMI等RPC中间件技术已经广泛应用 ...
- TX2 i2c-tools使用
安装: apt-get install libi2c-dev i2c-tools 检测i2c总线数目 用i2cdetect检测有几组i2c总线在系统上: i2cdetect -l 可以看到系统中有9组 ...
- Carte上面的作业1、2天就会丢失的问题
发现Carte上面的作业莫名其妙就会没有,问了客户的维护人员说也没删除. 对象时间也是No Limit,但还是隔1.2天就不见了. 那说明之前配置这里还是无效 <slave_config> ...
- 判断h5页面是小程序环境还是微信环境
1.话不多说直接上代码,已使用有效 <script type="text/javascript" src="https://res.wx.qq.com/open/j ...
- Spring Security 入门
一.Spring Security简介 Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架.它提供了一组可以在Spring应用上下文中配 ...
- maven 打包 war 包含 WEB-INF/lib 目录
<plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactI ...
- Haskell优雅的快排实现
说得快速排序,基本是常用的排序当中速度最快的排序了,之前也用C和Java实现过,但是过程十分痛苦,更重要的是写完代码只记得过程却对实质的过程觉得隔了一层纱,有种说不出的感觉.刚刚看一下Haskell实 ...
- MySQL的库、表详细操作
本节目录 一.库操作 二.表操作 三.行操作 一.库操作 1.创建数据库 1.1 语法 CREATE DATABASE 数据库名 charset utf8; 1.2 数据库命名规则 可以由字母.数字. ...
- Ubuntu里面vi编辑器在编辑文本时 如何在所有行行首或行尾插入字符
例如:我这里是在每一行行首插入new :%s/^/new 在20,50行首插入new :20,50s/^/new 在每一行行尾插入@@ :%s/$/@@ 在20到50行行尾插入## :20,50s/$ ...
- C#多线程学习一
一.概述:C#支持多线程并行执行程序,一个线程有他单独的执行路径,能够与其他线程同时执行,一个程序是由一个单线程开始,该单线程由CLR(公共语言运行时)和操作系统创建而成,并具有多线程创建额外线程的功 ...