Konfigurowanie usługi WCF TCP w aplikacji internetowej

Walczę z tym od wielu dni, dosłownie przechodząc przez sto artykułów, podając częściowe wskazówki, jak skonfigurować usługę WCF TCP w aplikacji internetowej. Jeśli ktoś może mi pomóc, zadaję to pytaniekompletny wytyczna.

Aktualny stan

Połączenie net.tcp działa na moim komputerze programistycznym. Działa również lokalnie po wdrożeniu w systemie Windows Server 2008 R2. Nie działa jednak zdalnie, nawet jeśli zdalnie można połączyć się z portem 808 na serwerze. Przewiń do dołu pytania, aby uzyskać szczegółowe informacje. Pomóż, jeśli możesz.

Stworzę nowe pytanie dotyczące tego szczegółu i zaktualizuję to pytanie odpowiedzią, jeśli otrzymam z tego wynik.

Kod

ja stworzyłemServerHubService.svc o następującej treści:

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

Konfiguracja aplikacji obsługującej usługę

Po samouczku online dodałem następujące elementy do mojego Web.config (wypróbowałem WIELE różnych odmian). To jest Web.config aplikacji internetowej obsługującej usługę, z którą później chcę się połączyć za pomocą 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" jest ważne, ponieważ w przeciwnym razie nie można utworzyć odwołania do usługi do usługi.

Konfiguracja serwera, na którym działa aplikacja internetowa

Ustawiam to na moim komputerze programistycznym z IIS 7.5

Czytałem, że IIS Express (wbudowany w Visual Studio) nie obsługuje net.tcp, więc utworzyłem nową stronę w IIS 7.5 za pomocą .NET 4.5 i ma powiązanie net.tcp

Poszedłem także do ustawień zaawansowanych witryny i ustawiłem opcję Włączone protokoły nahttp,net.tcp

Upewniłem się, że aktywacja funkcji Windows nie-HTTP jest włączona (i zrestartowana). Jest to funkcja systemu Windows, więc szukaj „Włącz lub wyłącz funkcje systemu Windows”, aby to znaleźć.

Potwierdzenie, że aplikacja internetowa jest uruchomiona

Strona działa dobrze dla reszty aplikacji internetowej. Skonfigurowałem test.mydomain.com, aby wskazywało na 127.0.0.1 w moimhosts plik. Mogę nawet odwiedzićhttp://test.mydomain.com/SignalR/ServerHubService.svc i pokaże mi ładną, automatycznie wygenerowaną stronę z .NET, wyjaśniającą, jak korzystać z tej usługi.

Jak na razie dobrze.

Strona wygenerowana przez .NET każe mi użyć tego adresu do wygenerowania połączenia z moją usługą:

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

Próbuję połączyć się z usługą jako klient

Jeśli nie pamiętasz, aby ustawićhttpGetEnabled="true" pojawi się błąd podczas próby utworzenia odwołania do usługi do niego. Jeśli korzystasz z klienta testowego WCF (również narzędzia zawartego w Visual Studio) i nie ustawiłeś httpGetEnabled, pojawi się następujący błąd:

Błąd: Nie można uzyskać metadanych z net.tcp: //nazwa_komputera/SignalR/ServerHubService.svc/mex

Jeśli jest to usługa Windows (R) Communication Foundation, do której masz dostęp, sprawdź, czy masz włączone publikowanie metadanych pod określonym adresem. Aby uzyskać pomoc dotyczącą publikowania metadanych, zapoznaj się z dokumentacją MSDN pod adresemhttp://go.microsoft.com/fwlink/?LinkId=65455.WS-Metadata

Exchange Error URI: net.tcp: //computername/SignalR/ServerHubService.svc/mex Metadane zawierają odniesienie, którego nie można rozwiązać: 'net.tcp: //computername/SignalR/ServerHubService.svc/mex'. Nie można połączyć się z net.tcp: //nazwa_komputera/SignalR/ServerHubService.svc/mex. Próba połączenia trwała przez okres 00: 00: 04.0032289.

Kod błędu TCP 10061: Nie można nawiązać połączenia, ponieważ komputer docelowy aktywnie go odmówił [2001: 0: 4137: 9e76: c81: a4c: a547: b2fd]: 808. Nie można nawiązać połączenia, ponieważ komputer docelowy aktywnie go odmówił [2001: 0: 4137: 9e76: c81: a4c: a547: b2fd]: 808

Jeśli jednak zrobiłeś wszystko jak powyżej, powinieneś być w stanie dodać odwołanie do usługi.

Metody wywoływania w usłudze

