如何在一个RabbitMQ队列中区分两个JSON对象

本文关键字:两个 对象 JSON 中区 一个 RabbitMQ 队列 | 更新日期: 2023-09-27 17:57:36

我希望能够在一个队列上发送两个不同的JSON消息。在C#中,我如何确定接收到的消息类型,以便将消息反序列化为正确的对象?我应该使用消息头还是创建另一个队列?每个消息类型的队列对我来说似乎太多了。谢谢!

额外详细信息:我有一个处理"运行"的Windows服务。运行ID由另一个系统分配,并将该ID丢弃在队列中。我的服务人员拿起ID开始工作。每个管路都会创建一个对象。现在,如果我想取消工作,我必须停止服务。但是,这就停止了所有的工作。我想添加一个CancelRun类型的方法,但我需要的只是运行ID。所以,我可以使用完全相同的JSON(所以是相同的类)。两个队列并不可怕,但我认为将类型或其他内容添加到自定义标头中可能会很聪明。

如何在一个RabbitMQ队列中区分两个JSON对象

以下是我所做的。我喜欢这种技术,因为我不会向JSON中添加不属于模型的内容。

IBasicProperties props = model.CreateBasicProperties();
props.Headers = new Dictionary<string, object>();
props.Headers.Add("RequestType", "CancelRunRequest");

然后,在接收端,我这样做(我用自定义EventArg-obj引发一个事件):

// Raise message received event
var args = new MessageReceivedArgs();
args.CorrelationId = response.BasicProperties.CorrelationId;
args.Message = Encoding.UTF8.GetString(response.Body);
args.Exchange = response.Exchange;
args.RoutingKey = response.RoutingKey;
if (response.BasicProperties.Headers != null && response.BasicProperties.Headers.ContainsKey("RequestType"))
{
args.RequestType = Encoding.UTF8.GetString((byte[])response.BasicProperties.Headers["RequestType"]);
}
MessageReceived(this, args);
model.BasicAck(response.DeliveryTag, false);

项目其他部分:

private void NewRunIdReceived(object p, MessageReceivedArgs e)
{
if(e.RequestType.ToUpper() == "CANCELRUNREQUEST")
{
    // This is a cancellation request
    CancelRun(e);
}
else
{
    // Default to startrun request for backwards compatibility.
    StartRun(e);
}
}

如果订单或接收和处理这些消息不是问题,我建议对每种类型使用单独的队列,那么rabbit处理大量队列也不是问题。若并没有,那个么订单对你们来说是至关重要的,你们可以在消息的头部放置标记来定义它的类型,但这将把你们的业务逻辑和传输层绑定起来。如果您稍后想在应用程序中更改传输层,则必须采用这部分代码才能使其正常工作。相反,您可以为这两种对象类型制作某种包装器,它隐藏内部内容,看起来相同,并且可以在所包含的类型中淡化自己。

按照sphair的建议添加运行时类型信息是有效的,但我不喜欢这样做,因为您失去了弱类型的可移植性值。您还可以考虑让反序列化的C#对象具有足够的通用性,以处理所有的风格,然后从那里进行分支。

您可以将它们全部添加到数组中,然后根据类型取消序列化,您必须手动添加类型属性,或者您可以创建Object IHaveType,然后在正在使用的对象中从中继承,但这是一种可怕的方法。

ObjectType1 : HaveType 
public class HaveType { public string Type { get { this.GetType(); }}}

Json

[{Type: 'ObjectType1', ...[other object stuff]},{Type : 'ObjectType2',...}]

JSON不会说明它是从什么类型序列化的,除非序列化程序本身向JSON添加了一些信息。

您可以在JSON中添加一些结构,以便能够推断类型。