我试图在SO上扩展这个答案,使WCF客户端在瞬态网络故障时重试,并处理需要重试的其他情况,例如身份验证到期.
题:
什么是需要处理的WCF异常,以及处理它们的正确方法是什么?
以下是一些我希望看到的示例技术,而不是proxy.abort():
由于一个人不太可能知道解决它们的所有例外或方法,因此请分享您所知道的内容.我将在下面的代码示例中汇总答案和方法.
// USAGE SAMPLE
//int newOrderId = 0; // need a value for definite assignment
//Service<IOrderService>.Use(orderService=>
//{
// newOrderId = orderService.PlaceOrder(request);
//}
/// <summary>
/// A safe WCF Proxy suitable when sessionmode=false
/// </summary>
/// <param name="codeBlock"></param>
public static void Use(UseServiceDelegateVoid<T> codeBlock)
{
IClientChannel proxy = (IClientChannel)_channelFactory.CreateChannel();
bool success = false;
try
{
codeBlock((T)proxy);
proxy.Close();
success = true;
}
catch (CommunicationObjectAbortedException e)
{
// Object …Run Code Online (Sandbox Code Playgroud) 我正在尝试构建一个SOA,客户端可以在服务器上执行长时间运行的查询,服务器使用回调进行响应.
我希望能够检测客户端是否断开连接(通过用户启动的关闭,未处理的异常或丢失网络连接),以便服务器可以选择取消昂贵的请求.
我正在测试各种故障情况,但我似乎无法启动某些事件处理程序.
经过测试的失败案例:在请求后杀死客户端进程.使用像CurrPorts这样的程序来关闭TCP连接.
测试代码:
using System;
using System.ServiceModel;
using System.Threading;
namespace WCFICommunicationObjectExperiments
{
class Program
{
static void Main(string[] args)
{
var binding = new NetTcpBinding(SecurityMode.None);
var serviceHost = new ServiceHost(typeof (Server));
serviceHost.AddServiceEndpoint(typeof (IServer), binding, "net.tcp://localhost:5000/Server");
serviceHost.Open();
Console.WriteLine("Host is running, press <ENTER> to exit.");
Console.ReadLine();
}
}
[ServiceContract(CallbackContract = typeof(IClient))]
public interface IServer
{
[OperationContract]
void StartProcessing(string Query);
}
public interface IClient
{
[OperationContract]
void RecieveResults(string Results);
}
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
public class Server : IServer
{
public void …Run Code Online (Sandbox Code Playgroud) 当我尝试设置双工模式通道时,我已将文件传输服务从basicHttpBinding移动到netTcpBinding.我还启动了net.tcp端口共享服务.
我目前在dev并且在xp框上自我托管,直到我们将应用程序移动到开发服务器.所以,就目前而言,我无法访问IIS.
在配置我的服务之后:
<service behaviorConfiguration="transferServiceBehavior" name="API.FileTransfer.FileTransferService">
<endpoint name="MyFileTransferEP"
address = ""
binding = "netTcpBinding"
bindingConfiguration="MyFileTransferNetTcpEP"
behaviorConfiguration="NetTcpEPBehavior"
contract="API.FileTransfer.IFileTransferService" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:8001/project/filetransfer.svc" />
</baseAddresses>
</host>
</service>
Run Code Online (Sandbox Code Playgroud)
而且,我的约束如下:
<netTcpBinding>
<binding name="MyFileTransferNetTcpEP"
hostNameComparisonMode="StrongWildcard"
closeTimeout="00:01:00"
openTimeout="00:01:00"
receiveTimeout="00:10:00"
sendTimeout="00:01:00"
maxReceivedMessageSize="2147483647"
transferMode="Streamed"
portSharingEnabled="true">
<security mode="None">
<transport clientCredentialType="None" />
<message clientCredentialType="None" />
</security>
</binding>
</netTcpBinding>
Run Code Online (Sandbox Code Playgroud)
当我正确浏览到SVC文件时,我得到了以下错误:
无法找到与绑定NetTcpBinding的端点匹配scheme net.tcp的基址.注册的基地址方案是[http].
在线阅读表明,为了解决这个问题,我需要将net.tcp绑定添加到IIS中应用程序的绑定.但是,如果我是自托管并且无法访问IIS,我该怎么办?顺便说一句,如果您正在阅读此内容并"执行"拥有IIS,请执行以下操作:右键单击IIS中的虚拟目录/应用程序 - >管理应用程序 - >高级设置.并且,在Enabled Protocols部分中,添加net.tcp.
有任何想法吗?
更新:我以为我有它工作,但它仍然无法正常工作.这是我现在拥有的:我仍然得到"找不到匹配scheme net.tcp的基地址"错误.我已经更改了所有基地址以反映您的建议.这就是我现在拥有的:
<service behaviorConfiguration="transferServiceBehavior" name="API.FileTransfer.FileTransferService">
<endpoint name="MyJSONFileTransferEP"
address="json"
binding="webHttpBinding"
bindingConfiguration="jsonWeb"
behaviorConfiguration="WebHttpEPBehavior"
contract="API.FileTransfer.IJSONFileTransferService" />
<endpoint name="MyPOXFileTransferEP"
address="pox"
behaviorConfiguration="WebHttpEPBehavior" …Run Code Online (Sandbox Code Playgroud) Bidirectional并且full-duplex是不同的概念.例如,Ethernet只有半双工,因为在特定时间,只有一个主机可以通过线路发送数据,并且它不能同时发送和接收数据.
因此,当我们通过以太网使用TCP时,我认为TCP只是双向或半双工.
但在这里它说TCP是全双工的.为什么?
重新获得赏金,因为我真的需要知道如何让它发挥作用,或者为什么不会这样做的明确答案.
有一段时间让双向(IsOneWay = false)WCF客户端服务器在.Net 3/3.5中工作.
在客户端成功注册该服务后,该服务的定期Announcement()将回调注册的客户端.现在,客户端或服务器挂起,直到服务器的SendTimeout(调整为2秒)过去.然后服务器端有一个超时异常,如下所示.只有这样,客户端用户代码才会立即接收METHOD CALL并尝试返回一个值.到那时,客户端的套接字被中止,WCF的内容失败.
在我看来,客户端上的某些东西正在挂起它的本地WCF队列,从处理到套接字超时,但不是很早就取消了本地方法调用.但是,如果相信下面的例外,服务器正在尝试将操作发送到http://schemas.microsoft.com/2005/12/ServiceModel/Addressing/Anonymous(不合适!)并且超时.也许该URI只是远程连接客户端的"名称",因为WCF知道为了出现错误消息而引用它,它似乎意味着它无法加载URI.我无法判断服务器是先失败还是客户端先失败.
我已经尝试添加WCF跟踪,但我没有获得更多信息.
类似的示例代码在这里,但它必须过多才能消化.我已经尝试过该代码的变种.
TimeoutException 'This request operation sent to http://schemas.microsoft.com/2005/12/ServiceModel/Addressing/Anonymous did not receive a reply within the configured timeout (00:00:00). The time allotted to this operation may have been a portion of a longer timeout. This may be because the service is still processing the operation or because the service was unable to send a reply message. Please consider increasing the operation timeout (by casting the channel/proxy to IContextChannel …Run Code Online (Sandbox Code Playgroud) 我们在WCF应用程序中使用了pub-sub模型,该模型几乎遵循Microsoft示例:设计模式:基于列表的发布 - 订阅.
虽然该服务提供了一个概念,subscribe()并且unsubscribe()在客户端死亡或通道出现故障时处理清理的最佳实践是什么?目前,当客户端订阅时,我将处理程序附加到当前InstanceContext的事件Closed和Faulted事件(服务用户的PerSession实例上下文模式和netTcpBinding):
_communicationObject = OperationContext.Current.InstanceContext;
_communicationObject.Closed += OnClientLost;
_communicationObject.Faulted += OnClientLost;
Run Code Online (Sandbox Code Playgroud)
然而,OnClientLost处理程序只是取消订阅客户端:
这个问题提出了类似的问题,但最终没有提供客户呼叫订阅和/或取消订阅之外的案例的答案
谢谢
我正在使用WCF在.Net 3.5中开发客户端/服务器应用程序.基本上,长时间运行的客户端服务(在多台计算机上)通过netTcpBinding建立到服务器的双工连接.然后,服务器使用客户端的回调契约来执行某些按需操作,客户端以异步方式响应(我认为这是相当标准的东西).我将DuplexClientBase类子类化以处理大部分通信.
不幸的是,当两端出现问题时(例如网络故障,意外异常等),通道出现故障/中止,所有后续操作都会失败.我通过创建一个RecoveringClientBase类来解决非双工通道中的这种限制,该类在客户端出现故障并重试操作时自动获取.
所以我的问题是,有没有一种既定的方法来确定双工通道何时出现故障?我应该在服务器或客户端上检查这个位置?如果做不到这一点,我有什么选择来确保连接重新建立?
更新:我正在寻找一些特定于双工通道的建议,其中服务器可能会尝试使用出现故障的回调通道.因此,当频道发生某些事情时,我需要立即重新连接/重新订阅的内容.目前,我正在收听频道的Closing事件,如果状态不是已关闭,则重新创建它.它有点工作,但它感觉hacky ......
我有一个自托管的wcf双工回调服务的问题.我得到一条InvalidOperationException消息:
此操作将死锁,因为在当前消息完成处理之前无法接收回复.如果要允许无序消息处理,请在CallbackBehaviorAttribute上指定Remediate的ConcurrencyMode或Multiple.
这是我的服务行为:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Reentrant, UseSynchronizationContext = true)]
Run Code Online (Sandbox Code Playgroud)
这是我的服务合同:
[ServiceContract(SessionMode = SessionMode.Required, CallbackContract = typeof(IClientCallback))]
[ServiceContract]
public interface IClientToService
{
[OperationContract(IsOneWay = false)]
LVSSStatus GetLvssStatus();
[OperationContract(IsOneWay = true)]
void PickSpecimen(long trackingNumber, int destCode);
[OperationContract(IsOneWay = true)]
void CancelCurrentPickTransaction();
}
Run Code Online (Sandbox Code Playgroud)
这是我的回调界面:
public interface ILvssClientCallback
{
[OperationContract(IsOneWay = true)]
void SendClientCallback(LvssCallbackMessage callbackMessage);
[OperationContract(IsOneWay = false)]
List<SpecimenTemplateDescriptor> GetTemplateDescriptorList(DrawerLayout drawerLayout);
[OperationContract(IsOneWay = false)]
SpecimenTemplate SelectSpecimenTemplate(string templateName, int version);
[OperationContract]
void SpecimenStoredInContainer(string containerID, bool isValidRackID, int rackRow, int rackCol, …Run Code Online (Sandbox Code Playgroud) 使用WSDualHttpBinding进行双工回调是否适用于实际场景?说,我有一个使用随机端口的.NET应用程序,该服务是否能够解析客户端的基地址和端口以进行回调?
为了努力磨练一些示例服务以用作我们内部场景的参考,我创建了这个WCF双工通道示例,汇总了多年来发现的几个示例.
双工部分不起作用,我希望我们都可以一起搞清楚.我讨厌发布这么多代码,但我觉得我已经把它缩减到了WCF的最短时间,同时整合了我希望由社区审查的所有部分.这里可能有一些非常糟糕的想法,我不是说它是对的,它就是我到目前为止所做的.
有三个部分.频道,服务器和客户端.三个项目,这里有三个代码文件.没有XML配置,所有内容都被编码.其次是代码输出.
Channel.proj/Channel.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
namespace Channel
{
public interface IDuplexSyncCallback
{
[OperationContract]
string CallbackSync(string message, DateTimeOffset timestamp);
}
[ServiceContract(CallbackContract = typeof(IDuplexSyncCallback))]
public interface IDuplexSyncContract
{
[OperationContract]
void Ping();
[OperationContract]
void Enroll();
[OperationContract]
void Unenroll();
}
}
Run Code Online (Sandbox Code Playgroud)
Server.proj/Server.cs,引用Channel,System.Runtime.Serialization,System.ServiceModel
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.Timers;
using Channel;
using System.Diagnostics;
using System.Net.Security;
namespace Server
{
class Program
{
// All of this just starts up the service …Run Code Online (Sandbox Code Playgroud)