Ошибка при первом вызове службы WCF - PullRequest
2 голосов
/ 19 ноября 2010

Я пишу клиент WCF для службы записи на Java одним из партнеров. Я получаю исключение, когда я делаю первый сервисный звонок их сервису. Но последующий запрос не выкинул ни одного исключения. Я использую консольное приложение, чтобы проверить это. Почему это не удается в первый раз, а не в другой раз?

Вот код, как я звоню в службу несколько раз

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: ошибка при получении ответа HTTP на https://test.intelligentcusomer.ServiceCompany.com/XYZCompanyAdapter/1.0. Это может быть связано с тем, что привязка конечной точки службы не использует протокол HTTP. Это также может быть связано с тем, что сервер прерывает контекст HTTP-запроса (возможно, из-за закрытия службы). Смотрите журналы сервера для более подробной информации. ---> System.Net.WebException: базовое соединение было закрыто: при получении произошла непредвиденная ошибка. ---> System.IO.IOException: невозможно прочитать данные из транспортного соединения: установленное соединение было прервано программным обеспечением на вашем хост-компьютере. ---> System.Net.Sockets.SocketException: установленное соединение было прервано программным обеспечением на вашем хост-компьютере в System.Net.Sockets.NetworkStream.Read (буфер Byte [], смещение Int32, размер Int32) --- Конец внутренней трассировки стека исключений --- в System.Net.ConnectStream.Read (буфер Byte [], смещение Int32, размер Int32) в System.Net.HttpWebRequest.MakeMemoryStream (потоковый поток) --- Конец внутренней трассировки стека исключений --- в System.Net.HttpWebRequest.GetResponse () в System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply (TimeSpan timeout) --- Конец внутренней трассировки стека исключений ---

Трассировка стека серверов: в System.ServiceModel.Channels.HttpChannelUtilities.ProcessGetResponseWebException (WebException webException, запрос HttpWebRequest, HttpAbortReason abortReason) в System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply (TimeSpan timeout) в System.ServiceModel.Channels.RequestChannel.Request (сообщение-сообщение, время ожидания TimeSpan) в System.ServiceModel.Dispatcher.RequestChannelBinder.Request (сообщение-сообщение, время ожидания TimeSpan) в System.ServiceModel.Channels.ServiceChannel.Call (строковое действие, логический односторонний режим, операция ProxyOperationRuntime, Object [] ins, Object [] outs, TimeSpan timeout) в System.ServiceModel.Channels.ServiceChannelProxy.InvokeService (метод IMethodCallMessageCall, операция 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 (запрос запроса процесса) в C: \ Projects \ MyCompany \ MyCompany.Dist. в MyCompany.Services.Clients.ServiceCompany.XYZCompanyAdapterClient.process (процесс process1) в C: \ Projects \ MyCompany \ MyCompany.Distribution \ CustomDeliveryProcessor \ Clients \ XYZCompanyServiceClient.cs: строка 1129 в CustomDeliveryProcessor.CusomerDelivery.CompanyTestTest () в C: \ Projects \ MyCompany \ MyCompany.Distribution \ CustomDeliveryProcessor \ CusomerDelivery.cs: строка 131

1 Ответ

3 голосов
/ 24 ноября 2010

Я исправил эту ошибку, установив для свойства 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;
...