0

我想实现从 ASP.NET 应用程序到 WCF 服务(托管在 Windows 服务中)的单向、即发即弃的调用。这是服务端的一个长时间运行的操作(否则我只会在 ASP.NET 应用程序中执行此操作),因此客户端(通道)在操作完成之前不应保持打开状态

无论这看起来多么微不足道,我一直在寻找一个优雅的解决方案几个小时,却找不到任何我喜欢的东西。有几个关于它的问题和博客文章,似乎有两种可能的解决方案:

  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>
4

0 回答 0