【问题标题】:Error when making First WCF Service Call进行第一次 WCF 服务调用时出错
【发布时间】:2011-05-12 18:43:10
【问题描述】:

我正在为一位合作伙伴用 Java 编写服务编写者的 WCF 客户端。当我对他们的服务进行第一次服务调用时,我遇到了一个例外。但随后的请求并没有抛出任何异常。我正在使用控制台应用程序对此进行测试。为什么第一次没有失败?

这是我如何多次调用服务的代码

for (int i = 0; i < 3; i++)
{
   ServiceClientTest();
}

这是绑定代码

TransportBindingElement transportElement = null;
        transportElement = new HttpsTransportBindingElement();
        ((HttpsTransportBindingElement)transportElement).AuthenticationScheme = AuthenticationSchemes.Basic;

        var messegeElement = new TextMessageEncodingBindingElement
        {
            MessageVersion = MessageVersion.CreateVersion(EnvelopeVersion.Soap11, AddressingVersion.None),
            ReaderQuotas =
                    {
                        MaxArrayLength = 200000,
                        MaxBytesPerRead = 200000,
                        MaxDepth = 200000,
                        MaxNameTableCharCount = 200000,
                        MaxStringContentLength = 200000
                    }
        };

        var binding = new CustomBinding(messegeElement, transportElement);
        return binding;

这是第一次请求的异常详情

未能为 CompanyXYZ ServiceCompany System.ServiceModel.CommunicationException 评分:接收对 https://test.intelligentcusomer.ServiceCompany.com/XYZCompanyAdapter/1.0 的 HTTP 响应时出错。这可能是由于服务端点绑定未使用 HTTP 协议。这也可能是由于服务器中止了 HTTP 请求上下文(可能是由于服务关闭)。有关更多详细信息,请参阅服务器日志。 ---> System.Net.WebException:底层连接已关闭:接收时发生意外错误。 ---> System.IO.IOException:无法从传输连接读取数据:已建立的连接被主机中的软件中止。 ---> System.Net.Sockets.SocketException:已建立的连接被主机中的软件中止 在 System.Net.Sockets.NetworkStream.Read(字节 [] 缓冲区,Int32 偏移量,Int32 大小) --- 内部异常堆栈跟踪结束 --- 在 System.Net.ConnectStream.Read(字节 [] 缓冲区,Int32 偏移量,Int32 大小) 在 System.Net.HttpWebRequest.MakeMemoryStream(流流) --- 内部异常堆栈跟踪结束 --- 在 System.Net.HttpWebRequest.GetResponse() 在 System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(时间跨度超时) --- 内部异常堆栈跟踪结束 ---

服务器堆栈跟踪: 在 System.ServiceModel.Channels.HttpChannelUtilities.ProcessGetResponseWebException(WebException webException,HttpWebRequest 请求,HttpAbortReason abortReason) 在 System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(时间跨度超时) 在 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 方法调用,ProxyOperationRuntime 操作) 在 System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage 消息)

在 [0] 处重新抛出异常: 在 System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg,IMessage retMsg) 在 System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData,Int32 类型) 在 MyCompany.Services.Clients.ServiceCompany.XYZCompanyAdapter.process(processRequest 请求) 在 MyCompany.Services.Clients.ServiceCompany.XYZCompanyAdapterClient.MyCompany.Services.Clients.ServiceCompany.XYZCompanyAdapter.process(processRequest request) 在 C:\Projects\MyCompany\MyCompany.Distribution\CustomDeliveryProcessor\Clients\XYZCompanyServiceClient.cs:line 1122 在 C:\Projects\MyCompany\MyCompany.Distribution\CustomDeliveryProcessor\Clients\XYZCompanyServiceClient.cs:line 1129 中的 MyCompany.Services.Clients.ServiceCompany.XYZCompanyAdapterClient.process(process process1) 在 C:\Projects\MyCompany\MyCompany.Distribution\CustomDeliveryProcessor\CusomerDelivery.cs:line 131 中的 CustomDeliveryProcessor.CusomerDelivery.CompanyTestTest() 处

【问题讨论】:

  • 每台客户端机器的第一次调用都会发生这种情况吗?或者只是网络服务器重启后的第一次调用?可能是客户端连接超时,因为 Web 服务器还没有启动 Web 服务。

标签: wcf wcf-client


【解决方案1】:

我通过将 KeepAlive 属性设置为 false 来修复此错误。我发现发生了什么,当第一个请求发送到服务端点时,从服务器得到 401 响应(这是显而易见的,因为服务使用基本身份验证,然后客户端在下一个请求中发送基本授权标头)关闭连接。客户端端点的默认行为是保持连接处于活动状态。尽管连接已关闭,但客户端仍使用已由服务器关闭的相同连接发送下一个请求,这会导致问题中出现上述错误。但是对于后续请求,此错误不会再次发生,因为客户端在第一个请求本身中发送带有授权标头的请求。所以没有401响应的机会。我做了什么来解决将 Keep alive 属性设置为 false 的问题。这样,在 401 响应之后,客户端会使用新连接发送另一个请求,而不是使用旧连接。这是代码

Binding binding = null;
        var transportElement = new HttpsTransportBindingElement
                                {
                                    AuthenticationScheme = AuthenticationSchemes.Basic,
                                    KeepAliveEnabled = false,
                                };

        var messegeElement = new TextMessageEncodingBindingElement
        {
            MessageVersion = MessageVersion.CreateVersion(EnvelopeVersion.Soap11, AddressingVersion.None),
            ReaderQuotas =
            {
                MaxArrayLength = 200000,
                MaxBytesPerRead = 200000,
                MaxDepth = 200000,
                MaxNameTableCharCount = 200000,
                MaxStringContentLength = 200000
            }
        };
        binding = new CustomBinding(messegeElement, transportElement);

        return binding;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-29
    • 2014-02-23
    • 2016-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多