如何:Web服务和处理Web服务中的客户端超时?

时间:2009-08-12 11:57:42

标签: .net web-services timeout

我正在尝试记录客户端在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服务中不会抛出异常。代码继续运行,直到它完成,然后将其结果返回到虚无(当连接关闭时)。

7 个答案:

答案 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终止请求时,它可能会被调用。

只是一些想法。