我想实现从 ASP.NET 应用程序到 WCF 服务(托管在 Windows 服务中)的单向、即发即弃的调用。这是服务端的一个长时间运行的操作(否则我只会在 ASP.NET 应用程序中执行此操作),因此客户端(通道)在操作完成之前不应保持打开状态。
无论这看起来多么微不足道,我一直在寻找一个优雅的解决方案几个小时,却找不到任何我喜欢的东西。有几个关于它的问题和博客文章,似乎有两种可能的解决方案:
我宁愿不使用消息队列,在服务器环境中安装这些开销太大。
剩下的就是添加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>