Исключение WCF при чтении из очереди msmq
У меня есть следующая проблема:
У меня есть проект silveright 5 и проект wcf (iis/ hosted) (.net 4).
Проект wcf содержит несколько служб с привязкой basicHttpBinding и одну службу с привязкой netMsmqBinding.
Существует один сценарий использования этого приложения, в котором пользователь может генерировать несколько экспортов в формате Excel до 30 файлов на пользователя и до 10 пользователей. Это длительная операция, до 3 минут на файл.
Сначала служба экспорта была httpBinded, и с запросом на создание более 15 отчетов она не сработала. Так что я увеличил время ожидания. Это явно не было правильным решением проблемы.
Поэтому я решил использовать очередь и изменил привязку для служб экспорта с basicHttpBinding на netMsmqBinding.
Рабочий процесс следующий:
Клиент Silverlight отправляет запрос для каждого файла следующему методу в ReportsService:
[SecurityTokenValidation]
[ErrorLogging]
public string GenerateTablesReport(List<MeasurementDescription> measurements)
{
if (measurements == null || measurements.Count.Equals(0))
{
throw new FaultException("Invalid argument.", new FaultCode(ErrorCodes.InvalidArgumentException));
}
//put on queue from here
ExportsServiceClient exportsServiceClient = new ExportsServiceClient();
exportsServiceClient.GenerateTablesReport(measurements.ToArray());
return new Guid().ToString();
}
В указанном выше способе я отправляю сообщение, помещая его в очередь. Я создал частную транзакционную очередь с именем ExportsService с необходимыми правами безопасности.
Пока это работает. Я вижу сообщения в очереди.
Проблема в том, что ExportsService не удается при попытке прочитать сообщения, и все они оказываются в папке "retry".
Я перепробовал все за последние два дня. Я попытался с некоторыми простыми игрушечными проектами просто проверить, работает ли на компьютере что-то вроде msmq.
В svclog я нашел это исключение. в System.ServiceModel.Channels.MsmqBindingMonitor.OnTimer(состояние объекта)System.Messaging.MessageQueueException (0x80004005): удаленный компьютер недоступен. в System.Messaging.MessageQueue.GetPrivateQueuesByMachine(String machineName)
ExportsService выглядит так:
public class ExportsService : IExportsService
{
[OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
[SecurityTokenValidation]
[ErrorLogging]
public void GenerateTablesReport(List<MeasurementDescription> measurements)
{
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
{
if (measurements == null || measurements.Count.Equals(0))
{
throw new FaultException("Invalid argument.", new FaultCode(ErrorCodes.InvalidArgumentException));
}
BusinessFactory.ReportsManager.GenerateTablesReport(measurements);
scope.Complete();
}
}
}
Интересные биты в веб-конфигурации выглядят так:
<client>
<endpoint address="net.msmq://localhost/private/ExportsService"
binding="netMsmqBinding" bindingConfiguration="NetMsmqBinding_IExportsService"
contract="WCF.ExportsService.IExportsService" name="NetMsmqBinding_IExportsService" />
</client>
<behaviors>
<endpointBehaviors>
<behavior name="BatchingBehavior">
<transactedBatching maxBatchSize="16"/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="foobar">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<dataContractSerializer maxItemsInObjectGraph="2147483647" />
<serviceThrottling maxConcurrentCalls="60" maxConcurrentInstances="60" maxConcurrentSessions="60" />
</behavior>
<behavior name="ThrottlingBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceThrottling maxConcurrentCalls="4"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
<bindings>
<basicHttpBinding>
<binding name="defaultBasicHttpBinding" closeTimeout="00:10:00"
openTimeout="00:10:00" sendTimeout="00:10:00" maxBufferSize="2147483647"
maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
maxArrayLength="2147483647" maxBytesPerRead="2147483647" />
</binding>
</basicHttpBinding>
<netMsmqBinding>
<binding name="defaultNetMsmqBinding">
<security mode="None" />
</binding>
<binding name="NetMsmqBinding_IExportsService">
<security mode="None" />
</binding>
</netMsmqBinding>
</bindings>
<services>
<service behaviorConfiguration="ThrottlingBehavior" name="FLM.Web.Services.ExportsService">
<endpoint address="net.msmq://localhost/private/ExportsService" binding="netMsmqBinding" bindingConfiguration="defaultNetMsmqBinding" behaviorConfiguration="BatchingBehavior" contract="FLM.Web.Services.IExportsService"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
<service behaviorConfiguration="foobar" name="FLM.Web.Services.ReportsService">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="defaultBasicHttpBinding" contract="FLM.Web.Services.IReportsService" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
<service behaviorConfiguration="foobar" name="FLM.Web.Services.SecurityService">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="defaultBasicHttpBinding" contract="FLM.Web.Services.ISecurityService" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
<service behaviorConfiguration="foobar" name="FLM.Web.Services.OrderingService">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="defaultBasicHttpBinding" contract="FLM.Web.Services.IOrderingService" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
<service behaviorConfiguration="foobar" name="FLM.Web.Services.ReportConfigurationService">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="defaultBasicHttpBinding" contract="FLM.Web.Services.IReportConfigurationService" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
<service behaviorConfiguration="foobar" name="FLM.Web.Services.AdminService">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="defaultBasicHttpBinding" contract="FLM.Web.Services.IAdminService" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>