One-way WCF call using netTcpBinding: add OneWayBindingElement through configuration

574 views Asked by At

I want to implement a one-way, fire-and-forget call from an ASP.NET application to a WCF service (hosted in a Windows Service). It's a long-running operation at the service-side (otherwise I would just do it inside the ASP.NET application) so the client (channel) should not remain open until the action completes.

However trivial a scenario this may seem, I've been searching for a graceful solution for hours and can't really find anything to my liking. There are a couple of SO questions and blog posts about it, and it seems there are two possible solutions:

  1. Use a message queue as communication layer, as suggested here.
  2. Use OneWayBindingElement, as suggested here.

I would rather not use Message Queues, installing these on the server environment is too much overhead.

That leaves adding OneWayBindingElement. But all examples I found do this in code, which I would rather not do because that rules out using the Visual Studio WcfSvcHost. Is it possible to extend my netTcpBinding with this infamous OneWayBindingElement through configuration ?

For completeness, here are the key parts in my code:

Service Interfce

[ServiceContract]
public interface ICalculationService
{
    [OperationContract(IsOneWay = true)]
    void StartTask(TaskType type);

    [OperationContract(IsOneWay = true)]
    void AbortTask(TaskType type);
}

Service Implementation

[ServiceBehavior(
    ConcurrencyMode = ConcurrencyMode.Multiple, 
    InstanceContextMode = InstanceContextMode.PerCall)]
public class CalculationService : ICalculationService
{
    // ...

    public void StartTask(TaskType type)
    {
        // ...
    }
}

Client code, inside controller

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;
    }
}

Service configuration

<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

There are 0 answers