1

我需要构建一个服务于两个接口的服务。一个接口使用basicHttpBinding,另一个应该是netTcpBinding。另一个也应该支持双工通信。

基本Http接口:

[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();
}

现在对于消费部分://使用第一个界面(这有效,所以我从问题中删除了它)//使用第二个界面:

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 不支持协定 IVERAAPCS,因为它定义了一个具有一个或多个操作的回调协定。请考虑使用 DuplexChannelFactory 而不是 ChannelFactory。

但我似乎无法找到使用 duplexChannelFactory 的方法。所以我的问题基本上是您如何使用自托管的双工 netTcpBinding 服务?

很抱歉这个问题很长,但我想提供尽可能多的信息。谢谢

4

1 回答 1

1

根据您在评论中的要求,这是一个示例。

将所有接口放在一个单独的程序集中。出于本示例的目的,我们将其命名为 ServiceContracts 并使用命名空间VERAAccessPoint.ServiceContracts

在这个程序集(您希望将其创建为类库 - DLL)中,放置、IVERAAccessPoint和数据协定。IVERAAPCSIClientCallbackClientInfo

接下来,在自托管应用程序中添加对 ServiceContracts 程序集的引用和using指令:

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>您也可以使用 using做类似的事情IVERAAccessPoint

我已经使用ChannelFactory<T>了很多,但从来没有使用过DuplexChannelFactory<T>,但这应该给你另一个探索的选择。

于 2013-05-27T18:17:22.797 回答