从Windows服务

时间:2017-11-15 11:23:05

标签: c# .net wcf

我正在构建Windows服务应用程序,它必须定期调用WCF服务。问题是服务的第一次调用总是成功的,我得到了预期的响应,但第二次和任何其他请求失败后我得到以下异常:

  

System.ServiceModel.CommunicationException:接收到https:XXXXXXXXXXXX的HTTP响应时发生错误。这可能是由于服务端点绑定不使用HTTP协议。这也可能是由于服务器中止HTTP请求上下文(可能是由于服务关闭)。请参阅服务器日志以获取更多详---> System.Net.WebException:基础连接已关闭:接收时发生意外错误。 ---> System.IO.IOException:无法从传输连接读取数据:远程主机强制关闭现有连接。 ---> System.Net.Sockets.SocketException:远程主机强制关闭现有连接   在System.Net.Sockets.Socket.Receive(Byte []缓冲区,Int32偏移量,Int32大小,SocketFlags socketFlags)   ...

我的Windows服务是使用System.ServiceProcess.ServiceBase构建的。 对于定期调用,我使用System.Timers.Timer类,如下所示:

    protected override void OnStart(string[] args)
    {
        try
        {
            InitTimer();
        }
        catch (Exception ex)
        {
            ExceptionHandler.HandleException(ex);
        }
    }

    private void InitTimer()
    {
        Timer apiPollingTimer = new Timer(60000); // 1 minute

        apiPollingTimer.Elapsed += ((sender, e) =>
        {
            OnTimerElapsed(sender, e);
        });
        apiPollingTimer.Enabled = true;
        apiPollingTimer.AutoReset = true;

        apiPollingTimer.Start();
    }

    protected void OnTimerElapsed(object sender, ElapsedEventArgs e)
    {
        try
        {
            ServiceClient client = new ServiceClient();
            ServiceResult result = client.GetUpdateTimes();

            client.Close();
        }
        catch (Exception ex)
        {
            ExceptionHandler.HandleException(ex);
        }
    }

这是WCF端点的绑定配置:

      <basicHttpBinding>
        <binding name="transportSecurity" closeTimeout="00:01:00"
       openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
       allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
       maxBufferSize="655360000" maxBufferPoolSize="524288" maxReceivedMessageSize="655360000"
       messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
       useDefaultWebProxy="true">
      <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="655360000"
          maxBytesPerRead="4096" maxNameTableCharCount="16384" />
      <security mode="Transport">
        <transport clientCredentialType="Certificate" proxyCredentialType="None" realm="" />
      </security>
    </binding>
  </basicHttpBinding>

编辑:这是客户端和行为配置:

<client>
  <endpoint address="https://XXXXXXXXXXXX"
      behaviorConfiguration="ClientCertBehavior"
      binding="basicHttpBinding" bindingConfiguration="transportSecurity"
      contract="GetUpdateTimesInterface"
      name="GetUpdateTimes" />
</client>

    <behaviors>
  <endpointBehaviors>
    <behavior name="ClientCertBehavior">
      <clientCredentials>
        <clientCertificate storeLocation="LocalMachine" storeName="My" x509FindType="FindBySerialNumber" findValue="xx xx xx"/>
      </clientCredentials>
    </behavior>
  </endpointBehaviors>
</behaviors>

编辑2:绑定服务wsdl的部分:

      <wsdl:binding name="ServiceSoapBinding" type="tns:GetUpdateTimesInterface">
    <soap12:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="GetUpdateTimes">
      <soap12:operation soapAction="urn:GetUpdateTimes" style="document"/>
      <wsdl:input name="GetUpdateTimes">
        <soap12:body use="literal"/>
      </wsdl:input>
      <wsdl:output name="GetUpdateTimesResponse">
        <soap12:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="GetUpdateTimesService">
    <wsdl:port name="GetUpdateTimes" binding="tns:ServiceSoapBinding">
      <soap12:address location="http:XXXXX"/>
    </wsdl:port>
  </wsdl:service>

我到目前为止尝试的是更改配额属性,但它没有帮助,我仍然得到相同的异常第二次调用服务。此外,如果我制作简单的控制台应用程序,我复制粘贴相同的计时器实现和绑定配置我没有得到异常,服务被调用并每次返回响应,它只在我安装此Windows服务时失败。

此外,我无法访问WCF服务实现,只能使用wsdl。

非常感谢任何帮助。

编辑3: 我已经使用Fiddler进行了一些检查,我注意到的是第一次将服务称为头连接:添加Keep-Alive并且SessionID为空,而第二次添加SessionID。我想也许有一种方法可以删除Connection:Keep-Alive来自调用或清除SessionID(如果它存在会有帮助)。以下是来自Fiddler的图片请求/回复:Image

编辑4:

尝试用customBinding替换basicHttpBinding并设置keepAliveEnabled但它没有帮助:

      <customBinding>
    <binding name="customTransportSecurity" closeTimeout="00:01:00"
       openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00">
      <textMessageEncoding messageVersion="Soap12" writeEncoding="utf-8" />
      <httpsTransport keepAliveEnabled="false" transferMode="Buffered" requireClientCertificate="true"
        allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
        maxBufferSize="655360000" maxBufferPoolSize="524288" maxReceivedMessageSize="655360000" realm="" />
    </binding>
  </customBinding>

0 个答案:

没有答案