我正在尝试记录客户端在Web服务调用上超时时发生的情况。
看看下面的HelloWorld代码。这是我想要做的,但似乎IsClientConnected无法正常工作,因为它总是返回true。
[WebMethod]
public string HelloWorld() {
//.. Do the Webservice stuff
if (!Context.Response.IsClientConnected) {
//Log some vital info about this call that timed out...
}
return "The WebService Result";
}
有没有人知道另一种检查Web服务调用状态的方法?
当客户端与Web服务调用断开连接时,Web服务中不会抛出异常。代码继续运行,直到它完成,然后将其结果返回到虚无(当连接关闭时)。
答案 0 :(得分:1)
我不相信一般会有例外。即使服务发送了长响应,导致传出传输窗口关闭,并且超时等待能够发送字节,所有这些都将在Web方法返回ASP.NET之后发生。
您应该做的是了解哪些网络方法花费的时间过长。您可以通过启用跟踪来开始执行此操作,如“Enabling Tracing in ASP.NET Web Services”中所示。然后,您可能需要更进一步,并分析服务以查看花费的时间。
您还应该仔细查看事件日志。特别是,从“ASP.NET”事件源中查找警告事件。这些来自ASP.NET Health Monitoring。我建议您了解健康监测系统,因为您可能会发现它为您做了许多事情,您必须自己编写,只需要以配置为代价。
答案 1 :(得分:0)
我希望每个Web服务调用都是请求/响应。如果服务不可用或超时等错误,我会发出抛出异常。
那么可以用try catch包围呼叫吗?
答案 2 :(得分:0)
这取决于您使用的Web服务框架的详细信息。从你所展示的内容来看,如果没有机制可以检测到这一点,我将不会感到惊讶。
一般来说,Web服务通常不需要使用HTTP之类的传输,您可以通过队列甚至电子邮件进行响应。通常,您不能将简单Web服务的服务器实现确保您的客户端已经看到了答案。如果您的测试有效,您会推断出什么?在你做完测试的那一刻,你决定不登录,然后在你回来之前,他已经离开了一段纳秒。在简单的SOAP / HTTP中,Client和Server之间没有事务关系。
有一些附加的Web服务标准可以解决其中的一些问题,但通常您需要设计Web服务,前提是调用者可能看不到答案。 (也许你也提供状态服务,所以客户可以退出然后回来问“你处理订单”345“)。
请告诉我们您希望通过此日志记录实现的目标,也许有人有设计方法可以提供帮助。
答案 3 :(得分:0)
HTTP协议没有规范服务器如何ping客户端。 IsClientConnected的意义 - 检查是否存在渲染HttpResponse的某些'不满意'查询。 并且可能(我不确定)客户端是否支持keep-connection-alive。
考虑拉动架构 - 你是否有单向方法,以及来自客户端的一些看门狗定期检查方法是否完成。
答案 4 :(得分:0)
我认为,为了让IsClientConnected返回false,您的Web服务代码中写着“// ..执行Web服务的东西”的部分必须比客户端的超时设置花费更长的时间来执行。您可以通过将客户端的超时设置为60秒并在IsClientConnected调用之前在您的Web服务代码中放置Thread.Sleep(70000)来模拟此情况。
但是,我不认为这会导致IsClientConnected返回false。定时Web服务请求并重置与服务器的连接是两种不同的动物。如果Response有一个名为IsClientStillWaitingForThisWebServiceCallToReturn的方法,那么可能会做你想要的。
我认为如果你在网络服务方法仍然在IsClientConnected检查之前的部分,你可以让IsClientConnected返回false,但是我猜这不是你想要的。< / p>
答案 5 :(得分:0)
我创建了一个简单的测试客户端,并将我的请求设置为100ms的超时
HttpWebRequest MakeRequest = (HttpWebRequest)WebRequest.Create("http://localhost:55959/ScanServer.asmx");
if (MakeRequest == null)
{
throw new Exception();
}
HttpWebResponse PostResponse = null;
MakeRequest.Method = "POST";
MakeRequest.AuthenticationLevel = System.Net.Security.AuthenticationLevel.None;
MakeRequest.UserAgent = "testing";
MakeRequest.Timeout = 100;
MakeRequest.ContentType = "application/soap+xml; charset=utf-8;";
try
{
byte[] PostBytes = UTF8Encoding.UTF8.GetBytes(PostData);
MakeRequest.ContentLength = PostBytes.Length;
Stream RequestStream = MakeRequest.GetRequestStream();
RequestStream.Write(PostBytes, 0, PostBytes.Length);
PostResponse = (HttpWebResponse)MakeRequest.GetResponse();
}
catch
{
throw;
}
在调试时调用SOAP WebService,我等待一个断点,直到客户端收到超时异常。然后将Context.Response.IsClientConnected
的值设置为false。我还使用Fiddler发送请求,当在服务器断点时我中止了会话。同样,该值设置为false。
我不知道为什么在检查IsClientConnected时没有能够记录数据的超时,除非超时是在与服务器的初始连接中。
答案 6 :(得分:-1)
订阅某种事件比检查某些标志更好。基本上,ASP.NET正在终止请求,因为它花费的时间比配置的超时值(httpRuntime元素中的executionTimeout设置)要长。但是,我不确定ASP.NET运行时是否存在此类事件。显然,它也没有引起任何例外。因此,在这种特定情况下,您的服务和ASP.NET运行时之间似乎存在脱节。我很想知道是否有办法/技巧来完成你所追求的目标。
与此同时,您可以查看ASP.NET性能计数器。有一个叫做“请求超时”。它可能包括在队列中等待或执行期间超时的请求。您可以在Web方法的开头和结尾读取Web服务的性能计数器。如果数字跳了,这意味着请求只是超时。它可能不一定意味着跳转对应于该特定请求,但在任何情况下,您仍然可以记录一些信息,例如传递给Web方法的参数,经过的时间等可能有用的信息。您还可以在web.config中增加executionTimeout值,以便在您尝试优化Web方法以便在客户端需要立即解决方案时更快地运行时留出更多时间。
如果这是一个asmx Web服务,您可能希望查看global.asax中的Session_End事件。当ASP.NET终止请求时,它可能会被调用。
只是一些想法。