消息队列第二篇:MessageQueue实战(课程订单)
本篇一开始就上代码,主要演练MessageQueue的实际应用。用户提交订单(消息发送),系统将订单发送到订单队列(Order Queue)中;订单管理系统(消息接收)端,监听消息队列,收到新的消息就显示在订单列表中,用户可以处理订单。原创(每行代码皆为自己手敲的)
1、提交课程订单
public partial class Form1 : Form
{
// author:fjzhang 2017-08-01
public Form1()
{
InitializeComponent();
}
/// <summary>
/// 提交订单按钮
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnSubmit_Click(object sender, EventArgs e)
{
try
{
//实例一个课程订单对象
var order = new CourseOrder();
//订单信息
order.Course = new Course()
{
Title = comboBoxCourse.SelectedItem.ToString()
};
//顾客信息
order.Customer = new Customer()
{
Company = textBoxCompany.Text,
Contact = textBoxContact.Text
};
//实例一个队列对象
using (var queue = new MessageQueue(CourseOrder.CourseOrderQueueName))
{
//实例一个消息对象
using (var message = new System.Messaging.Message(order))
{
//设置优先级
if (checkBoxPriority.CheckState == CheckState.Checked)
{
message.Priority = MessagePriority.High;
}
//设置消息可以恢复
message.Recoverable = true;
//发送消息
queue.Send(order, string.Format("课程订单[{0}]", order.Customer.Company));
}
}
//提示订单提交成功
MessageBox.Show("订单提交成功!", "课程订单", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (MessageQueueException ex)
{
//提示异常信息
MessageBox.Show(ex.Message, "异常提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
2、处理课程订单
/// <summary>
/// 订单处理界面 author:fjzhang 2017-08-01
/// </summary>
public partial class Form1 : Form
{
/// <summary>
/// 订单队列
/// </summary>
private MessageQueue orderQueue;
/// <summary>
/// 构造函数,初始化界面窗体,监听订单队列
/// </summary>
public Form1()
{
InitializeComponent();
//队列名称
string queueName = CourseOrder.CourseOrderQueueName;
//初始化订单队列
orderQueue = new MessageQueue(queueName);
//设置消息类型
orderQueue.Formatter = new XmlMessageFormatter(new Type[] {
typeof(CourseOrder),
typeof(Customer),
typeof(Course)
});
//在未收到订单之前,不启用处理订单按钮
btnProcessOrder.Enabled = false;
//开始监听订单队列
Task t1 = new Task(PeekMessages);
t1.Start();
}
/// <summary>
/// 监听订单队列(如果收到新订单,就在订单列表显示出来)
/// </summary>
private void PeekMessages()
{
//使用消息队列枚举器来显示队列的所有消息
using (MessageEnumerator messagesEnumerator = orderQueue.GetMessageEnumerator2())
{
//检查队列中是否有新消息。如果没有消息,就等待队列的新消息,这里设置等待3小时后才退出。
while (messagesEnumerator.MoveNext(TimeSpan.FromHours(3)))
{
//这里的LaBELIdMapping是我自己定义的,就两字String类型的字段(Id,Label)
var lableId = new LabelIdMapping()
{
Id = messagesEnumerator.Current.Id,
Label = messagesEnumerator.Current.Label
};
//使用主线程执行新增收到订单行
this.Invoke(new EventHandler(delegate
{
AddListItem(lableId);
}));
}
//提示等待3小时还没有新消息进队列
MessageBox.Show("三小时内没有订单", "退出提醒", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
/// <summary>
/// 在订单列表新增一项
/// </summary>
/// <param name="labelIdMapping"></param>
private void AddListItem(LabelIdMapping labelIdMapping)
{
//在listBox控件中新增一行
listBox1.Items.Add(labelIdMapping);
}
/// <summary>
/// 处理订单
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnProcessOrder_Click(object sender, EventArgs e)
{
LabelIdMapping labelId = listBox1.SelectedItem as LabelIdMapping;
var message = orderQueue.ReceiveById(labelId.Id);
listBox1.Items.Remove(labelId);
listBox1.SelectedIndex = -1;
btnProcessOrder.Enabled = false;
textBoxCourse.Text = string.Empty;
textBoxCompany.Text = string.Empty;
textBoxContact.Text = string.Empty;
MessageBox.Show(string.Format("订单[{0}]处理成功", labelId.Label), "订单管理", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
/// <summary>
/// 选中消息列表某一行(订单)执行事件(查看订单详情)
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
LabelIdMapping labelId = listBox1.SelectedItem as LabelIdMapping;
if (labelId == null)
return;
orderQueue.MessageReadPropertyFilter.Priority = true;
var message = orderQueue.PeekById(labelId.Id);
CourseOrder order = message.Body as CourseOrder;
if (order != null)
{
textBoxCourse.Text = order.Course.Title;
textBoxCompany.Text = order.Customer.Company;
textBoxContact.Text = order.Customer.Contact;
btnProcessOrder.Enabled = true; if (message.Priority > MessagePriority.Normal)
{
labelPriority.Text = "高优先级";
}
else
{
labelPriority.Text = "--";
}
}
else
{
MessageBox.Show("当前选中的不是课程订单", "订单管理", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
}
3、效果
以上就是今天实现的全部代码,主要实现了消息的发送和消息的接收,代码写了注释。有不足的地方,上一篇写到消息有几种类型,其中有两种“确认消息”和“响应消息”还没有演示,后面再写一篇应用“确认消息”和“响应消息”。
消息队列第二篇:MessageQueue实战(课程订单)的更多相关文章
- Java中常用的七个阻塞队列第二篇DelayQueue源码介绍
Java中常用的七个阻塞队列第二篇DelayQueue源码介绍 通过前面两篇文章,我们对队列有了了解及已经认识了常用阻塞队列中的三个了.本篇我们继续介绍剩下的几个队列. 本文主要内容:通过源码学习De ...
- 消息队列第一篇:MessageQueue介绍
消息队列有哪些好处或功能: 1.消息可以在断开连接的环境下发送.不需要同时运行正在发送和正在接收的应用程序. 2.使用快捷模式,消息可以非常快地发送.在快捷模式下,消息存储在内存中. 3.对于可恢复的 ...
- RabbitMQ消息队列入门篇(环境配置+Java实例+基础概念)
一.消息队列使用场景或者其好处 消息队列一般是在项目中,将一些无需即时返回且耗时的操作提取出来,进行了异步处理,而这种异步处理的方式大大的节省了服务器的请求响应时间,从而提高了系统的吞吐量. 在项目启 ...
- 消息队列-一篇读懂rabbitmq(生命周期,confirm模式,延迟队列,集群)
什么是消息队列? 就是生产者生产一条消息,发送到这个rabbitmq,消费者连接rabbitmq并且进行消费,生产者和消费者并需要知道对方是如何工作的,从而实现程序之间的解耦,异步和削峰,这也就是消息 ...
- 鸿蒙内核源码分析(消息队列篇) | 进程间如何异步传递大数据 | 百篇博客分析OpenHarmony源码 | v33.02
百篇博客系列篇.本篇为: v33.xx 鸿蒙内核源码分析(消息队列篇) | 进程间如何异步传递大数据 | 51.c.h .o 进程通讯相关篇为: v26.xx 鸿蒙内核源码分析(自旋锁篇) | 自旋锁 ...
- 线程安全使用(四) [.NET] 简单接入微信公众号开发:实现自动回复 [C#]C#中字符串的操作 自行实现比dotcore/dotnet更方便更高性能的对象二进制序列化 自已动手做高性能消息队列 自行实现高性能MVC WebAPI 面试题随笔 字符串反转
线程安全使用(四) 这是时隔多年第四篇,主要是因为身在东软受内网限制,好多文章就只好发到东软内部网站,懒的发到外面,现在一点点把在东软写的文章给转移出来. 这里主要讲解下CancellationT ...
- ASP.NET Core消息队列RabbitMQ基础入门实战演练
一.课程介绍 人生苦短,我用.NET Core!消息队列RabbitMQ大家相比都不陌生,本次分享课程阿笨将给大家分享一下在一般项目中99%都会用到的消息队列MQ的一个实战业务运用场景.本次分享课程不 ...
- 跟我一起学WCF(1)——MSMQ消息队列
一.引言 Windows Communication Foundation(WCF)是Microsoft为构建面向服务的应用程序而提供的统一编程模型,该服务模型提供了支持松散耦合和版本管理的序列化功能 ...
- 【MQ】消息队列及常见MQ比较
一.什么是消息队列 我们可以把消息队列比作是一个存放消息的容器,当我们需要使用消息的时候可以取出消息供自己使用.消息队列是分布式系统中重要的组件,使用消息队列主要是为了通过异步处理提高系统性能和削峰. ...
随机推荐
- 浅析 golang interface 实现原理
interface 在 golang 中是一个非常重要的特性.它相对于其它语言有很多优势: duck typing.大多数的静态语言需要显示的声明类型的继承关系.而 golang 通过 interfa ...
- mybatis第二天_拓展——与spring整合以及逆向工程
一.整合思路 1.SqlSessionFactory对象应该放到spring容器中作为单例存在. 2.传统dao的开发方式中,应该从spring容器中获得sqlsession对象. 3.Mapper代 ...
- java rmi 入门实例
java rmi 入门实例 (2009-06-16 16:07:55) 转载▼ 标签: java rmi 杂谈 分类: java-基础 java rmi即java远程接口调用,实现了2台虚拟机之 ...
- Nginx+iptables屏蔽访问Web页面过于频繁的IP(防DDOS,恶意访问,采集器)
通过分析nginx的日志来过滤出访问过于频繁的IP地址,然后添加到nginx的blockip.conf,并重启nginx 脚本如下: #!/bin/shnginx_home = /Data/app_1 ...
- mypwd的实现——20155328
mypwd的实现 分析 pwd不带参数时,实现的是查看并打印当前所在位置的绝对路径功能. 如图: 所以实现mypwd时重点在于循环打印路径名,循环的终止条件是是到了根目录.判定是否到达根目录的标准为: ...
- 几种交叉验证(cross validation)方式的比较
模型评价的目的:通过模型评价,我们知道当前训练模型的好坏,泛化能力如何?从而知道是否可以应用在解决问题上,如果不行,那又是哪里出了问题? train_test_split 在分类问题中,我们通常通过对 ...
- JavaScript之字符串的常用操作函数
字符串的操作在js中非常繁琐,但也非常重要.在使用过程中,也会经常忘记,今天就对这个进行一下整理. String 对象 String 对象用于处理文本(字符串). new String(s); // ...
- 1、算法介绍,lowB三人组,快速排序
1.什么是算法 2.递归 # 一直递归,递归完成再打印 def func4(x): if x > 0: func4(x - 1) print(x) func4(5) 3.时间 复杂度 (1)引入 ...
- CF 348 D. Turtles
D. Turtles 链接 题意: 给定一个N*M的棋盘,有些格子不能走,问有多少种从(1,1)到(N,M)的两条不相交路径. 分析: lGV定理. 定理:点集A={a1,a2,…an}A={a1,a ...
- spring cloud网关通过Zuul RateLimit 限流配置
目录 引入依赖 配置信息 RateLimit源码简单分析 RateLimit详细的配置信息解读 在平常项目中为了防止一些没有token访问的API被大量无限的调用,需要对一些服务进行API限流.就好比 ...