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 ...
随机推荐
- Linux(ubuntu18.04)切换python版本
前言 Ubuntu18.04系统在安装python时会安装两个版本:2.7和3.6.默认情况下系统环境使用的是python2,但是我们有时需要使用python3来作为我们的开发环境,所以需要自由切换p ...
- 网络基础 08_NAT
1 NAT的基本概念 为什么需要NAT IPv4地址紧缺 什么是NAT NAT(Network Address Translation) 私有IPv4地址 10.0.0.0 - 10.255.255. ...
- Python and Bluetooth
环境 Windows7-64bit + Python2.7.15-64bit + Pybluez 安装pybluez时会报错,处理方法~ 1.安装VCForPython27.msi,这是为了提供vis ...
- c# 获取项目根目录方法
编写程序的时候,经常需要用的项目根目录.自己总结如下 1.取得控制台应用程序的根目录方法 方法1.Environment.CurrentDirectory 取得或设置当前工作目录的完整限定路径 ...
- (转)CentOS7安装KVM虚拟机详解
原文:https://github.com/jaywcjlove/handbook/blob/master/CentOS/CentOS7%E5%AE%89%E8%A3%85KVM%E8%99%9A%E ...
- Ubuntu系统Apache Maven安装
操作系统:Linux x64 / Ubuntu 14.04 Apache Maven版本:3.3.9 建议预先搭建Java开发环境:详见上一篇<Linux Ubuntu系统下Java开发环境搭建 ...
- a+b+c的N次方展开
今天在给儿子看笔记本上的照片的时候,偶然发现了2009年手绘的一张a+b+c的N次方展开图,故写下面的博客以记之,为年轻时代的我点个赞! 20年前的我,一个充满激情的且富有专注力的数学发烧友! 10年 ...
- GB2312编码(为什么要加2020H、8080H,外码→内码→交换码→字形码)
为什么要加上2020H和8080H? 区位码.内码.国标码怎么转换非常简单,但是令人迷惑的是为什么要那么转换?这种转换不可能平白无故地那样转换! 我搜索很多资料,找到最好的解释,总结如下: 首先,注意 ...
- 我和ARM的那些事儿3 beep之旅,最详细的ARM裸机工程设置
前言 在博客园里面我搜索了老半天,找相应的mini2440的裸机开发的程序,让我挺失望的就是居然没有人对做arm这块做详细的解答,到底如何去做,到底如何去配置,都不清楚,让我很纠结,那么我花了近一星期 ...
- Django 中文文档地址
http://djangobook.py3k.cn/2.0/ MK一下