Podczas próby wywołania prostej metody Hello World w usłudze od klienta testowego WCF zwraca następujący błąd:

Nie można połączyć się z net.tcp: //computername/SignalR/ServerHubService.svc. Próba połączenia trwała przez okres 00: 00: 04.0002288. Kod błędu TCP 10061: Nie można nawiązać połączenia, ponieważ komputer docelowy aktywnie go odmówił.

Jest to wewnętrzny stos stosu, który zawiera błąd:

Nie można nawiązać połączenia, ponieważ komputer docelowy aktywnie go odmówił [2001: 0: 5ef5: 79fb: 3884: a: a547: b2fd]: 808 w System.Net.Sockets.Socket.DoConnect (EndPointSunapshot, SocketAddress socketAddress) w System .Net.Sockets.Socket.Connect (EndPoint remoteEP) w System.ServiceModel.Channels.SocketConnectionInitiator.Connect (Uri uri, TimeSpan timeout)

Jeśli użyjesznetstat -an |find /i "listening" aby zobaczyć, że nic nie nasłuchuje na porcie 808, prawdopodobnie dlatego, że usługa adaptera nasłuchującego Net.Tcp nie jest uruchomiona.

Potwierdzenie

Połączenie trwa teraz, ale zanim zostanie uznane za sukces, potrzebne jest potwierdzenie. Muszę potwierdzić, że w rzeczywistości jest to wywołanie net.tcp na porcie 808, a nie połączenie w punkcie końcowym http. Próbuję to zrobić za pomocą Wiresharka, ale nie pojawia się, prawdopodobnie dlatego, że jest to wywołanie z mojej lokalnej maszyny.

Rozlokowanie

Ostatnim wyzwaniem do pokonania byłoby wdrożenie tego na serwerze sieciowym, zapewniając, że to, co działa na maszynie programistycznej, działa również na serwerze WWW.

Nie działa po opublikowaniu w systemie Windows Server 2008 R2. Daje to wspólneSocketException: An existing connection was forcibly closed by the remote host.

Działa dobrze lokalnie na serwerze, ale nie działa zdalnie.

Oto lista kontrolna używana do sprawdzenia serwera:

JestNet.Tcp Listener Adapter usługa działa? takCzy witryna IIS jest powiązana znet.tcp Ustawić808:*? takCzy włączone są protokoły w Ustawieniach zaawansowanych dla witryny w usługach IIS ustawionych nahttp,net.tcp? takCzy serwer nasłuchuje na porcie 808? Tak, sprawdzonenetstat -an |find /i "listening"Czy port 808 jest otwarty w zaporze? Tak.Zapora jest wyłączona na serwerze.Mogę telnetować się do serwera na porcie 808 z zewnątrz za pomocątelnet mydomain.com 808W konfiguracji usługi na serwerze potwierdzono, co następuje:baseAddress jest dostosowany donet.tcp://mydomain.com:808/SignalR/ServerHubService.svcTo byłolocalhost wcześniej, ale zmieniono namydomain.com po tym, jak nie działa na serwerze:<identity><dns value="mydomain.com" /></identity>Został przetestowany z klientem lokalnie na serwerze i na innym serwerze. Oba mogą połączyć się z portem 808 za pomocą telnetu i oba dają ten sam komunikat o błędzie.

Jakiej konfiguracji brakuje na serwerze? Jestem tak blisko celu. Pomóż mi rozwiązać ten problem i wypełnij pytanie.

Oto konfiguracja klienta na serwerze wywołująca usługę:

<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>

Próbowałem również bez 808 skonfigurowanego w punkcie końcowym, ponieważ podobno jest to domyślny port dla połączeń net.tcp. Jednak nadal daje ten sam rezultat.

Zamiast próbować wielu rzeczy losowo, dobrym pytaniem jest być może: Jak można debugować coś takiego?Czy mogę zainstalować program na dowolnym serwerze, który powie mi dokładnie DLACZEGO to połączenie jest blokowane?

Dzięki tak skonfigurowanemu Wiresharkowi można sprawdzić połączenie przychodzące na serwer na porcie 808 i ewentualnie określić, dlaczego połączenie nie działa. Nie mam jednak pojęcia, jak to teraz analizować.

Powodzenia

Zrezygnowałem i zaimplementowałem to w warstwie gniazda. Zadziałało natychmiast. Mam jednak nadzieję, że pomoże to komuś innemu. Ustawiam odpowiedź, ponieważ wiele problemów zostało rozwiązanych i ostatecznie zadziałało lokalnie, więc pozostały problem prawdopodobnie jest związany ze mną w określonym środowisku.

questionAnswers(7)

yourAnswerToTheQuestion