WCF over TCP: проблема при вызове с удаленной машины
От: SteeLHeaD  
Дата: 31.05.11 21:19
Оценка: -1
Приветствую!
Написал WCF — based клиент — сервер, работающие через TCP — соединение.
Сервер работает как виндовый сервис, клиент подключается к нему и передает сообщения — в общем,
это просто некоторая модификация чата. сервер — синглтон.
обнаружилась засада, с которой я борюсь уже пару дней: если клиент запущен на машине, которая не находится в моем домене (windows — домене), то она не соединяется с сервером с такой вот безинформативной ошибкой "Подключение к сокету было прервано. Возможно, это вызвано ошибкой обработки сообщения, превышением времени ожидания на удаленном узле или проблемой с выделенным сетевым ресурсом. Тайм-аут локального сокета: "00:00:59.7661950"."
Таймаут соединения не имеет к реальной ошибке никакого отношения, ошибка возникает мгновенно после запуска клиента.
соединение telnet-ом к нужному порту устанавливается без проблем.
То, что ошибка возникает при коннекте машин, находящихся в разных доменах, наводит на мысль о шифровании и SSPI, но я сделал на клиенте и сервере все для отсутствия какой либо security, вот конфиги клиента и сервера:
клиент:


  <system.serviceModel>
    <bindings>
      <netTcpBinding>
        <binding name="TcpBinding" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions" hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="524288" maxBufferSize="65536" maxConnections="10" maxReceivedMessageSize="65536">
          <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
          <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false"/>
          <security mode="None">
            <message clientCredentialType="None"/>
            <transport clientCredentialType="None" protectionLevel="None"/>
          </security>
        </binding>
      </netTcpBinding>
    </bindings>
    <client>
      <endpoint address="net.tcp://192.168.1.2:8000/CallService/service" binding="netTcpBinding" bindingConfiguration="TcpBinding" contract="CallService" name="TcpBinding">
        <identity>
          <userPrincipalName value="davydov@office.local"/>
        </identity>
      </endpoint>
    </client>
  </system.serviceModel>


сервер:

    <system.serviceModel>
        <behaviors>
            <serviceBehaviors>
                <behavior name="MetadataBehavior">
                    <serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:8001/CallService/mex"/>
                </behavior>
      </serviceBehaviors>
        </behaviors>
        <services>
            <service behaviorConfiguration="MetadataBehavior" name="CallServer.CallService">
                <endpoint address="service" binding="netTcpBinding" contract="CallServer.ICallService" name="TcpBinding"/>
                <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" name="MexBinding"/>
                <host>
                    <baseAddresses>
                        <add baseAddress="net.tcp://localhost:8000/CallService/"/>
                        <add baseAddress="http://localhost:8001/CallService/"/>
                    </baseAddresses>
                </host>
            </service>
        </services>
    <bindings>
      <netTcpBinding>
        <binding name="TcpBinding" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions" hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="524288" maxBufferSize="65536" maxConnections="10" maxReceivedMessageSize="65536">
          <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
          <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false"/>
          <security mode="None">
            <message clientCredentialType="None"/>
            <transport clientCredentialType="None" protectionLevel="None"/>
          </security>
        </binding>
      </netTcpBinding>
    </bindings>
    </system.serviceModel>


полный текст ошибки:
message: "Подключение к сокету было прервано. Возможно, это вызвано ошибкой обработки сообщения, превышением времени ожидания на удаленном узле или проблемой с выделенным сетевым ресурсом. Тайм-аут локального сокета: "00:00:59.7661950"."

source: mscorlib

stack trace:

