2009-08-12 96 views
7

我正在尝试记录客户在Web服务调用中超时时发生的情况。如何:Web服务和处理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服务中不会引发异常。代码继续运行,直到它完成,然后将其结果返回到虚无(当连接关闭时)。

+3

IIS版本在IsClientConnected的准确性中扮演着重要角色。我急于想看看别人提出的解决同样问题的方法*没有*投票。 – Marc 2009-08-12 13:31:21

回答

0

我希望每个Web服务调用都是一个请求/响应。如果发生错误,例如服务不可用或超时,我希望发生异常。

那么是否有可能用try catch包围呼叫?

+0

当客户端超时时,Web服务内不会抛出异常。它只是完成并将结果“发送”为虚无。 – Wolf5 2009-08-12 12:14:08

+0

aha,所以你说的是服务器端,而不是客户端。对不起,我不清楚。 – djna 2009-08-12 12:38:32

-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杀死请求时,它可能会被调用。

只是有些想法。

+1

-1:是什么让你认为请求被“杀死”?他所知道的只是客户端暂停。 – 2009-08-12 13:06:07

+0

是什么让你觉得他不是?也许你应该开始专注于提供答案,而不是尝试与其他人的帖子发现错误。我们试图给OP一些方向和提示。最后,他需要决定哪一个适用于或最适合他/她的问题。我们只有有限的信息与之合作并做出假设。 – 2009-08-12 13:16:24

+1

“他”?他假设如果客户“断开连接”,服务将被通知。事实并非如此。他还假设客户端断开连接。所有这些都是从客户超时的事实推断出来的。事实是,我们只知道客户超时。 – 2009-08-12 13:29:24

0

这将取决于您正在使用的Web服务框架的细节。从你所表现出来的情况来看,如果你没有机制来检测这一点,我将不会感到惊讶。

想象一下,Web服务通常不需要使用HTTP等传输方式,您可以通过队列或电子邮件进行响应。一般来说,您不能像服务器实现简单的Web服务那样确保您的客户已经看到了答案。如果你的测试有效,你会推断什么?在你做测试的那一刻,他就在那里,在你决定不登录之后的一秒钟,但在你回来之前他已经离开了。客户端和服务器之间在简单的SOAP/HTTP中没有事务关系。

有一些附加的Web服务标准来解决其中的一些问题,但通常你需要设计你的Web服务,假设调用者可能看不到答案。 (也许你也提供状态服务,所以客户可以放弃,然后回来问“你是否处理了订单”345)。

请告诉我们你想用这个日志记录实现什么,也许有人有一个设计方法来帮助。

+0

集群中的服务存在问题,但我们不知道当客户端连接到集群URL而不是物理服务器URL时,哪个集群服务是超时的。 这里的目标是在这些情况下,在客户端和服务器之间出现超时或过早断开连接的情况下,通常会向我的webservices添加一个“登录到Windows”事件。 – Wolf5 2009-08-12 12:58:27

+0

我这样做,假设如下:当客户端进行WS调用到服务器有一个TCP套接字连接建立。此连接仍在等待回复。一旦服务完成了代码的处理,数据就会在这个连接上返回。 只要服务正在执行代码就建立了连接,那么应该有一种方法来获取该TCP连接的状态。 – Wolf5 2009-08-12 12:59:16

+0

所以我只想要一个通用的“故障转移”记录器,用于客户端断开连接的各种Web服务,我可以轻松添加到代码中。 – Wolf5 2009-08-12 13:02:37

0

HTTP协议没有规定服务器如何ping客户端。 IsClientConnected的意义 - 检查是否存在一些'不满意'的查询来呈现HttpResponse。 如果客户端支持keep-connection-alive,可能会(我不确定)。

想想拉动架构 - 是否有单向的方法,以及客户端的一些看门狗定期检查方法是否完成。

+0

