Настройка службы WCF TCP в веб-приложении

Я боролся с этим в течение нескольких дней, буквально просматривая сотню статей, дающих частичные рекомендации о том, как настроить службу WCF TCP в веб-приложении. Если кто-то может мне помочь, я сделаю этот вопросполный руководство.

Текущее состояние

Соединение net.tcp работает на моей машине для разработки. Он также работает локально после развертывания на Windows Server 2008 R2. Тем не менее, он не работает удаленно, хотя можно удаленно подключиться к порту 808 на сервере. Прокрутите до конца вопроса для деталей. Пожалуйста, помоги, если можешь.

Я создам новый вопрос для этой детали и дополню этот вопрос ответом, если получу из этого результат.

Код

я создалServerHubService.svc со следующим содержанием:

namespace Manage.SignalR
{
    [ServiceContract]
    public class ServerHubService
    {
        [OperationContract]
        public void UpdateServerStatus(string serverStatus)
        {
            // Do something
        }
    }
}

Настройка приложения, на котором размещен сервис

Следуя онлайн-руководству, я добавил следующее в свой Web.config (я пробовал МНОГИЕ различные варианты). Это Web.config веб-приложения, в котором размещается служба, к которой я позже хочу подключиться с помощью TCP.

<configuration>
  <system.serviceModel>
    <services>
      <service behaviorConfiguration="ServerHubBehavior"
      name="Manage.SignalR.ServerHubService">
        <endpoint address=""
              binding="netTcpBinding"
              bindingConfiguration="portSharingBinding"
              name="MyServiceEndpoint"
              contract="Manage.SignalR.ServerHubService">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>

        <endpoint address="mex"
              binding="mexTcpBinding"
              bindingConfiguration=""
              name="MyServiceMexTcpBidingEndpoint"
              contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="net.tcp://test.mydomain.com:808/SignalR/ServerHubService.svc" />
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="ServerHubBehavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings>
      <netTcpBinding>
        <binding name="portSharingBinding" portSharingEnabled="true"/>
      </netTcpBinding>
    </bindings>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"
      minFreeMemoryPercentageToActivateService="0" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
</configuration>

httpGetEnabled="true" важно, потому что в противном случае вы не можете создать ссылку на службу.

Настройка сервера, на котором работает веб-приложение

Я устанавливаю это на моей машине для разработки, на которой установлен IIS 7.5

Я прочитал, что IIS Express (встроенный в Visual Studio) не поддерживает net.tcp, поэтому я настроил новый веб-сайт в IIS 7.5 с использованием .NET 4.5, который имеет привязку net.tcp

Я также зашел в Расширенные настройки для веб-сайта и установил Включенные протоколы вhttp,net.tcp

Я удостоверился, что функция Windows Non-HTTP Activation включена (и перезапущена). Это функция Windows, поэтому найдите «Включение или отключение функций Windows», чтобы найти это.

Подтверждение запуска веб-приложения

Сайт отлично работает для остальной части веб-приложения. Я настроил test.mydomain.com, чтобы он указывал на 127.0.0.1 в моемhosts файл. Я могу даже посетитьhttp://test.mydomain.com/SignalR/ServerHubService.svc и он покажет мне красивую автоматически сгенерированную страницу из .NET, объясняющую, как использовать этот сервис.

Все идет нормально.

Страница, сгенерированная .NET, говорит мне использовать этот адрес для создания соединения с моим сервисом:

net.tcp://computername/SignalR/ServerHubService.svc/mex

Попытка подключиться к услуге в качестве клиента

Если вы не помните, чтобы установитьhttpGetEnabled="true" вы получите сообщение об ошибке при попытке создать ссылку на службу. Если вы используете тестовый клиент WCF (также включенный в Visual Studio) и не установили httpGetEnabled, вы получите сообщение об ошибке, подобное следующему:

Ошибка: невозможно получить метаданные из net.tcp: //computername/SignalR/ServerHubService.svc/mex

Если это служба Windows (R) Communication Foundation, к которой у вас есть доступ, убедитесь, что вы включили публикацию метаданных по указанному адресу. Для получения справки о включении публикации метаданных, пожалуйста, обратитесь к документации MSDN по адресуhttp://go.microsoft.com/fwlink/?LinkId=65455.WS-Metadata

URI ошибки Exchange: net.tcp: //computername/SignalR/ServerHubService.svc/mex Метаданные содержат ссылку, которая не может быть разрешена: 'net.tcp: //computername/SignalR/ServerHubService.svc/mex'. Не удалось подключиться к net.tcp: //computername/SignalR/ServerHubService.svc/mex. Попытка подключения продолжалась в течение промежутка времени 00: 00: 04.0032289.

