none
Проблема с повторными подключениями WCF RRS feed

  • Вопрос

  • Здраствуйте. У меня возникла неприятная проблема с WCF.

    Моя программа синхронизирует файлы по сети. Клиенты подключаются к серверу, происходит синхронизация, новые файлы клиента передаются на сервер, новые файлы сервера скачиваются на клиент. Причем вначале производится провера соединения, в конце выполняются еще несколько процедур с сервера. Первый раз все работает нормально и иногда даже второй. Но следующий сеанс виснет на каком либо из шагов, причём виснет при подключении к серверу. Далее вылазит time limit и больше сервер не пингуется. После перезапуска программы все работает, но снова как и прежде после 1-2 сеанса виснет.

    Все отлично работает на локальном компьютере, но не работает по сети.

    Вот файл конфигурации клиента:

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
     <system.serviceModel>
      <bindings>
       <basicHttpBinding>
        <binding name="BasicHttpBinding_ISyncService" closeTimeout="00:01:00"
         openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:10:00"
         allowCookies="false" bypassProxyOnLocal="false" maxReceivedMessageSize="1500000000"
         messageEncoding="Mtom" transferMode="Streamed" useDefaultWebProxy="false">
         <security>
          <transport realm="">
           <extendedProtectionPolicy policyEnforcement="Never" />
          </transport>
         </security>
        </binding>
       </basicHttpBinding>
    
      </bindings>
      <client>
       <endpoint address="http://localhost:8731/SyncService" binding="basicHttpBinding"
        bindingConfiguration="BasicHttpBinding_ISyncService" contract="ServiceReference1.ISyncService"
        name="BasicHttpBinding_ISyncService" />
      </client>
     </system.serviceModel>
    </configuration>
    

     Вот сервера:

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
    
     <system.web>
      <httpRuntime maxRequestLength="1500000000"/>
      <customErrors mode="Off"></customErrors>
     </system.web>
    
     <system.serviceModel>
      <bindings>
       <basicHttpBinding>
        <binding name="SyncServicesBinding" closeTimeout="00:01:00" openTimeout="00:01:00"
         receiveTimeout="00:10:00" sendTimeout="00:20:00" allowCookies="false"
         bypassProxyOnLocal="false" maxReceivedMessageSize="1500000000"
         messageEncoding="Mtom" transferMode="Streamed">
         <security>
          <transport>
           <extendedProtectionPolicy policyEnforcement="Never" />
          </transport>
         </security>
        </binding>
       </basicHttpBinding>
       
      <services>
       <service behaviorConfiguration="SynDataNet.SyncServiceBehavior"
        name="SynDataNet.SyncService">
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <endpoint address="" binding="basicHttpBinding" bindingConfiguration="SyncServicesBinding"
         contract="SynDataNet.ISyncService" />
        <host>
         <baseAddresses>
          <add baseAddress="http://localhost:8731/SyncService" />
         </baseAddresses>
        </host>
       </service>
      </services>
    
      <behaviors>
       <serviceBehaviors>
        <behavior name="SynDataNet.SyncServiceBehavior">
         <serviceMetadata httpGetEnabled="true" />
         <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
       </serviceBehaviors>
      </behaviors>
     </system.serviceModel>
    </configuration><br/>
    
    

    Вот так создаю подключение на клиенте:

    SynDataNet.ServiceReference1.SyncServiceClient cl = new SynDataNet.ServiceReference1.SyncServiceClient("BasicHttpBinding_ISyncService",<br/> "http://" + IPport[0] + ":" + IPport[1] + "/SyncService");
    

    Вызываю методы на клиенте так:

    cli.UploadFileBase(ClientBaseName, fileInfo.Name, fileInfo.Length, ServerBaseName, syncOne, stream);
    

    Закрываю в конце соединение методом Close()

    cli.Close();
    

     На сервере ничего особенного не делаю, очищаю потоки:

      [MessageContract]
      public class RemoteFileInfoDown : IDisposable
      {
        [MessageHeader(MustUnderstand = true)]
        public string FileName;
    
        [MessageHeader(MustUnderstand = true)]
        public long Length;
    
        [MessageBodyMember(Order = 1)]
        public System.IO.Stream FileByteStreamDown;
    
        public void Dispose()
        {
          if (FileByteStreamDown != null)
          {
            FileByteStreamDown.Close();
            FileByteStreamDown = null;
          }
        }
      }
    

     На клиенте все выполняется в отдельном классе, вызываю методы класса из формы.

    Включал трассировку сервиса: 

    на клиенте при успешном выполнении метода в логе:

     1) Открытие System.ServiceModel.Channel/41515234

     2) Информация о ServiceChannel.

     3) Открытие System.ServiceModel.Channels.HttpChannelFactory+HttpRequestChannel/41917874

     4) System.ServiceModel.Channels.HttpChannelFactory+HttpRequestChannel/41917874 открыт.

     5) System.ServiceModel.Channels.ServiceChannel/41515234 открыт.

     6) Сообщение было написано.

     7) Через канал отправлено сообщение.

     8) Получен ответ HTTP

     9) Через канал получено сообщение.

     10)  Через канал запроса получен ответ

     11) Сообщение было прочитано

     12) Сообщение было закрыто

     13) Сообщение было закрыто.

    При невыполнении метода с сервера все прерывается на 5 шаге, 6 шаг не появляется, лог прерывается. Никаких исключений не генерируется.

    Пожалуйста, помогите в решении проблемы, заранее благодарен.

     

    1 декабря 2010 г. 22:31