是的。这将在一个轮询器解决方案上失败,但到目前为止,当我嗅探有关web服务的网络流量时,有一个请求和响应。从来没有建立一个新的HTTP连接来接收结果,因为这将显示在服务器的新HTTP头中。所以我假设有一个连接保持活着。这种连接将以某种方式成为.Net Socket。可能隐藏起来,但最糟糕的情况下可以通过一点反思。插座有一个我可以检查的状态。 – Wolf5 2009-08-12 13:08:28

+0

是的,你是对的。 IsClientConnected完全返回您描述的内容。保持活力只是optiomization标志,但不是规则。这就是为什么它谈论可能性(仅限于)通过同一套接字传输其他内容。 – Dewfy 2009-08-12 13:14:13

0

我认为为了让IsClientConnected返回false,说明“//做Web服务的东西”的Web服务代码部分需要花费更长的时间来执行,而不是客户端的超时设置。您可以通过将客户端的超时设置为60秒并在IsClientConnected调用之前在您的Web服务代码中放入Thread.Sleep(70000)来模拟此过程。

但是,我不认为即使这会导致IsClientConnected返回false。对Web服务请求进行定时并重置与服务器的连接是两种不同的动物。如果Response有一个名为IsClientStillWaitingForThisWebServiceCallToReturn的方法,那可能会做你想做的事情。

我想你可以让IsClientConnected返回false,如果你实际上断开客户端的网络,而Web服务方法仍然在IsClientConnected检查之前的部分,但我猜这不是你想要的。

+0

我的概念测试只是一个运行睡眠的web服务应用程序,就像您提到的那样,另一个应用程序调用该webservice的超时时间为100ms。该应用程序终止并出现错误=连接已关闭。然后,应用程序进入IsClientConnected,然后仍然是True,并返回没有错误的退出。 – Wolf5 2009-08-12 13:23:30

+0

正如我所说的,客户端在Web服务请求上超时并且客户端重置到服务器的连接不是同一回事,所以您的结果正是我期望的结果。IsClientConnected返回True,因为客户端仍然连接到服务器(即使Web服务调用已超时)。 – MusiGenesis 2009-08-12 13:29:01

+1

在Web服务调用上进行时序调整仅在客户端发生,服务器不会知道任何事情。 – MusiGenesis 2009-08-12 13:30:23

1

我不相信总体上会有例外。即使该服务正在发回一个长响应,以致传出传输窗口关闭,并且等待可以发送字节的超时,所有这些都会在Web方法返回到ASP.NET之后发生。

你应该做的是学习哪些Web方法花费的时间太长。您可以通过打开跟踪来开始执行此操作,如“Enabling Tracing in ASP.NET Web Services”中所示。然后,您可能需要更进一步,并对服务进行简介以查看时间花在何处。

您还应仔细查看事件日志。特别是,从“ASP.NET”事件源查找警告事件。这些来自ASP.NET Health Monitoring。我建议您了解健康监测系统,因为您可能会发现它为您做了很多事情,您只需花费配置即可自行编写。

+0

我会研究健康监测。恐怕追踪将会是致命的。来自几种不同类型客户的这些服务有很多流量。 糟糕的是,似乎没有办法从web服务端检测客户端和web服务之间的断开连接。如果有的话,我希望有人会启发这个线程。 – Wolf5 2009-08-12 13:43:10

+0

你正在运行哪个操作系统版本? Vista和Server 2008都有一个EtwTraceListener,它记录到“Windows事件跟踪”子系统,该子系统速度足以让设备驱动程序使用它。 – 2009-08-12 15:23:54

+0

2003在服务器上。 – Wolf5 2009-08-13 06:41:16

0

我创建了一个简单的测试客户端,并设置了我的请求在100毫秒

 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 Web服务调用调试时我一直在等待一个破发点,直到客户端收到超时异常。然后将Context.Response.IsClientConnected的值设置为false。我还使用Fiddler发送请求,并在服务器中断点时中止会话。该值也被设置为false。

为什么在检查IsClientConnected时无法记录数据时出现超时的原因,除非超时处于与服务器的初始连接中。