Server stack trace: 
   в System.ServiceModel.Channels.SocketConnection.ReadCore(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout, Boolean closing)
   в System.ServiceModel.Channels.SocketConnection.Read(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout)
   в System.ServiceModel.Channels.DelegatingConnection.Read(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout)
   в System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.SendPreamble(IConnection connection, ArraySegment`1 preamble, TimeoutHelper& timeoutHelper)
   в System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.DuplexConnectionPoolHelper.AcceptPooledConnection(IConnection connection, TimeoutHelper& timeoutHelper)
   в System.ServiceModel.Channels.ConnectionPoolHelper.EstablishConnection(TimeSpan timeout)
   в System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.OnOpen(TimeSpan timeout)
   в System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
   в System.ServiceModel.Channels.ServiceChannel.OnOpen(TimeSpan timeout)
   в System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)

Exception rethrown at [0]: 
   в System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
   в System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
   в System.ServiceModel.ICommunicationObject.Open(TimeSpan timeout)
   в System.ServiceModel.ClientBase`1.System.ServiceModel.ICommunicationObject.Open(TimeSpan timeout)
   в System.ServiceModel.ClientBase`1.Open()
   в CallClient.CCallClient.tryConnectToServer()
15:57:41 GetGlobals.Контрагенты.Get(): точка перед return
15:57:41 GetGlobals.Контрагенты.Get(): return 28089
15:57:42 GetGlobals.События.get: начинаем запрос событий
15:57:42 GetGlobals.События.get: второй варинат (RepList.событиеRepository.GetNew)
15:57:45 СобытиеRepository.GetNew: lat=15:26, return: 4 элементов
15:57:45 GetGlobals.События.get: вытащили 4 событий
15:58:12 CCallClient.tryConnectToServer(): Подключение к сокету было прервано. Возможно, это вызвано ошибкой обработки сообщения, превышением времени ожидания на удаленном узле или проблемой с выделенным сетевым ресурсом. Тайм-аут локального сокета: "00:00:57.0540570".;mscorlib;
Server stack trace: 
   в System.ServiceModel.Channels.SocketConnection.ReadCore(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout, Boolean closing)
   в System.ServiceModel.Channels.SocketConnection.Read(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout)
   в System.ServiceModel.Channels.DelegatingConnection.Read(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout)
   в System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.SendPreamble(IConnection connection, ArraySegment`1 preamble, TimeoutHelper& timeoutHelper)
   в System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.DuplexConnectionPoolHelper.AcceptPooledConnection(IConnection connection, TimeoutHelper& timeoutHelper)
   в System.ServiceModel.Channels.ConnectionPoolHelper.EstablishConnection(TimeSpan timeout)
   в System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.OnOpen(TimeSpan timeout)
   в System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
   в System.ServiceModel.Channels.ServiceChannel.OnOpen(TimeSpan timeout)
   в System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)

Exception rethrown at [0]: 
   в System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
   в System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
   в System.ServiceModel.ICommunicationObject.Open(TimeSpan timeout)
   в System.ServiceModel.ClientBase`1.System.ServiceModel.ICommunicationObject.Open(TimeSpan timeout)
   в System.ServiceModel.ClientBase`1.Open()
   в CallClient.CCallClient.tryConnectToServer()

Могу добавить исходники клиента и сервера, но повторяю, что для машин в одном домене все работает идеально.
А если не в домене — клиент не подключается к серверу, это видно по логам сервера.
у меня уже руки опускаются, потому что не понимаю, в какую сторону копать.
Какие нибудь соображения?
Re: WCF over TCP: проблема при вызове с удаленной машины
От: adontz Грузия http://adontz.wordpress.com/
Дата: 31.05.11 21:25
Оценка:
Здравствуйте, SteeLHeaD, Вы писали:

Версии ОС? Отключение файрвола на сервере помогает?
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[2]: WCF over TCP: проблема при вызове с удаленной машины
От: SteeLHeaD  
Дата: 01.06.11 02:25
Оценка:
Здравствуйте, adontz, Вы писали:

A>Версии ОС? Отключение файрвола на сервере помогает?


Все самое банальное: клиент работает на машине с WinXP или Win 7 Professional, (примечание: клиент написан на .NET 3.5)
Сервер — работает на Windows server 2003, сервер написан на .Net 4.0
В процессе экспериментов все файерволы были отключены, да и соединение с telnet'а устанавливается.
Сегодня продолжу эксперименты, надеюсь на свежие идеи!
Re[3]: WCF over TCP: проблема при вызове с удаленной машины
От: adontz Грузия http://adontz.wordpress.com/
Дата: 01.06.11 02:35
Оценка:
Здравствуйте, SteeLHeaD, Вы писали:

