VS2019中新建控制台应用程序RabbitMQDemo【.net framework 4.6.1】,右键项目RabbitMQDemo,
一、管理NuGet程序包,输入关键字【RabbitMQ.Client】
注意,还需依赖【System.Memory.dll和System.Threading.Chanels.dll】点击安装
安装成功后,相关引用的dll就到package包下
应用程序将自动添加引用
RabbitMQ.Client以及相关应用
添加对Newtonsoft.Json.dll的引用,用于实体类T与json字符串之间的转换。
二、添加测试类Inbound_Check,代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RabbitMQDemo
{
/// <summary>
/// 进站校验
/// </summary>
public class Inbound_Check
{
/// <summary>
/// 工作中心任务ID
/// </summary>
public string taskId { get; set; }
/// <summary>
/// 工作中心编号
/// </summary>
public string workcenterNumber { get; set; }
/// <summary>
/// 托盘号
/// </summary>
public string containerNumber { get; set; }
/// <summary>
/// 条码
/// </summary>
public List<string> productSNList { get; set; }
/// <summary>
/// 设备编号
/// </summary>
public string deviceNumber { get; set; }
}
}
三、测试RabbitMQ代码如下:
using Newtonsoft.Json;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace RabbitMQDemo
{
class Program
{
/// <summary>
/// 从服务器获取的反馈消息,当服务器发送反馈消息时,将消息放入该缓冲区
/// </summary>
static string MessageBuffer = string.Empty;
static void Main(string[] args)
{
IConnection conn = CreateConnection();
try
{
string sendJson = "";
IModel sendChannel = CreateSendChannel(conn);
IModel receiveChannel = CreateReceiveChannel(conn);
for (int i = 0; i < 10; i++)
{
List<string> checkSNList = new List<string>();
checkSNList.Add("ABCD" + new Random(Guid.NewGuid().GetHashCode()).Next(1, 1000));
checkSNList.Add("XY" + DateTime.Now.ToString("yyyyMMddHHmmss"));
Inbound_Check materia = new Inbound_Check//获取taskid,获取mess工作信息
{
taskId = "1648873243570266113",
deviceNumber = "SZACSHJ",
workcenterNumber = "SZACSHJ",
productSNList = checkSNList,
containerNumber = "",
};
sendJson = JsonConvert.SerializeObject(materia);//把获取的工单信息转为json格式
Console.WriteLine(sendJson);
SendCommand(sendChannel, sendJson);
Thread.Sleep(4000);
}
bool result = SendCommandAndWaitFeedback(sendChannel, sendJson, 6000);
Console.WriteLine($"发送命令并等待反馈的结果:【{result}】");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.ReadLine();
}
/// <summary>
/// 创建连接
/// </summary>
/// <returns></returns>
public static IConnection CreateConnection()
{
ConnectionFactory factory = new ConnectionFactory()
{
HostName = "192.168.1.100",
UserName = "SZACSHJ",
Password = "jzsdSZACSHJ",
Port = 5672,
VirtualHost = "/"
};
try
{
//连接服务器
IConnection conn = factory.CreateConnection();
return conn;
}
catch (Exception ex)
{
///连接服务器失败防呆
Console.WriteLine($"连接RabbitMQ服务器【{factory.HostName}:{factory.Port}】失败!{ex.Message},\r\n{ex.StackTrace}");
return null;
}
}
/// <summary>
/// 创建发送通道
/// </summary>
/// <param name="conn"></param>
/// <returns></returns>
public static IModel CreateSendChannel(IConnection conn)
{
if (conn == null)
{
return null;
}
string exchangeName = "EX_SZACSHJ";
string queueName = "SZACSHJ_Inbound_check";
//创建通道
IModel channel = conn.CreateModel();
//direct:默认,根据routingKey完全匹配,好处是先匹配再发送
//topic:根据绑定关键字通配符规则匹配、比较灵活
//Fanout:不需要指定routingkey,相当于群发
//header:不太常用,可以自定义匹配规则
//开启发布者确认
channel.ConfirmSelect();
//声明交换机
channel.ExchangeDeclare(exchangeName, ExchangeType.Topic, durable: true, autoDelete: false, arguments: null);
//声明队列
channel.QueueDeclare(queueName, durable: true, autoDelete: false, exclusive: false, arguments: null);
//队列绑定交换机
channel.QueueBind(queueName, exchangeName, routingKey: queueName);
return channel;
}
/// <summary>
/// 创建接收通道
/// </summary>
/// <param name="conn"></param>
/// <returns></returns>
public static IModel CreateReceiveChannel(IConnection conn)
{
MessageBuffer = string.Empty;
if (conn == null)
{
return null;
}
string feedbackQueueName = "SZACSHJ_Inbound_check_Feedback";
//创建通道
IModel channel = conn.CreateModel();
//声明反馈队列
channel.QueueDeclare(feedbackQueueName, durable: true, autoDelete: false, exclusive: false, arguments: null);
//字节限制,一次接收的消息数
channel.BasicQos(prefetchSize: 0, prefetchCount: 1, false);
//声明消费者
EventingBasicConsumer consumer = new EventingBasicConsumer(channel);
//接收消息事件:当服务器反馈结果时,会自动触发Received事件
consumer.Received += (model, ea) =>
{
string msg = Encoding.UTF8.GetString(ea.Body.ToArray());
MessageBuffer = msg;
Console.WriteLine(msg);
};
//是否开启自动确认
channel.BasicConsume(queue: feedbackQueueName, autoAck: true, consumer: consumer);
//线程休眠用于接收消息,首次连接只是注册接收事件,并未接收消息
return channel;
}
/// <summary>
/// 发送命令
/// </summary>
/// <param name="channel"></param>
/// <param name="sendJson"></param>
public static void SendCommand(IModel channel, string sendJson)
{
if (channel == null)
{
return;
}
string exchangeName = "EX_SZACSHJ";
string queueName = "SZACSHJ_Inbound_check";
//设置消息是否持久化,防止服务器重启后消息还未保存造成丢失
IBasicProperties props = channel.CreateBasicProperties();
props.Persistent = true;
//将发布的消息转换成字节数组
byte[] msgBody = Encoding.UTF8.GetBytes(sendJson);
channel.BasicPublish(exchange: exchangeName, routingKey: queueName, basicProperties: props, body: msgBody);
//可以发送一批消息后,调用该方法;也可以每发一条调用一次。发布失败立刻选择重新发布
if (!channel.WaitForConfirms())
{
Console.WriteLine("发布消息未确认");
for (int i = 0; i < 3; i++)
{
channel.BasicPublish(exchange: exchangeName, routingKey: queueName, basicProperties: props, body: msgBody);
if (channel.WaitForConfirms())
{
break;
}
}
}
else
{
Console.WriteLine("发布消息已确认");
}
}
/// <summary>
/// 发送命令并等待反馈信息
/// </summary>
/// <param name="channel"></param>
/// <param name="sendJson"></param>
/// <param name="timeout">超时毫秒数,-1为无限等待</param>
/// <returns></returns>
public static bool SendCommandAndWaitFeedback(IModel channel, string sendJson, int timeout)
{
SendCommand(channel, sendJson);
SpinWait.SpinUntil(() => MessageBuffer.Length > 0, timeout);
return MessageBuffer.Length > 0;
}
}
}