11
votes

Puis-je appeler une méthode dans un service de WCF auto-hébergé localement?

J'ai un contrat de service WCF qui est fondamentalement le modèle d'abonné de publication.

Le service WCF est hébergé dans le service Windows que je souhaite publier. Les clients s'abonnent aux messages et lorsque le service Windows fait quelque chose qu'il publie à tous les clients. P>

Pour héberger le service que j'ai déclaré une classe ServiceHost et la classe contractuelle a une méthode qui n'est pas marquée dans l'interface mais est implémenté dans la classe à publier. p>

Je veux pouvoir appeler cette méthode localement (ne pas passer par WCF) qui publie ensuite le message via Callbacks. P>

Je ne peux pas semble aller de ServiceHost à l'instance de la classe contractuelle. P>

est-ce possible et si oui comment? Je sais que le travail consiste à faire construire un client dans le service, mais il semble un peu étrange créant un client à se connecter à lui-même. P>

Merci d'avance P>

Djidave p>app.configleight /p>

<system.serviceModel>
    <services>
      <service behaviorConfiguration="Processor.Wcf.ServiceBehavior"
        name="Processor.Wcf.ProcessorService">
        <endpoint address="net.tcp://localhost:9000/processor/service"
              binding="netTcpBinding" name="procService"
              bindingConfiguration="netTcpBindingConfig"
              contract="Processor.Wcf.IProcessorService"/>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
          <host>
            <baseAddresses>
              <add baseAddress="http://localhost:8732/Design_Time_Addresses/Processor.Wcf/Service1/" />
            </baseAddresses>
          </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="Processor.Wcf.ServiceBehavior">
          <!-- To avoid disclosing metadata information, 
          set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="True"/>
          <!-- To receive exception details in faults for debugging purposes, 
          set the value below to true.  Set to false before deployment 
          to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="False" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings>
      <netTcpBinding>
        <binding name="netTcpBindingConfig"
                 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="Transport">
            <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
          </security>
        </binding>
      </netTcpBinding>
    </bindings>

  </system.serviceModel>


0 commentaires

4 Réponses :


8
votes

Sauf si vous fournissez la référence d'instance de service au ServiceHost en tant que paramètre Constructor, il n'ya pas de moyen d'avoir le service de service vous fournir une référence d'instance de service. Si vous fournissez cette référence de cette instance, vous créez un service singleton qui n'est généralement pas une bonne idée.

Pour conserver le service tel qu'il est configuré, vous devrez appeler la part d'un client. C'est en fait plus facile que vous pourriez penser. Étant donné que votre code d'hôte a accès au contrat de service, vous pouvez l'utiliser avec le classe canielelfactory à Obtenez un proxy pour le service. Outre le contrat de service, tout ce que vous avez à fournir est le point final NAME et SUYLYLYLICORY fera le reste. Vous trouverez ci-dessous un exemple de comment faire ceci: xxx

mise à jour: En plus de cette approche, vous devriez envisager de vous servir exposer un point de NetNamedpipeLinding à améliorer les performances. Cette liaison fait presque beaucoup tout en mémoire et est la liaison la plus rapide pour la même invocation de service de la machine.


3 commentaires

Merci pour la réponse, je peux obtenir l'usine avec succès, mais lorsque vous essayez d'appeler Createcharnel, je reçois «la propriété d'adresse sur canalysacory.endPoint était null. Le point de terminaison de la canalisation doit avoir une adresse valide spécifiée.». Je vais poster l'app.config en tant que modifier vers le poste d'origine.


Si l'exception est lancée même si le nom du point d'extrémité que vous passez, la fonction est «Procservice», il peut s'agir d'un problème d'autorisation. Ceci est juste une conjecture, mais le compte du service Windows est celui utilisé pour accéder au service WCF. Il pourrait être possible qu'il n'ait pas autorisé à invoquer le service car vous avez besoin d'une authentification Windows. Si ce n'est pas la casse, je vous recommanderais que vous ajoutez et configurez le NetNamedpipeLinding au lieu d'essayer de résoudre la liaison TCP puisqu'un meilleur choix pour ce que vous faites.


Utile: social.msdn.microsoft.com/forums/vstudio/en-us/...



3
votes

Pour un service WCF Instanciateur Plus d'une fois (non-Singleton), vous pouvez gérer une liste contenant la fonction de rappel correspondante de chaque instance, comme indiqué ici: MDSN . Vous pouvez appeler la méthode CallClients () (à partir de cet exemple MSDN) du code d'hébergement directement car il s'agit d'un membre statique de la classe de service. C'est la seule autre autre façon que j'ai trouvée ..


0 commentaires

2
votes

sauf si vous fournissez la référence d'instance de service au service de service en tant que paramètre constructeur,

Cette ligne de la solution de Sixto résolvait des choses pour moi. Crédit et merci à ce message aussi.

J'utilise une liaison en duplex pour le moment.


Le concept de clé est que vous pouvez passer dans un type type ou une instance au constructeur ServiceHost .

donc ce que j'avais auparavant était: xxx

ce dont j'avais besoin Était: xxx

aussi, je devais marquer myservice avec xxx

... Et maintenant, je peux appeler les méthodes de l'hôte à l'intérieur du service.

Cependant, gardez à l'esprit que l'instance que vous avez créée ne disposera pas d'un opérationContext si vous appelez directement ses méthodes: Httptps://stackoverflow.com/a/15270541/385273

bonne chance!


0 commentaires