获取System.Net.WebException:底层连接已关闭但无法修复

时间:2012-10-24 09:48:32

标签: c# .net wcf web-services iis

我在堆栈中已经阅读了很多博客和许多问题,但找不到我的确切场景(实际上非​​常简单)。

上下文

我在Visual Studio 2010项目的库中编写了一个服务。我编写了服务合同的接口和实现该合同的服务类。

namespace MyNS.WebSrvLibrary {
[ServiceContract(Namespace = "http://schemas.dummy.com")]
public interface IEchoService {
  [OperationContract()]
  EchoMessageResponse Echo(EchoMessage msg);
}
}

服务:

namespace MyNS.WebSrvLibrary {
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
public class EchoService : IEchoService {
  public EchoService() {}
  [OperationBehavior()]
  public virtual EchoMessageResponse Echo(EchoMessage msg) {
    return new EchoMessageResponse("Ciccio");
  }
  public static IEchoService GetChannel(string addr = "") {
    // Create the service endpoint
    Binding binding = new BasicHttpBinding();
    ServiceEndpoint endpoint =
      new ServiceEndpoint(
            ContractDescription.GetContract(typeof(IEchoService)),
            binding,
            new EndpointAddress(addr));
    // Create channel factory and get proper channel for service.
    ChannelFactory<IEchoService> channelFactory = new ChannelFactory<IEchoService>(endpoint);
    IEchoService svc = channelFactory.CreateChannel();
    return svc;
  }
}
}

EchoMessageResponseEchoMessage等类已应用DataContract,但没关系。

我之前说过的服务被编译成一个dll(程序集),只需添加引用即可导入到bin文件夹中的Web应用程序中。在此Web应用程序中,我有用于Web服务的svc文件:

<%@ ServiceHost Language="C#" Debug="true" Service="MyNS.WebSrvLibrary.EchoService" %>

这是Web.config文件:

<?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <services>
      <service name="MyNS.WebSrvLibrary.EchoService">
        <endpoint name="basicHttpBinding" address="" 
                                     binding="basicHttpBinding" 
                                     bindingConfiguration="basicHttpBinding_Svc"
                                     contract="MyNS.WebSrvLibrary.IEchoService"/>
        <endpoint name="mexHttpBinding" address="/Mex"
                                     binding="mexHttpBinding"
                                     contract="IMetadataExchange"/>
      </service>
    </services>
    <bindings>
      <basicHttpBinding>
        <binding maxReceivedMessageSize="2147483647" openTimeout="12:00:00" receiveTimeout="12:00:00" closeTimeout="12:00:00" sendTimeout="12:00:00">
          <readerQuotas maxStringContentLength="1310720"
                        maxArrayLength="16384"
                        maxBytesPerRead="24096"
                        maxDepth="10000"
                        maxNameTableCharCount="16384"/>
        </binding>
        <binding name="basicHttpBinding_Svc" maxReceivedMessageSize="2147483647" openTimeout="12:00:00" receiveTimeout="12:00:00" closeTimeout="12:00:00" sendTimeout="12:00:00">
          <readerQuotas maxStringContentLength="1310720"
                        maxArrayLength="16384"
                        maxBytesPerRead="24096"
                        maxDepth="10000"
                        maxNameTableCharCount="16384"/>
        </binding>
      </basicHttpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>
</configuration>

所以,最后,我有一个客户端应用程序编译成可执行的.exe文件,如下所示:

class Program {
  static void Main(string[] args) {
    IEchoService svc = EchoService.GetChannel("http://localhost:80/T/Service.svc");
    EchoMessageResponse rmsp = svc.Echo(new EchoMessage("Hello"));
    System.Threading.Thread.Sleep(10000);
  } /* Main */
} /* Program */

有关服务器端事务的信息

Web应用程序在IIS中的默认网站中托管,当然是在侦听端口80。

问题

当我运行可执行应用程序时,我收到System.ServiceModel.CommunicationException例外:

  

