我想实现从ASP.NET应用程序到WCF服务(托管在Windows服务中)的单向,即发即忘的调用。它是服务端的长期运行(否则我只是在ASP.NET应用程序中执行),因此客户端(通道)应该不保持打开状态,直到操作完成。
无论这种情况看起来多么微不足道,我几个小时都在寻找一个优雅的解决方案,并且无法找到我喜欢的任何东西。关于它有几个SO问题和博客文章,似乎有两种可能的解决方案:
OneWayBindingElement
。我宁愿不使用Message Queues,在服务器环境中安装这些也是太多开销。
即添加OneWayBindingElement
。但是我发现的所有示例都是在代码中执行此操作,我宁愿不这样做,因为这会使用Visual Studio WcfSvcHost进行排除。是否可以使用这个臭名昭着的OneWayBindingElement
通过配置扩展我的netTcpBinding?
为了完整起见,以下是我的代码中的关键部分:
服务互动
[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>