11

基本的にパブリッシュ サブスクライバー パターンである WCF サービス コントラクトがあります。

WCF サービスは、公開元の Windows サービス内でホストされています。クライアントはメッセージをサブスクライブし、Windows サービスが何かを実行すると、すべてのクライアントにパブリッシュします。

サービスをホストするために、ServiceHost クラスを宣言しました。Contract クラスには、インターフェイスでフラグが設定されていないが公開するクラスで実装されているメソッドがあります。

このメソッドを (WCF 経由ではなく) ローカルで呼び出すことができるようにしたいと考えています。これにより、コールバック経由でメッセージが発行されます。

ServiceHost からコントラクト クラスのインスタンスに到達できないようです。

これは可能ですか?クライアントをサービスに組み込むことも回避策であることは知っていますが、それ自体に接続するクライアントを作成するのは少し奇妙に思えます。

前もって感謝します

DJIDave

app.config

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

4 に答える 4

8

ServiceHost へのサービス インスタンス参照をコンストラクター パラメーターとして提供しない限り、ServiceHost にサービス インスタンス参照を提供させる方法はありません。そのインスタンス参照を提供すると、シングルトン サービスを作成することになりますが、これは一般的にはお勧めできません。

サービスを構成されたままにするには、クライアントを介してサービスを呼び出す必要があります。これは、実際には思ったよりも簡単です。ホスト コードはサービス コントラクトにアクセスできるため、それをChannelFactory クラスと共に使用して、サービスのプロキシを取得できます。サービス コントラクトの他に提供する必要があるのは、エンドポイントだけで、あとは ChannelFactory が行います。以下は、これを行う方法の例です。

private IMyServiceContract GetLocalClient(string serviceEndpointName)
{
    var factory = new ChannelFactory<IMyServiceContract>(serviceEndpointName);
    return factory.CreateChannel();
}

更新: このアプローチに加えて、パフォーマンスを向上させるために、サービスにNetNamedPipeBinding エンドポイントを公開することを検討する必要があります。このバインドはほとんどすべてをメモリ内で実行し、同じマシン サービス呼び出しの最速のバインドです。

于 2011-05-20T11:00:00.920 に答える
3

複数回インスタンス化する WCF サービス (非シングルトン) の場合、次のように、各インスタンスの対応するコールバック関数を含むリストを維持できます: mdsn。メソッドCallClients() (この MSDN の例から) は、サービス クラスの静的メンバーであるため、ホスティング コードから直接呼び出すことができます。これは私が見つけた唯一の他の方法です..

于 2012-04-19T13:37:43.700 に答える