Как устранить ошибку преобразования имени при отправке сообщений MSMQ
Недавно я следил за этой статьей о том, как настроить трехстороннюю систему массового обслуживания с MSMQ, в которой издатель, сервер очереди и подписчик находятся в отдельных системах в домене Active Directory. Мне удалось завершить часть 1 и первую половину части 2. Однако, когда я продолжаю вторую половину части 2 и включаю безопасность транспорта, я получаю следующую ошибку: An error occurred when converting the 'mymsmqservermachine.mydomain.network.ads\private$\Path/To/MyQueuedService.svc' queue path name to the format name: Unrecognized error -1072824300 (0xc00e0014). All operations on the queued channel failed. Ensure that the queue address is valid. MSMQ must be installed with Active Directory integration enabled and access to it is available.
Я подтвердил следующее:
- Интеграция Active Directory для MSMQ включена на всех машинах в сторонней системе, согласно этому сообщению Stackru.
- URL-адрес очереди остается точно таким же, каким он был до включения защиты, которая работала просто отлично, без ошибок анализа.
- Я следую инструкциям Windows при установке MSMQ здесь.
Соответствующие части трассировки стека, которые я получаю:
at System.ServiceModel.Channels.MsmqFormatName.FromQueuePath(String queuePath)
at System.ServiceModel.Channels.MsmqUri.ActiveDirectory.UriToFormatName(Uri uri)
at System.ServiceModel.Channels.MsmqOutputChannel.OpenQueue()
--- End of inner exception stack trace ---
Server stack trace:
at System.ServiceModel.Channels.MsmqOutputChannel.OpenQueue()
at System.ServiceModel.Channels.MsmqOutputChannel.OnOpenCore(TimeSpan timeout)
at System.ServiceModel.Channels.MsmqOutputChannel.OnBeginOpen(TimeSpan timeout, AsyncCallback callback, Object state)
at System.ServiceModel.Channels.CommunicationObject.OpenAsyncResult.InvokeOpen()
at System.ServiceModel.Channels.CommunicationObject.OpenAsyncResult..ctor(CommunicationObject communicationObject, TimeSpan timeout, AsyncCallback callback, Object state)
at System.ServiceModel.Channels.CommunicationObject.BeginOpen(TimeSpan timeout, AsyncCallback callback, Object state)
at System.ServiceModel.Channels.ServiceChannel.OnBeginOpen(TimeSpan timeout, AsyncCallback callback, Object state)
at System.ServiceModel.Channels.CommunicationObject.OpenAsyncResult.InvokeOpen()
at System.ServiceModel.Channels.CommunicationObject.OpenAsyncResult..ctor(CommunicationObject communicationObject, TimeSpan timeout, AsyncCallback callback, Object state)
at System.ServiceModel.Channels.CommunicationObject.BeginOpen(TimeSpan timeout, AsyncCallback callback, Object state)
at System.ServiceModel.Channels.ServiceChannel.CallOpenOnce.System.ServiceModel.Channels.ServiceChannel.ICallOnce.BeginCall(ServiceChannel channel, TimeSpan timeout, AsyncCallback callback, Object state)
at System.ServiceModel.Channels.ServiceChannel.CallOnceManager.BeginCallOnce(TimeSpan timeout, CallOnceManager cascade, AsyncCallback callback, Object state)
at System.ServiceModel.Channels.ServiceChannel.BeginEnsureOpened(TimeSpan timeout, AsyncCallback callback, Object state)
at System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.StartEnsureOpen(Boolean completedSynchronously)
at System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.FinishEnsureInteractiveInit(IAsyncResult result, Boolean completedSynchronously)
at System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.StartEnsureInteractiveInit()
at System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.Begin()
at System.ServiceModel.Channels.ServiceChannel.BeginCall(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, TimeSpan timeout, AsyncCallback callback, Object asyncState)
at System.ServiceModel.Channels.ServiceChannel.BeginCall(ServiceChannel channel, ProxyOperationRuntime operation, Object[] ins, AsyncCallback callback, Object asyncState)
at System.Threading.Tasks.TaskFactory`1.FromAsyncImpl[TArg1,TArg2,TArg3](Func`6 beginMethod, Func`2 endFunction, Action`1 endAction, TArg1 arg1, TArg2 arg2, TArg3 arg3, Object state, TaskCreationOptions creationOptions)
at System.ServiceModel.Channels.ServiceChannelProxy.TaskCreator.CreateTask(ServiceChannel channel, ProxyOperationRuntime operation, Object[] inputParameters)
at System.ServiceModel.Channels.ServiceChannelProxy.TaskCreator.CreateTask(ServiceChannel channel, IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
Исходя из содержимого трассировки стека, кажется, что сбой происходит из-за разрешения имени очереди в Active Directory. Я попытался следующее, чтобы попытаться устранить такую ошибку:
- Упрощение имени, не содержащее точек и косых черт (не работает)
- Использование общедоступной очереди вместо частной, если этот шаг был пропущен в исходном учебнике по MSDN (это не было, не работало)
На данный момент у меня нет идей. Кто-нибудь сталкивался с этой ошибкой при использовании WCF с привязками net.msmq и решал их проблему?
РЕДАКТИРОВАТЬ: при запуске следующего тестового кода с того же компьютера и того же пользователя, я могу отправить сообщение в очередь совершенно нормально:
Me.TestContext.WriteLine("Executing under user '{0}'", WindowsIdentity.GetCurrent().Name)
Dim msg = New System.Messaging.Message()
msg.Body = "This is a test message"
msg.Label = "Test Message"
msg.Formatter = new ActiveXMessageFormatter()
Dim queue = new MessageQueue("FormatName:DIRECT=OS:mymsmqservermachine.mydomain.network.ads\private$\Path/To/MyQueuedService.svc")
queue.Send(msg)
1 ответ
По чистой случайности я наткнулся на решение и записал его в своем блоге.
Суть решения заключалась в том, что мне пришлось добавить DNS-идентификатор для моей привязки конечной точки WCF в моем клиенте:
Dim endpointAddress = New EndpointAddress(queueUri, EndpointIdentity.CreateDnsIdentity(queueUri.Host))
Dim netMsmqBinding = New NetMsmqBinding With
{
.Durable = true,
.ExactlyOnce = false,
.UseActiveDirectory = false,
.Security = New NetMsmqSecurity With
{
.Mode = NetMsmqSecurityMode.Transport
}
}
Return New ChannelFactory(Of ICwteCentralPublishingServiceChannel)(netMsmqBinding, endpointAddress)
Я извиняюсь перед миром за код Visual Basic, это устаревшее приложение и не был мой выбор.