Mise en place du service TCP WCF dans une application web

j'ai lutté avec cela pendant des jours, en parcourant littéralement une centaine d'articles donnant des directives partielles sur la façon de mettre en place un service basé sur TCP WCF dans une application web. Si quelqu'un peut m'aider, je ferai de cette question une ligne directrice complète .

état Actuel

sur Le net.connexion tcp fonctionne sur ma machine de développement. Il fonctionne également localement après avoir été déployé dans un Windows Server 2008 R2. Cependant, il ne fonctionne pas à distance, même s'il est possible de telnet au port 808 sur le serveur à distance. Faites défiler vers le bas de la question pour plus de détails. S'il vous plaît aider si vous le pouvez.

je vais créer une nouvelle question pour ce détail et mettre à jour cette question avec la réponse si j'obtiens un résultat.

Code

j'ai créé ServerHubService.svc avec le contenu suivant:

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

Configuration de l'application hébergeant le service

suite à un tutoriel en ligne, j'ai ajouté ce qui suit à mon site web.config (j'ai essayé plusieurs variantes). C'est le Web.config de l'application Web hébergeant le service que je veux plus tard connecter avec 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" est important parce que sinon vous ne pouvez pas créer une référence de service à service.

Configuration du serveur où l'application web est en cours d'exécution

je mets en place ce sur ma machine de développement qui a IIS 7.5

j'ai lu que IIS Express (construit dans Visual Studio) ne supporte pas net.tcp, donc j'ai mis en place un nouveau site Web dans IIS 7.5 en utilisant .NET 4.5 et qui a un réseau.tcp liaison

bindings in IIS

je suis également allé à des paramètres avancés pour le site web et les Protocoles activés de http,net.tcp

j'ai veillé à ce que la fonctionnalité Windows Non-Activation HTTP soit activée (et redémarrée). C'est une Fonctionnalité de Windows donc chercher des "fonctionnalités Windows Activer ou désactiver" pour trouver cela.

enter image description here

confirmation que l'application web est en cours d'exécution

le site fonctionne très bien pour le reste de l'application web. J'installe test.mydomain.com pointer vers 127.0.0.1 dans mon fichier hosts . Je peux même visiter http://test.mydomain.com/SignalR/ServerHubService.svc et il me montrera une belle page générée automatiquement à partir de .NET, expliquant comment utiliser ce service.

pour l'instant tout va bien.

la page générée par .NET me dit d'utiliser cette adresse pour générer une connexion à mon service:

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

essayer de se connecter au service en tant que client

si vous ne vous souvenez pas de mettre httpGetEnabled="true" vous obtiendrez une erreur en essayant de créer une référence de service à elle. Si vous utilisez le Client Test de la WCF (également un outil inclus dans Visual Studio) et que vous n'avez pas configuré httpGetEnabled, vous obtiendrez une erreur du type:

erreur: Impossible d'obtenir des métadonnées de net.tcp://nom de l'ordinateur/SignalR/ServerHubService.svc / mex

S'il s'agit D'un service de la Fondation Windows (R) Communication auquel vous avoir accès, veuillez vérifier que vous avez activé la publication des métadonnées à l'adresse spécifiée. Pour obtenir de l'aide pour la publication de métadonnées, veuillez reportez-vous à la documentation du MSDN à l'adresse suivante: http://go.microsoft.com/fwlink/?LinkId=65455.WS-Metadata

erreur D'échange URI: net.tcp://nom de l'ordinateur/SignalR/ServerHubService.métadonnées svc/mex contient une référence qui ne peut être résolue: 'net.tcp://nom de l'ordinateur/SignalR/ServerHubService.svc / mex". Ne pouvait pas se connecter au net.tcp://nom de l'ordinateur/SignalR/ServerHubService.svc / mex. La tentative de connexion a duré pendant une période de temps de 00:00: 04.0032289.

code D'erreur TCP 10061: aucune connexion n'a pu être établie car la cible machine a activement refusé [2001:0:4137:9e76:c81:a4c:a547: b2fd]: 808. Aucune connexion n'a pu être établie car l'ordinateur cible activement refusé [2001: 0: 4137:9e76:c81:a4c:a547:b2fd]: 808

cependant, si vous avez fait tout comme ci-dessus, vous devriez être en mesure d'ajouter une référence au service.

l'Appel de méthodes dans le service

en essayant d'appeler une méthode Hello World simple dans le service du Client de Test de la WCF, il renvoie le suivant erreur:

