考虑一些客户端调用WebMethod的情况,并且在建立连接之后,主机进程崩溃并且连接变为半开。 ASP.NET WebMethod代理会自动检测它吗?
我们假设WebMethod超时已达到无限或大量时间。是否仅在TCP保持活动数据包发送时检测到连接错误(默认情况下在Windows上空闲2小时后)?
[WebService(Namespace = "http://www.example.com/TestService/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class TestService : System.Web.Services.WebService
{
[WebMethod]
public void DoLongWork()
{
// long work here
}
}
Web参考代理呼叫:
public void ServiceClient()
{
var serviceProxy = new MyNamespace.TestService();
// serviceProxy.Url = ...
serviceProxy.Timeout = -1; // do not use timeout
// will it wait for 2 hours (when TCP keep-alive will be sent) if connection was lost after handshake?
serviceProxy.DoLongWork();
}
更新
我尝试过多个场景,这里是我使用Wireshark查看幕后内容的结果。
在这两种情况下,客户端通过发送TCP RST标志进行通知。似乎Windows负责关闭崩溃/被杀死进程的套接字。在.NET中,System.Net.WebException
将被抛出:
Unhandled Exception: System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a receive. ---> System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags) at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size) --- End of inner exception stack trace --- at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size) at System.Net.PooledStream.Read(Byte[] buffer, Int32 offset, Int32 size) at System.Net.Connection.SyncRead(HttpWebRequest request, Boolean userRetrievedStream, Boolean probeRead) --- End of inner exception stack trace --- at System.Web.Services.Protocols.WebClientProtocol.GetWebResponse(WebRequest request) at System.Web.Services.Protocols.HttpWebClientProtocol.GetWebResponse(WebRequest request) at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters) at WebMethodAndTCPHalfOpenTest.TestWebReference.TestService.DoLongWork(Int32 sec) at WebMethodAndTCPHalfOpenTest.Program.Main(String[] args)
TCPView v3.01 - TCP/UDP endpoint viewer Copyright (C) 1998-2010 Mark Russinovich and Bryce Cogswell Sysinternals - www.sysinternals.com [TCP] WebMethodAndTCPHalfOpenTest.exe PID: 8180 State: ESTABLISHED Local: 192.168.1.2 Remote: 5.167.159.81Windows Version: Microsoft Windows [Version 6.1.7601]
Wireshark输出:
我已在我的系统上检查了KeepAliveTime注册表设置:
HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters但它已丢失,因此应使用默认的2小时(?)。
第二点中描述的结果可以解释吗?为什么没有发送TCP keepalive?代理是否为底层套接字(https://msdn.microsoft.com/en-us/library/windows/desktop/ee470551(v=vs.85).aspx)显式确定了不同的keepalive行为?
答案 0 :(得分:2)
如果主机进程崩溃,则连接将关闭。它不会等待TCP保持活跃。您可以通过旋转WebService并使其自动崩溃来轻松测试此方案。
答案 1 :(得分:2)
看起来保持活着并不保证,因为事情可能会破坏Windows中的设置(没有注册表值不是结束所有)。
根据这个: Windows TCP socket has SO_KEEPALIVE enabled by default?
看起来您不应该依赖此行为并设置超时。如果您正在使用soap请求,则可以始终调用异步请求,然后根据客户端可配置值等待请求,并对超时进行良好的逻辑处理。