Код ошибки TCP 10061: не удалось установить соединение, поскольку целевая машина активно отказывала ему [2001: 0: 4137: 9e76: c81: a4c: a547: b2fd]: 808. Невозможно установить соединение, поскольку целевая машина активно отказывала в этом [2001: 0: 4137: 9e76: c81: a4c: a547: b2fd]: 808

Однако, если вы сделали все, как указано выше, вы сможете добавить ссылку на сервис.

Вызов методов в сервисе

При попытке вызвать простой метод Hello World в службе из тестового клиента WCF он возвращает следующую ошибку:

Не удалось подключиться к net.tcp: //computername/SignalR/ServerHubService.svc. Попытка подключения продолжалась в течение промежутка времени 00: 00: 04.0002288. Код ошибки TCP 10061: Соединение не может быть установлено, потому что целевой компьютер активно отказал ему.

Это внутренняя трассировка стека, которая включена в сообщение об ошибке:

Невозможно установить соединение, поскольку целевая машина активно отказывала в этом [2001: 0: 5ef5: 79fb: 3884: a: a547: b2fd]: 808 в System.Net.Sockets.Socket.DoConnect (EndPoint endPointSnapshot, SocketAddress socketAddress) в системе .Net.Sockets.Socket.Connect (EndPoint remoteEP) в System.ServiceModel.Channels.SocketConnectionInitiator.Connect (Uri uri, TimeSpan timeout)

Если вы используетеnetstat -an |find /i "listening" чтобы увидеть, что ничего не прослушивается на порте 808, возможно, потому что служба адаптера прослушивателя Net.Tcp не работает.

подтверждение

Вызов проходит, но требуется подтверждение, прежде чем он может быть объявлен успешным. Мне нужно подтвердить, что это на самом деле вызов net.tcp через порт 808, а не вызов конечной точки http. Я пытаюсь сделать это с Wireshark, но он не появляется, вероятно, потому что это звонок, происходящий с и на мою локальную машину.

развертывание

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

Он не работает после публикации в Windows Server 2008 R2. Это дает общееSocketException: An existing connection was forcibly closed by the remote host.

Он хорошо работает локально на сервере, но не работает удаленно.

Вот контрольный список, используемый для проверки сервера:

ЭтоNet.Tcp Listener Adapter служба работает? даЯвляется ли сайт IIS привязанным кnet.tcp установлен в808:*? даВключены ли протоколы в разделе «Дополнительные параметры» для сайта в IIS, установленного наhttp,net.tcp? даСервер прослушивает порт 808? Да, проверил сnetstat -an |find /i "listening"Порт 808 открыт в брандмауэре? Да.Брандмауэр на сервере отключен.Я могу telnet к серверу на порт 808 снаружи сtelnet mydomain.com 808В конфигурации службы на сервере было подтверждено следующее:baseAddress настроен наnet.tcp://mydomain.com:808/SignalR/ServerHubService.svcЭто былоlocalhost раньше, но изменился наmydomain.com после того, как он не работал на сервере:<identity><dns value="mydomain.com" /></identity>Он был протестирован с клиентом локально на сервере и на другом сервере. Оба могут подключиться к порту 808 через telnet, и оба выдают одно и то же сообщение об ошибке.

Какая конфигурация может отсутствовать на сервере? Я так близко к цели. Пожалуйста, помогите мне в устранении неполадок и завершите вопрос.

Вот конфигурация клиента на сервере, вызывающем сервис:

<system.serviceModel>
  <bindings>
    <netTcpBinding>
      <binding name="MyServiceEndpoint" />
    </netTcpBinding>
  </bindings>
  <client>
    <endpoint address="net.tcp://mydomain.com:808/SignalR/ServerHubService.svc"
      binding="netTcpBinding" bindingConfiguration="MyServiceEndpoint"
      contract="ServerHubService.ServerHubService" name="MyServiceEndpoint">
      <identity>
        <dns value="mydomain.com" />
      </identity>
    </endpoint>
  </client>
</system.serviceModel>

Я также попытался без 808, настроенного в конечной точке, поскольку по слухам это порт по умолчанию для соединений net.tcp. Однако это все равно дает тот же результат.

Вместо того, чтобы делать много вещей случайно, возможно, хороший вопрос: как отладить что-то подобное?Могу ли я установить на любой сервер программу, которая точно скажет мне, ПОЧЕМУ этот вызов блокируется?

Если Wireshark настроен следующим образом, можно посмотреть на вызов, поступающий на сервер через порт 808, и определить, почему вызов не работает. Однако я не знаю, как это проанализировать в настоящее время.

Удачи

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

Ответы на вопрос(7)

Ваш ответ на вопрос