Эмм... а нельзя их на одной версии фреймворка запустить?
A journey of a thousand miles must begin with a single step © Lau Tsu
Re: WCF over TCP: проблема при вызове с удаленной машины
От: Аноним  
Дата: 01.06.11 04:22
Оценка:
Здравствуйте, SteeLHeaD, Вы писали:

SLH>
SLH>  <system.serviceModel>

SLH>      <endpoint address="net.tcp://192.168.1.2:8000/CallService/service" binding="netTcpBinding" SLH>


SLH>[/code]


SLH>Какие нибудь соображения?

А что если перебросить на 80 порт?
Re[2]: WCF over TCP: проблема при вызове с удаленной машины
От: SteeLHeaD  
Дата: 01.06.11 10:59
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, SteeLHeaD, Вы писали:


SLH>>
SLH>>  <system.serviceModel>

SLH>>      <endpoint address="net.tcp://192.168.1.2:8000/CallService/service" binding="netTcpBinding" SLH>


SLH>>[/code]


SLH>>Какие нибудь соображения?

А>А что если перебросить на 80 порт?
Да не в портах тут дело.
явно что то недокручено с шифрованием.
Кроме того, если тестировать на восьмидесятом порту я и могу, то на production сервисе он просто занят IIS ом.
Как этому гребаному WCF объяснить, что все его навороты не нужны, а нужно тупое TCP — соединение, я не знаю.
уже думаю похерить все написанное и переписать на Remoting.
Re[3]: WCF over TCP: проблема при вызове с удаленной машины
От: adontz Грузия http://adontz.wordpress.com/
Дата: 01.06.11 15:34
Оценка:
Здравствуйте, SteeLHeaD, Вы писали:

SLH>Как этому гребаному WCF объяснить, что все его навороты не нужны, а нужно тупое TCP — соединение, я не знаю.

SLH>уже думаю похерить все написанное и переписать на Remoting.

А на HTTP никак?
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[4]: WCF over TCP: проблема при вызове с удаленной машины
От: SteeLHeaD  
Дата: 01.06.11 17:01
Оценка:
A>А на HTTP никак?

Здравствуйте, adontz.
Спасибо Вам, вы мне помогали еще месяц назад, когда я только начинал экспериментировать с WCF.
На HTTP не получается по причине того, что нужен callback — у меня события приходят со стороны сервера.
Ну и на TCP все быстро работает, что в этой задаче немаловажно.
Теперь про результаты сегодняшних экспериментов:
пробовал коннектиться к серверу с разных машин.
Помеянл версию фреймворка на 4.0 на клиенте и на сервере.
Выяснилось:
со "своей" машины устанавливается нормальное TCP соединение.
С "чужой" машины можно приконнектиться telnet'ом, и соединение продержится несколько секунд.
Но если клиент коннектится с "чужой" машины, то сервер практически мгновенно (за дооли секунды)
принудительно рвет соединение.
Все это наводит меня на мысли об авторизации — что то я там еще не отключил.
В первом моем сообщениии — полные конфиги клиента и сервера.
Не хочется из за непраильной конфигурации полностью переписывать всю communication часть.
Так что если еще что то посоветуете — буду благодарен.

С уважением,
SH.
Re[5]: WCF over TCP: проблема при вызове с удаленной машины
От: adontz Грузия http://adontz.wordpress.com/
Дата: 01.06.11 17:52
Оценка:
Здравствуйте, SteeLHeaD, Вы писали:

HTTP поддерживает двусторонний обмен сообщениями. Я просто думаю, что бинарный протокол между версиями мог немного поменяться. Поэтому либо попробуйте с одной и той же версией фреймворка, либо попробуйте SOAP/HTTP.

Попробуйте Service Trace Viewer Tool
A journey of a thousand miles must begin with a single step © Lau Tsu
Re: WCF over TCP: проблема при вызове с удаленной машины
От: fdn721  
Дата: 02.06.11 04:37
Оценка:
Здравствуйте, SteeLHeaD, Вы писали:

У WCF есть фатальный недостаток, время на машинах должно быть одинаковым.

