Односторонний вызов WCF с использованием netTcpBinding: добавьте OneWayBindingElement через конфигурацию

Я хочу реализовать однонаправленный вызов "забей и забудь" из приложения ASP.NET в службу WCF (размещенную в службе Windows). Это длительная операция на стороне службы (в противном случае я бы просто сделал это внутри приложения ASP.NET), поэтому клиент (канал) не должен оставаться открытым до завершения действия.

Каким бы банальным ни был этот сценарий, я искал изящное решение в течение нескольких часов и не могу найти что-нибудь по своему вкусу. Об этом есть пара вопросов SO и сообщения в блоге, и, кажется, есть два возможных решения:

  1. Используйте очередь сообщений в качестве коммуникационного уровня, как предлагается здесь.
  2. использование 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>

0 ответов

Другие вопросы по тегам