ne pouvait pas se connecter à net.tcp://nom de l'ordinateur/SignalR/ServerHubService.svc. Connexion la tentative a duré pendant une période de temps de 00:00: 04.0002288. TCP code d'erreur 10061: Aucune connexion n'a pu être établie car l'ordinateur cible activement l'a refusé.

c'est le stactrace intérieur qui est inclus dans avec l'erreur:

aucune connexion n'a pu être établie parce que la cible la machine activement refusé [2001:0:5ef5:79fb:3884:: a547:b2fd]:808 à Système.Net.Douilles.Socket.DoConnect(EndPoint endPointSnapshot), SocketAddress socketAddress) Système.Net.Douilles.Socket.Connect (EndPoint remoteEP) à Système.ServiceModel.Canal.SocketConnectionInitiator.Connect (Uri) uri, plage de Temps (timeout)

si vous utilisez netstat -an |find /i "listening" pour voir que rien n'écoute sur le port 808, c'est probablement parce que le Net.Adaptateur D'Écoute Tcp le service n'est pas en cours d'exécution.

Confirmation

l'appel est passé maintenant, mais une certaine confirmation est nécessaire avant qu'il puisse être déclaré un succès. Je dois confirmer que c'est en fait net.tcp appelle sur le port 808 et pas vraiment un appel sur le terminal http. J'essaie de faire ça avec Wireshark, mais ça ne se voit pas, probablement parce que c'est un appel de et Vers ma machine locale.

déploiement

le dernier défi à relever serait de déployer cela sur un serveur web, en s'assurant que ce qui fonctionne sur la machine de développement, fonctionne aussi sur le serveur web.

il ne fonctionne pas après publier sur un serveur Windows 2008 R2. Il donne le commun SocketException: An existing connection was forcibly closed by the remote host .

fonctionne bien localement sur le serveur, mais ne fonctionne pas à distance.

Voici la liste de contrôle utilisée pour vérifier le serveur:

  • est-ce que le service Net.Tcp Listener Adapter fonctionne? Oui
  • le site de L'IIS est-il lié à net.tcp par 808:* ? Oui
  • est activé protocoles sous Paramètres avancés pour le site dans IIS réglé à http,net.tcp ? Oui
  • est-ce que le serveur écoute sur le port 808? Oui, vérifié avec netstat -an |find /i "listening"
  • est-ce qu'un port 808 est ouvert dans le pare-feu? Oui.
    • le pare-feu est désactivé sur le serveur.
    • je peux telnet au serveur sur le port 808 de l'extérieur avec telnet mydomain.com 808
  • Dans la configuration du service sur le serveur, ce qui suit a été confirmé:
    • baseAddress est ajusté à net.tcp://mydomain.com:808/SignalR/ServerHubService.svc
    • c'était localhost avant, mais changé en mydomain.com après il n'a pas travail sur le serveur: <identity><dns value="mydomain.com" /></identity>
  • il a été testé avec un client localement sur le serveur et sur un autre serveur. Les deux peuvent se connecter au port 808 avec telnet et donnent le même message d'erreur.

quelle configuration pourrait manquer sur le serveur? Je suis si près du but. Veuillez m'aider à résoudre ce problème et répondre à la question.

voici le client configuration sur le serveur appelant le service:

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

j'ai également essayé sans 808 configuré dans l'endpoint, car c'est le port par défaut pour net.les connexions tcp. Cependant, il donne toujours le même résultat.

au Lieu d'essayer beaucoup de choses au hasard, la bonne question est peut-être: Comment déboguer quelque chose comme cela? puis-je installer un programme sur l'un ou l'autre serveur qui me dira exactement pourquoi cet appel est bloqué?

avec Wireshark configuré comme ceci, il est possible de regarder l'appel venant au serveur sur le port 808 et éventuellement de déterminer pourquoi l'appel ne fonctionne pas. Cependant, je n'ai aucune idée de comment analyser ce à l'heure actuelle.

wireshark

bonne chance

j'ai abandonné et implémenté ceci dans la couche socket à la place. Il a travaillé immédiatement. J'espère que cela peut aider quelqu'un d'autre. Je mets en place une réponse parce que beaucoup des problèmes ont été résolus et cela a finalement fonctionné localement, donc tout problème restant est probablement lié à mon environnement spécifique.

29
demandé sur Niels Brinch 2013-05-18 23:53:35

7 réponses

vous devez générer le Proxy basé sur les métadonnées exposées sur HTTP pour tcp.(assurez-vous que httpGetEnabled est défini à true). L'adresse que vous utilisez à la clientèle doit être hébergés adresse. Veuillez consulter ci-dessous post.

http://blogs.msdn.com/b/swiss_dpe_team/archive/2008/02/08/iis-7-support-for-non-http-protocols.aspx

