Односторонний вызов WCF с использованием netTcpBinding: добавьте OneWayBindingElement через конфигурацию
Я хочу реализовать однонаправленный вызов "забей и забудь" из приложения ASP.NET в службу WCF (размещенную в службе Windows). Это длительная операция на стороне службы (в противном случае я бы просто сделал это внутри приложения ASP.NET), поэтому клиент (канал) не должен оставаться открытым до завершения действия.
Каким бы банальным ни был этот сценарий, я искал изящное решение в течение нескольких часов и не могу найти что-нибудь по своему вкусу. Об этом есть пара вопросов SO и сообщения в блоге, и, кажется, есть два возможных решения:
- Используйте очередь сообщений в качестве коммуникационного уровня, как предлагается здесь.
- использование
OneWayBindingElement
, как предлагается здесь.
Я бы предпочел не использовать очереди сообщений, их установка в серверной среде - это слишком много.
Это оставляет добавление OneWayBindingElement
, Но все примеры, которые я нашел, делают это в коде, что я бы предпочел не делать, потому что это исключает использование Visual Studio WcfSvcHost. Можно ли расширить мой netTcpBinding с этим печально известным OneWayBindingElement
через конфигурацию?
Для полноты, вот ключевые части в моем коде:
Сервис Интерфейс
[ServiceContract]
public interface ICalculationService
{
[OperationContract(IsOneWay = true)]
void StartTask(TaskType type);
[OperationContract(IsOneWay = true)]
void AbortTask(TaskType type);
}
Внедрение сервиса
[ServiceBehavior(
ConcurrencyMode = ConcurrencyMode.Multiple,
InstanceContextMode = InstanceContextMode.PerCall)]
public class CalculationService : ICalculationService
{
// ...
public void StartTask(TaskType type)
{
// ...
}
}
Код клиента, внутри контроллера
public class SourcesController
{
[HttpPost]
public ActionResult Upload(UploadFilesVM files)
{
// ...
using(var svcClient = GetSvcClientInstance())
{
svcClient.StartTask(TaskType.RefreshInspectionLotData);
svcClient.StartTask(TaskType.RefreshManugisticsData);
}
// ...
return RedirectToAction("Progress");
}
private CalculationServiceClient GetSvcClientInstance()
{
var client = new CalculationServiceClient();
client.Endpoint.Behaviors.Add(new SatBehavior(Context));
client.Open();
return client;
}
}
Сервисная конфигурация
<services>
<service name="...CalculationService">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8732/PLU0006B/"/>
<add baseAddress="net.tcp://localhost:8733/PLU0006B/"/>
</baseAddresses>
</host>
<endpoint
address="CalculationService"
binding="netTcpBinding"
bindingConfiguration="SatOneWayBinding"
contract="....ICalculationService" />
<endpoint
address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange"/>
</service>
</services>
<bindings>
<netTcpBinding>
<binding name="SatOneWayBinding">
<!-- I'm hoping I can configure 'OneWayBindingElement' here ? -->
<security mode="None">
</security>
</binding>
</netTcpBinding>
</bindings>