我在堆栈中阅读了许多博客和许多问题,但找不到我的确切场景(实际上这是非常简单的场景)。
语境
我在 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;
}
}
}
像EchoMessageResponse
和EchoMessage
已经DataContract
应用的类,它们没问题。
正如我之前所说的,该服务被编译成一个 dll(程序集),我只需添加一个引用就可以将其导入 bin 文件夹中的 Web 应用程序中。在这个 Web 应用程序中,我有svc
Web 服务的文件:
<%@ 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
到目前为止,这种方法一直对我有用......不明白为什么我现在有问题......
实际上它应该是一个什么样的问题?不能超时真的不要相信这一点,它是一种简单的方法,在许多可能的方式中最快。很奇怪……真的。