Ответы

  • Поменяй ServicePointManager.DefaultConnectionLimit с 2 на что-нибудь побольше. Кодом, или через конфиг:

    <system.net>
     <connectionManagement>
       <add address="*" maxconnection="8"/>
     </connectionManagement>
    </system.net>
    
    
    Если поможет - значит не всегда закрываешь соединения на клиенте.

    • Помечено в качестве ответа [S]hell 6 декабря 2010 г. 23:19
    6 декабря 2010 г. 13:13

Все ответы

  • Попробуйте установить 
    <serviceBehaviors>
    <behavior name="SynDataNet.SyncServiceBehavior">
    <serviceThrottling maxConcurrentCalls ="9999" maxConcurrentInstances=" 9999 "/> 
    </behavior> 
    </serviceBehaviors>
    

    Также посмотрите топик http://social.msdn.microsoft.com/Forums/en-NZ/wcf/thread/29f8d535-de29-4cf2-8f9d-cc79f01344c6

    Возможно это вам поможет


    Для связи [mail]
    2 декабря 2010 г. 16:06
    Модератор
  • Почитал топик, метод Close() я и так выполнял всегда.

     

    Попробовал установить на сервере данные параметры, тоже не помогает.

    Я думаю проблема в клиенте, а не в сервере, так как после перезапуска программы (клиента) все снова работает. Как будто забивает канал, или соединение не до конца завершается, а потом, после перезапуска, все снова работает.

    4 декабря 2010 г. 18:49
  • Поменяй ServicePointManager.DefaultConnectionLimit с 2 на что-нибудь побольше. Кодом, или через конфиг:

    <system.net>
     <connectionManagement>
       <add address="*" maxconnection="8"/>
     </connectionManagement>
    </system.net>
    
    
    Если поможет - значит не всегда закрываешь соединения на клиенте.

    • Помечено в качестве ответа [S]hell 6 декабря 2010 г. 23:19
    6 декабря 2010 г. 13:13
  • Поменяй ServicePointManager.DefaultConnectionLimit с 2 на что-нибудь побольше. Кодом, или через конфиг:

     

    <system.net>
     <connectionManagement>
     <add address="*" maxconnection="8"/>
     </connectionManagement>
    </system.net>
    
    
    Если поможет - значит не всегда закрываешь соединения на клиенте.

    Спасибо большое, PashaPash! Действительно, после установки данного параметра, подключения больше не стали зависать.

    Подскажите, пожалуйста, в каких случаях нужно закрывать соединение. После каждого вызова метода с сервера?

    И закрывать его методом Close(), а дальше снова открывать как ' cli = new...' .


    6 декабря 2010 г. 23:24