接收HTTP响应时发生错误   http://localhost/T/Service.svc。这可能是由于服务   端点绑定不使用HTTP协议。这也可能是应该的   到服务器中止的HTTP请求上下文(可能是由于   关闭服务)。有关详细信息,请参阅服务器日志。

innerException的类型为:System.Net.WebException

  

基础连接已关闭:发生意外错误   收到。

innerException(异常树中的最后一个)属于System.Net.Sockets.SocketException类型:

  

远程主机强行关闭现有连接。

完整的堆栈如下:

  

服务器堆栈跟踪:at   System.ServiceModel.Channels.HttpChannelUtilities.ProcessGetResponseWebException(引发WebException   webException,HttpWebRequest请求,HttpAbortReason abortReason)
  在   System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(时间跨度   超时)at   System.ServiceModel.Channels.RequestChannel.Request(消息消息,   TimeSpan超时)at   System.ServiceModel.Dispatcher.RequestChannelBinder.Request(消息   消息,TimeSpan超时)at   System.ServiceModel.Channels.ServiceChannel.Call(String action,   Boolean oneway,ProxyOperationRuntime操作,Object [] ins,   对象[]出局,TimeSpan超时)at   System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage   methodCall,ProxyOperationRuntime operation)at   System.ServiceModel.Channels.ServiceChannelProxy.Invoke(即时聊天   消息)

     

在[0]处重新抛出异常:at   System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(即时聊天   reqMsg,IMessage retMsg)at   System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData&安培;   msgData,Int32类型)at   DDBR.DiscoveryServiceLibrary.IEchoService.Echo(EchoMessage msg)at   DDBR.TestClient.Program.Main(String [] args)in   C:\数据\ ROOT_APPS \ DistributedDataBackupAndRecovery \ TestClient的\ Program.cs中:线   20在System.AppDomain._nExecuteAssembly(RuntimeAssembly程序集,   System.AppDomain.ExecuteAssembly上的String [] args)(String   assemblyFile,Evidence assemblySecurity,String [] args)at   Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
  在System.Threading.ThreadHelper.ThreadStart_Context(对象状态)
  在System.Threading.ExecutionContext.Run(ExecutionContext   executionContext,ContextCallback回调,对象状态,布尔值   ignoreSyncCtx)at   System.Threading.ExecutionContext.Run(执行上下文   executionContext,ContextCallback回调,对象状态)at   System.Threading.ThreadHelper.ThreadStart()

可以在第一个异常的StackTrace属性中找到(初始异常,而不是内部异常)。

有点奇怪......

非常奇怪的是,如果我打开浏览器并输入:

http://localhost/T/Service.svc

我得到了着名的屏幕,我的Microsoft IIS公开了一些有关该服务的基本信息。这意味着Web服务处于活动状态并在指定的地址(端点)上运行。

我寻找这个例外,但没有人有这些特点......通常会涉及更详细和复杂的背景。

怎么办?

还有一件事......

您可能想知道为什么我不使用服务引用...因为我不想。这是有原因的。这里的要点是GetChannel方法到目前为止一直与我合作......不明白为什么我现在有问题......

实际上它应该是什么样的问题?它不能超时真的不相信这一点,它是一种简单的方法,以最快的方式发挥作用。这很奇怪......真的。

2 个答案:

答案 0 :(得分:0)

看起来您需要向控制台应用添加服务引用并使用代理对象而不是您正在使用的实际服务类。您正在将该服务用作客户端。而不是通过在向客户端项目添加服务引用时创建的自动生成的代理类来调用服务。

答案 1 :(得分:0)

问题是与DataContract相关的问题。在我用作传递给服务方法的消息的一个类中,我有一个错误的属性导致序列化器遇到循环...这导致StackOverflow Exception导致序列化器进入Berserk并且连接到关闭。

我认为问题不是数据相关问题,也没有为此提供代码。很抱歉打扰了他们。至少我的问题可以提供一些关于DataContracts中的错误的有用信息,但是通过查看异常描述无法真正掌握。