简体   繁体   English

自托管两个wcf接口(其中一个为双工)

[英]Self hosting two wcf interfaces (one of them is duplex)

I need to build a service that serves two interfaces. 我需要构建一个服务于两个接口的服务。 One interface uses basicHttpBinding, and the other should be netTcpBinding. 一个接口使用basicHttpBinding,另一个接口应该是netTcpBinding。 The other one should also support duplex communication. 另一个也应该支持双工通信。

basicHttp interface: basicHttp接口:

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

Implementation: 实现方式:

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

duplex netTcpContract: 双向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;

}

And implementation: 并实现:

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

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

I tried to self host both interfaces and this is the best i could do: 我试图自托管两个接口,这是我能做的最好的事情:

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

Now for the consuming part: //Consuming the first interface (this works so i removed it form the question) //Consuming the second interface: 现在,对于消耗部分://使用第一个接口(这样做可以使我从问题中删除它)//使用第二个接口:

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

This produces the following error: 这将产生以下错误:

ChannelFactory does not support the contract IVERAAPCS as it defines a callback contract with one or more operations. ChannelFactory不支持合同IVERAAPCS,因为它定义了一个或多个操作的回调合同。 Please consider using DuplexChannelFactory instead of ChannelFactory. 请考虑使用DuplexChannelFactory而不是ChannelFactory。

But I just can't seem to find a way to use the duplexChannelFactory. 但是我似乎似乎找不到使用duplexChannelFactory的方法。 So my question is basically how do you consume a duplex netTcpBinding service tat is self hosted? 所以我的问题基本上是您如何使用自托管的双工netTcpBinding服务?

Sorry for the long question, but I wanted to provide as much information as I could. 很抱歉,这个问题很长,但我想提供尽可能多的信息。 Thanks 谢谢

Per your request in the comments, here's an example. 根据您在评论中的要求,这里有一个例子。

Place all of your interfaces in a separate assembly. 将所有接口放置在单独的组件中。 For purposes of this example, let's name it ServiceContracts and use the namespace VERAAccessPoint.ServiceContracts . 就本示例而言,我们将其命名为ServiceContracts并使用名称空间VERAAccessPoint.ServiceContracts

Inside this assembly (which you'll want to create as a class library - DLL), you place IVERAAccessPoint , IVERAAPCS , IClientCallback and the data contract ClientInfo . 在此程序集(您将要创建为类库DLL)内部,放置IVERAAccessPointIVERAAPCSIClientCallback和数据协定ClientInfo

Next, add add a reference to the ServiceContracts assembly in your self-hosted application and a using directive: 接下来,在您的自托管应用程序中添加对ServiceContracts程序集的引用和using指令:

using VerAAccessPoint.ServiceContracts;

That way you can implement the contract interfaces and host the services. 这样,您可以实现合同接口并托管服务。

Finally, in your client application add the reference to the assembly and the using directive, and then you can do the following: 最后,在客户端应用程序中,添加对程序集的引用和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();

You could do something similar with ChannelFactory<T> using IVERAAccessPoint as well. 您也可以使用IVERAAccessPointChannelFactory<T>做类似的事情。

I have used ChannelFactory<T> a lot, but never the DuplexChannelFactory<T> , but this should give you another option to explore. 我已经使用ChannelFactory<T>了很多,但从未使用过DuplexChannelFactory<T> ,但这应该给您提供了另一种探索的选择。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM