Приветствую!
Написал WCF — based клиент — сервер, работающие через TCP — соединение.
Сервер работает как виндовый сервис, клиент подключается к нему и передает сообщения — в общем,
это просто некоторая модификация чата. сервер — синглтон.
обнаружилась засада, с которой я борюсь уже пару дней: если клиент запущен на машине, которая не находится в моем домене (windows — домене), то она не соединяется с сервером с такой вот безинформативной ошибкой "Подключение к сокету было прервано. Возможно, это вызвано ошибкой обработки сообщения, превышением времени ожидания на удаленном узле или проблемой с выделенным сетевым ресурсом. Тайм-аут локального сокета: "00:00:59.7661950"."
Таймаут соединения не имеет к реальной ошибке никакого отношения, ошибка возникает мгновенно после запуска клиента.
соединение telnet-ом к нужному порту устанавливается без проблем.
То, что ошибка возникает при коннекте машин, находящихся в разных доменах, наводит на мысль о шифровании и SSPI, но я сделал на клиенте и сервере все для отсутствия какой либо security, вот конфиги клиента и сервера: клиент:
полный текст ошибки:
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, Вы писали:
A>Версии ОС? Отключение файрвола на сервере помогает?
Все самое банальное: клиент работает на машине с WinXP или Win 7 Professional, (примечание: клиент написан на .NET 3.5)
Сервер — работает на Windows server 2003, сервер написан на .Net 4.0
В процессе экспериментов все файерволы были отключены, да и соединение с telnet'а устанавливается.
Сегодня продолжу эксперименты, надеюсь на свежие идеи!
Re[3]: WCF over TCP: проблема при вызове с удаленной машины
SLH>>[/code]
SLH>>Какие нибудь соображения? А>А что если перебросить на 80 порт?
Да не в портах тут дело.
явно что то недокручено с шифрованием.
Кроме того, если тестировать на восьмидесятом порту я и могу, то на production сервисе он просто занят IIS ом.
Как этому гребаному WCF объяснить, что все его навороты не нужны, а нужно тупое TCP — соединение, я не знаю.
уже думаю похерить все написанное и переписать на Remoting.
Re[3]: WCF over TCP: проблема при вызове с удаленной машины
Здравствуйте, SteeLHeaD, Вы писали:
SLH>Как этому гребаному WCF объяснить, что все его навороты не нужны, а нужно тупое TCP — соединение, я не знаю. SLH>уже думаю похерить все написанное и переписать на Remoting.
Здравствуйте, adontz.
Спасибо Вам, вы мне помогали еще месяц назад, когда я только начинал экспериментировать с WCF.
На HTTP не получается по причине того, что нужен callback — у меня события приходят со стороны сервера.
Ну и на TCP все быстро работает, что в этой задаче немаловажно.
Теперь про результаты сегодняшних экспериментов:
пробовал коннектиться к серверу с разных машин.
Помеянл версию фреймворка на 4.0 на клиенте и на сервере.
Выяснилось:
со "своей" машины устанавливается нормальное TCP соединение.
С "чужой" машины можно приконнектиться telnet'ом, и соединение продержится несколько секунд.
Но если клиент коннектится с "чужой" машины, то сервер практически мгновенно (за дооли секунды)
принудительно рвет соединение.
Все это наводит меня на мысли об авторизации — что то я там еще не отключил.
В первом моем сообщениии — полные конфиги клиента и сервера.
Не хочется из за непраильной конфигурации полностью переписывать всю communication часть.
Так что если еще что то посоветуете — буду благодарен.
С уважением,
SH.
Re[5]: WCF over TCP: проблема при вызове с удаленной машины
HTTP поддерживает двусторонний обмен сообщениями. Я просто думаю, что бинарный протокол между версиями мог немного поменяться. Поэтому либо попробуйте с одной и той же версией фреймворка, либо попробуйте SOAP/HTTP.
Здравствуйте, fdn721, Вы писали:
F>У WCF есть фатальный недостаток, время на машинах должно быть одинаковым. F>Если оно расходится на некоторое значение (по моему 5 минут), то всё перестаёт работать.
Господа,
спасибо за ваши советы,
я так понимаю, что никто в мире пока эту ситуацию разруливать не научился.
Видимо, придется выбросить 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 тыс
Попробовал сменить протокол на wsDualHttpBinding
НИчего не меняется — схема секьюрити для двунаправленных каналов одинакова.
независимо от того, netTcp это или wsDualHttpBinding.
Соединение не открывается.
причем уже на любых двух машинах.
в общем, решено, переписываю на remoting.
Re: WCF over TCP: проблема при вызове с удаленной машины
Здравствуйте, SteeLHeaD, Вы писали:
SLH>Могу добавить исходники клиента и сервера, но повторяю, что для машин в одном домене все работает идеально. SLH>А если не в домене — клиент не подключается к серверу, это видно по логам сервера. SLH>у меня уже руки опускаются, потому что не понимаю, в какую сторону копать. SLH>Какие нибудь соображения?
Во многих случаях с wcf, когда непонятно что происходит и как вообще заставить это работать, помогает включение трассировки wcf. Для этого в конфиг нужно добавить примерно следующие строки:
Здравствуйте, anton_t, спасибо за инфо по трассировке!
я к этому времени все это уже прочитал, но тем не менее.
что происходит — в общем понятно, не срабатывает авторизация.
как её включить ту или иную — видимо, просто не хватает готовых работающих примеров конфиг файлов в стиле "а теперь, дети, смотрите: чтобы включить авторизацию по виндовому логину и паролю — напишите вот эти волшебные строчки..."
Спасибо еще раз всем подключившимся к обсуждению.