1

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

语境

我在 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 应用程序中,我有svcWeb 服务的文件:

<%@ 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

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

完整的堆栈如下:

服务器堆栈跟踪:在 System.ServiceModel.Channels.HttpChannelUtilities.ProcessGetResponseWebException(WebException webException, HttpWebRequest request, HttpAbortReason abortReason)
在 System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan 超时) 在 System.ServiceModel.Channels.RequestChannel.Request(消息消息,TimeSpan 超时) 在 System.ServiceModel.Dispatcher.RequestChannelBinder.Request(消息消息,TimeSpan超时)在 System.ServiceModel.Channels.ServiceChannel.Call(字符串操作,布尔单向,ProxyOperationRuntime 操作,Object[] 输入,Object[] 输出,TimeSpan 超时)在 System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall,ProxyOperationRuntime操作)在 System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage 消息)

在 [0] 处重新抛出异常:在 System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) 在 DDBR.DiscoveryServiceLibrary 的 System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)。 C:\Data\ROOT_APPS\DistributedDataBackupAndRecovery\TestClient\Program.cs 中 DDBR.TestClient.Program.Main(String[] args) 的 IEchoService.Echo(EchoMessage msg):System.AppDomain._nExecuteAssembly 的第 20 行(RuntimeAssembly 程序集,字符串[] args) 在 System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) 在 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
在 System.Threading.ThreadHelper.ThreadStart_Context(Object state)
在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx) 在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 在 System.Threading.ThreadHelper.ThreadStart()

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

很奇怪的东西……

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

http://localhost/T/Service.svc

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

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

该怎么办?

还有一件事...

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

实际上它应该是一个什么样的问题?不能超时真的不要相信这一点,它是一种简单的方法,在许多可能的方式中最快。很奇怪……真的。

4

2 回答 2

0

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

于 2012-10-24T09:54:00.393 回答
0

这个问题是DataContract相关的。在我用作传递给服务方法的消息的一个类中,我写错了一个属性,导致序列化程序经历循环......这导致StackOverflow Exception序列化程序变得狂暴并且连接被关闭。

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

于 2012-10-25T13:15:16.603 回答