7
répondu Prasath 2013-05-22 08:19:10

dans votre question vous avez mentionné que vous vous êtes connecté à "test.mydomain.com" mais l'erreur a changé le serveur en "computername". Puis dans votre commentaire vous avez mentionné qu'il ne se connecte toujours pas. Si vous souhaitez que l'alias soit retourné dans le fichier WSDL/MEX, ajoutez le noeud userequestheadersformetadata dans votre comportement de service. Voici les informations MSDN sur ce noeud: MSDN useRequestHeadersForMetadataAddress noeud

voici comment votre config devrait regarder. Cela tient compte de la réponse donnée par Prasath (httpGetEnabled="true").

<serviceBehaviors>
   <behavior name="ServerHubBehavior">
      <serviceMetadata httpGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="false" />
      <useRequestHeadersForMetadataAddress>
         <defaultPorts>
            <add scheme="net.tcp" port="808" />
         </defaultPorts>
      </useRequestHeadersForMetadataAddress>
   </behavior>
</serviceBehaviors>
2
répondu J Man 2013-05-22 21:14:57

héberger un service basé sur TCP dans IIS a toujours été un ours. WCF rend très facile l'exécution de votre propre hôte de service, en écoutant sur votre port TCP. Ma recommandation serait de le faire et de le configurer pour qu'il fonctionne comme un service Windows.

voir cet article: http://msdn.microsoft.com/en-us/library/ff649818.aspx

0
répondu Mike Pugh 2013-05-24 22:14:32

je suppose que le problème que vous rencontrez est que vous devez configurer le SPN (nom Principal du Service) pour votre service FMC (sur la machine) et le faire ajouter au compte de service sous lequel le service est exécuté.

si vous l'exécutez sous l'utilisateur par défaut de l'application pool, alors vous devez avoir le SPN configuré pour la machine.

je sais qu'il est troublant, et est typiquement la surprise qui attend de nous devs une fois que notre service est prêt à déployer dans des environnements de production ou de préproduction.

le SPN est utilisé par Kerberos pendant le processus d'authentification.

essayez d'utiliser L'IP de la machine pour résoudre votre service au lieu du nom d'hôte. (Ceci n'est pas censé exiger un SPN), remplacer "test.mydomain.com "par l'adresse IP de la machine:

<host>
    <baseAddresses>
        <add baseAddress="net.tcp://192.168.0.253:808/SignalR/ServerHubService.svc" />
    </baseAddresses>
</host>

regardez ces articles: - Kerberos pour L'administrateur occupé

- WCF sur intranet avec authentification windows

- Pour le post suivant, essayer de lire celui qui n'est pas accepté comme une réponse: ce SPN que je dois mettre pour un filet.service tcp?

0
répondu Ashraf ElSwify 2017-05-23 10:29:39

avez-vous essayé d'héberger le service (à des fins de test) dans un service Windows sur votre machine locale? De cette façon, vous saurez au moins si le problème est du côté du service ou si c'est la configuration IIS/server.

0
répondu mez 2013-05-25 00:41:29

vous avez Net.Service de partage de ports TCP tournant sur le serveur je suppose... n'ont pas trouvé explicitement mentionnés.

0
répondu Nicolai Ustinov 2013-05-29 13:39:38

j'ai eu un problème similaire ici aujourd'hui, en appelant un filet.tcp WCF service de l'intérieur d'un asp.net Web api. Je ne dirai pas que de toutes les autres machines ce service a fonctionné pendant des années, mais les appels ont été faits WCF auto hébergement, wcf iis asp.net compatibilité hébergement - > contre le net.service tcp auto-hébergé. Quand j'ai publié mon api web simple appelant le même réseau.le service tcp, tout est allé de Travers, et toute la connexion a été interrompue sans aucune raison, même la wcf complète le fait de retracer les deux parties (le service et le client) n'a pas aidé, mais simplement de dire que la même "connexion a été interrompue".

j'ai déjà connu ce net.tcp est livré avec la sécurité sur le transport activé, en utilisant l'authentification windows pour signer et crypter la communication, si bien, je viens d'essayer d'éteindre la sécurité et tout commence à fonctionner correctement.

essayez simplement de désactiver la sécurité de cette façon des deux côtés (client et service):

<security mode="None"/>

full service de liaison:

<netTcpBinding>

    <binding name="netTcpBinding" portSharingEnabled="true">

        <security mode="None"/>

    </binding>

</netTcpBinding>

j'espère que cela pourra vous aider aussi.

0
répondu Michael Denny 2014-02-04 18:00:54