Если оно расходится на некоторое значение (по моему 5 минут), то всё перестаёт работать.
Re[2]: WCF over TCP: проблема при вызове с удаленной машины
От: SteeLHeaD  
Дата: 02.06.11 06:04
Оценка:
Здравствуйте, fdn721, Вы писали:

F>У WCF есть фатальный недостаток, время на машинах должно быть одинаковым.

F>Если оно расходится на некоторое значение (по моему 5 минут), то всё перестаёт работать.

Спасибо за совет,
проверил — нет, не расходится.
Re: Нет идей?
От: SteeLHeaD  
Дата: 02.06.11 06:08
Оценка:
Господа,
спасибо за ваши советы,
я так понимаю, что никто в мире пока эту ситуацию разруливать не научился.
Видимо, придется выбросить WCF и переписать все на remoting.
я конечно попробую еще побарахтаться, ( переписать транспорт на HTTP и т.п.),
но это уже явно "не то" решение, которое подразумевалось.
Если у кого то появится работающий пример WCF с TCP транспортом — это будет здорово.
Re[2]: Нет идей?
От: Аноним  
Дата: 02.06.11 09:57
Оценка:
Здравствуйте, SteeLHeaD, Вы писали:

SLH>Господа,

SLH>спасибо за ваши советы,
SLH>я так понимаю, что никто в мире пока эту ситуацию разруливать не научился.
SLH>Видимо, придется выбросить WCF и переписать все на remoting.
SLH>я конечно попробую еще побарахтаться, ( переписать транспорт на HTTP и т.п.),
SLH>но это уже явно "не то" решение, которое подразумевалось.
SLH>Если у кого то появится работающий пример WCF с TCP транспортом — это будет здорово.

скажу по секрету, что у WCF общее кол-во конфигураций разных параметров превышает 10 тыс
Re: WCF over TCP: результаты экспериментов
От: SteeLHeaD  
Дата: 03.06.11 20:32
Оценка:
Попробовал сменить протокол на wsDualHttpBinding
НИчего не меняется — схема секьюрити для двунаправленных каналов одинакова.
независимо от того, netTcp это или wsDualHttpBinding.
Соединение не открывается.
причем уже на любых двух машинах.
в общем, решено, переписываю на remoting.
Re: WCF over TCP: проблема при вызове с удаленной машины
От: anton_t Россия  
Дата: 04.06.11 11:05
Оценка:
Здравствуйте, SteeLHeaD, Вы писали:

SLH>Могу добавить исходники клиента и сервера, но повторяю, что для машин в одном домене все работает идеально.

SLH>А если не в домене — клиент не подключается к серверу, это видно по логам сервера.
SLH>у меня уже руки опускаются, потому что не понимаю, в какую сторону копать.
SLH>Какие нибудь соображения?

Во многих случаях с wcf, когда непонятно что происходит и как вообще заставить это работать, помогает включение трассировки wcf. Для этого в конфиг нужно добавить примерно следующие строки:

<configuration>
...
   <system.diagnostics>
      <sources>
            <source name="System.ServiceModel" 
                    switchValue="Information, ActivityTracing"
                    propagateActivity="true">
            <listeners>
               <add name="traceListener" 
                   type="System.Diagnostics.XmlWriterTraceListener" 
                   initializeData= "c:\log\Traces.svclog" />
            </listeners>
         </source>
      </sources>
   </system.diagnostics>
...
</configuration>


Трассировка будет записываться в файл c:\log\Traces.svclog.
Re[2]: WCF over TCP: проблема при вызове с удаленной машины
От: SteeLHeaD  
Дата: 06.06.11 10:16
Оценка:
Здравствуйте, anton_t, спасибо за инфо по трассировке!
я к этому времени все это уже прочитал, но тем не менее.
что происходит — в общем понятно, не срабатывает авторизация.
как её включить ту или иную — видимо, просто не хватает готовых работающих примеров конфиг файлов в стиле "а теперь, дети, смотрите: чтобы включить авторизацию по виндовому логину и паролю — напишите вот эти волшебные строчки..."
Спасибо еще раз всем подключившимся к обсуждению.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.