1

2 つのインターフェースを提供するサービスを構築する必要があります。一方のインターフェイスは basicHttpBinding を使用し、もう一方は netTcpBinding にする必要があります。もう一方も二重通信をサポートする必要があります。

basicHttp インターフェース:

[ServiceContract(Name = "accesspointService")]
[XmlSerializerFormat]
public interface IVERAAccessPoint
{
    [OperationContract]
    CompositeType GetDataUsingDataContract(MyClass obj);
}

実装:

 [ServiceBehavior(Name = "accesspointService", Namespace = "http://www.w3.org/2009/02/ws-tra")]
public class VERAAccessPoint : IVERAAccessPoint
{
    public CompositeType GetDataUsingDataContract(MyClass obj)
    {
        //something
        return composite;
    }
}

デュプレックス netTcpContract:

[ServiceContract(CallbackContract = typeof(IClientCallback))]
public interface IVERAAPCS
{
    [OperationContract(IsOneWay=true)]
    void Subscribe(ClientInfo info);

    [OperationContract(IsOneWay=true)]
    void Unsubscribe(ClientInfo info);

}

public interface IClientCallback
{
    [OperationContract(IsOneWay = true)]
    void PushDocument(XDocument doc);
}

[DataContract]
public class ClientInfo
{
    public string id;

}

そして実装:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession,ConcurrencyMode = ConcurrencyMode.Single)]
public class VERAAPCS : IVERAAPCS
{
    public void Subscribe(ClientInfo info)
    {
        //something
    }

    public void Unsubscribe(ClientInfo info)
    {
        //Something
    }
}

私は両方のインターフェースを自己ホストしようとしましたが、これが私ができる最善の方法です:

Uri baseAddress1 = new Uri("http://localhost:6544/hello");
//host the first interface
using (ServiceHost host = new ServiceHost(typeof(VERAAccessPoint.VERAAccessPoint), baseAddress))
{

    // Enable metadata publishing.
    ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
    smb.HttpGetEnabled = true;
    smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
    host.Description.Behaviors.Add(smb);

    host.Open();
    //Host the second (duplex interface)
    using (ServiceHost host2 = new ServiceHost(typeof(VERAAccessPoint.VERAAPCS)))
    {
        host2.AddServiceEndpoint(typeof(VERAAccessPoint.IVERAAPCS), new NetTcpBinding(), "net.tcp://localhost:6543/hello2");
        host2.Open();
        Console.ReadLine();
        host2.Close();
    }
    host.Close();
}

消費部分については次のとおりです。//最初のインターフェイスを消費します(これは機能するため、質問から削除しました)//2番目のインターフェイスを消費します:

var myBinding = new NetTcpBinding();
var myEndpoint = new EndpointAddress("net.tcp://localhost:6543/hello2");
var myChannelFactory = new ChannelFactory<VERAAccessPoint.IVERAAPCS>(myBinding, myEndpoint);

VERAAccessPoint.IVERAAPCS client = null;

client = myChannelFactory.CreateChannel();

これにより、次のエラーが発生します。

ChannelFactory は、1 つ以上の操作でコールバック コントラクトを定義するため、コントラクト IVERAAPCS をサポートしません。ChannelFactory の代わりに DuplexChannelFactory の使用を検討してください。

しかし、duplexChannelFactory を使用する方法が見つからないようです。だから私の質問は、基本的に、自己ホスト型の二重 netTcpBinding サービスをどのように消費するのですか?

長い質問で申し訳ありませんが、できるだけ多くの情報を提供したかったのです。ありがとう

4

1 に答える 1

1

コメントのリクエストに従って、ここに例を示します。

すべてのインターフェイスを別のアセンブリに配置します。この例では、ServiceContracts という名前を付けて、名前空間を使用しますVERAAccessPoint.ServiceContracts

このアセンブリ (クラス ライブラリ (DLL) として作成する必要があります) 内に、、、IVERAAccessPointおよびIVERAAPCSデータIClientCallbackコントラクトを配置しClientInfoます。

using次に、セルフホステッド アプリケーションとディレクティブに ServiceContracts アセンブリへの参照を追加します。

using VerAAccessPoint.ServiceContracts;

そうすれば、コントラクト インターフェイスを実装し、サービスをホストできます。

最後に、クライアント アプリケーションで、アセンブリとusingディレクティブへの参照を追加すると、次のことが可能になります。

IVERAAPCS client = null;
var myBinding = new NetTcpBinding();
var myEndpoint = new EndpointAddress("net.tcp://localhost:6543/hello2");
var myDuplexChannelFactory = new DuplexChannelFactory<IVERAAPCS>(myBinding, myEndpoint);

client = myDuplexChannelFactory.CreateChannel();

ChannelFactory<T>を使用して同様のことを行うこともできますIVERAAccessPoint

私はChannelFactory<T>多くのことを使用してきましたが、 を使用したことはありませんDuplexChannelFactory<T>

于 2013-05-27T18:17:22.797 に答える