我正在使用NServiceBus 4.4.2,我创建了一个实现IAuthorizeSubscriptions
的类,以接受/拒绝订阅。我需要在发布者中提供有关订阅者的一些其他信息,因此我尝试创建一个实现IMutateOutgoingTransportMessages
的类,并使用ConfigureComponent<MyMutator>(DependencyLifecycle.InstancePerCall)
以正常方式注册它。所有这个类都是为传出消息添加标题。
不幸的是,订阅者发送订阅控制消息时未设置标头。我已经检查过,如果订阅者做了一个Bus.Send(),我的自定义标题 被附加到传输消息的Headers集合中,所以我不认为这是我的mutator的问题,除非我需要以不同方式注册。
有没有办法将标题添加到订阅消息中,或者我是否采用了错误的方式并且应该通过其他方式传递信息?
修改
Mutator Code:
public class MyMutator : IMutateOutgoingTransportMessages
{
public void MutateOutgoing(object[] messages, TransportMessage transportMessage)
{
transportMessage.Headers.Add("CustomHeader", "Test");
}
}
IAuthorizeSubscriptions代码:
我可以在AuthorizeSubscribe
方法中设置一个断点,但它会被点击,但headers
不包含我的自定义标题。
public class SubscriptionAuthoriser : IAuthorizeSubscriptions
{
public bool AuthorizeSubscribe(string messageType, string clientEndpoint, IDictionary<string, string> headers)
{
// headers doesn't contain the "CustomHeader" header
return true;
}
public bool AuthorizeUnsubscribe(string messageType, string clientEndpoint, IDictionary<string, string> headers)
{
return true;
}
}
答案 0 :(得分:0)
从NServiceBus版本4.3开始,不再调用传出订阅消息调用InvokeOutgoingTransportMessagesMutators,因此消息标题不再可能出现这种情况。我问了一段类似的问题@ https://groups.google.com/forum/#!topic/particularsoftware/XVLQkCouKCk。当我在等待上述线程的响应时,我实现了一个临时解决方法,这是一种手动订阅方法(主要使用NServiceBus单播总线源构建)。这可能不是推荐的,但我想我会发布它,无论如何它会帮助某人。
public void Subscribe(Type eventType, Address targetAddress)
{
var transportMessage = new TransportMessage
{
ReplyToAddress = Address.PublicReturnAddress,
Recoverable = true
};
transportMessage.Headers.Add("NServiceBus.ControlMessage", true.ToString());
transportMessage.Headers["SubscriptionMessageType"] = eventType.AssemblyQualifiedName;
transportMessage.MessageIntent = MessageIntentEnum.Subscribe;
var fdqn = OutgoingTransportMessageMutator.GetLocalhostFqdn();
transportMessage.ReplyToAddress = new Address(transportMessage.ReplyToAddress.Queue, fdqn);
string fullPath = MsmqUtilities.GetFullPath(targetAddress);
try
{
using (var messageQueue = new MessageQueue(fullPath, false, false, QueueAccessMode.Send))
{
using (var message1 = MsmqUtilities.Convert(transportMessage))
{
message1.UseDeadLetterQueue = false;
message1.UseJournalQueue = false;
message1.ResponseQueue = new MessageQueue(MsmqUtilities.GetReturnAddress(transportMessage.ReplyToAddress.ToString(), targetAddress.ToString()));
messageQueue.Send(message1, MessageQueueTransactionType.Single);
}
}
}
catch (MessageQueueException ex)
{
if (ex.MessageQueueErrorCode == MessageQueueErrorCode.QueueNotFound)
{
string message1 = targetAddress == (Address)null ? "Failed to send message. Target address is null." : string.Format("Failed to send message to address: [{0}]", targetAddress);
throw new QueueNotFoundException(targetAddress, message1, ex);
}
throw;
}
catch (Exception ex)
{
_log.Error(ex);
throw;
}
}