首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >WCF双工P2P,避免对等调用本身,并连接到特定的对等点。

WCF双工P2P,避免对等调用本身,并连接到特定的对等点。
EN

Stack Overflow用户
提问于 2013-12-19 13:54:31
回答 2查看 483关注 0票数 2

我正在开发一个.NET应用程序,它将使位于因特网上任何位置(通常位于NAT之后)的对计算机能够并行地交换消息。我做了一些可能的解决方案的研究,并得出结论,也许WCF双工P2P连接适合我所需要的东西。因为我是WCF的新手,所以我创建了一个小型的测试应用程序,它似乎在一般情况下运行良好--向另一方发送特定消息的对等程序也会在自己的接口上调用并接收回它。这是代码

代码语言:javascript
复制
using System;
using System.Threading.Tasks;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;

[ServiceContract(CallbackContract = typeof(IDataChannel))]
public interface IDataChannel
{
    [OperationContract(IsOneWay = true)]
    void SendData(string data);
}

public class WCFP2PTransport : IDataChannel
{
    private IDataChannel m_outChannel = null;
    private DuplexChannelFactory<IDataChannel> m_factory = null;
    private Task m_completion;
    private string m_name;

    public WCFP2PTransport(string service, string name)
    {
        m_name = name;
        try
        {
            var binding = new NetPeerTcpBinding();
            binding.Security.Mode = SecurityMode.None;

            var endpoint = new ServiceEndpoint(
                ContractDescription.GetContract(typeof(IDataChannel)),
                binding,
                new EndpointAddress("net.p2p://" + service));

            m_factory = new DuplexChannelFactory<IDataChannel>(
                new InstanceContext(this),
                endpoint);

            m_outChannel = m_factory.CreateChannel();

            m_completion = Task.Factory.FromAsync(((ICommunicationObject)m_outChannel).BeginOpen, ((ICommunicationObject)m_outChannel).EndOpen, null);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
            var tsk = new TaskCompletionSource<bool>();
            tsk.SetException(ex);
            m_completion = tsk.Task;
        }
    }

    public Task ChannelOpened
    {
        get
        {
            return m_completion;
        }
    }

    public void SendToPeer(string data)
    {
        m_outChannel.SendData(data);
    }

    // IDataChannel method(s), handle incoming traffic
    public void SendData(string data)
    {
        Console.WriteLine("{0} Received data: {1}", m_name, data);
    }

    // cleanup code omitted for brevity
}

class Program
{
    static void Main(string[] args)
    {
        var peer1 = new WCFP2PTransport("WCF_P2P_Test", "Peer1");
        var peer2 = new WCFP2PTransport("WCF_P2P_Test", "Peer2");

        Task.WaitAll(peer1.ChannelOpened, peer2.ChannelOpened);

        peer1.SendToPeer("Packet1");
        peer2.SendToPeer("Packet2");

        Console.ReadKey();
    }
}

此应用程序的输出是

Peer1接收数据: Packet1 Peer2接收数据: Packet1 Peer1接收数据: Packet2 Peer2接收数据: Packet2

当我想看到

Peer2接收数据: Packet1 Peer1接收数据: Packet2

当然,我可以在我的应用程序中做一些技巧来过滤掉不必要的传入流量,但在此之前,我想知道

  1. 是否可以将WCF配置为不响应它自己的调用而调用对等方?
  2. 什么是最好的方式来限制节点只能成对地连接,而每个对等点只连接到特定的对等点?我可以考虑为每对使用唯一的P2P服务名称,这就是为什么有一个参数将其提供给对等类构造函数?
EN

回答 2

Stack Overflow用户

发布于 2014-07-10 00:50:43

您需要RemoteOnlyMessagePropagationFilter:当您创建Peer 2对等通道时:

代码语言:javascript
复制
        var sourceContext = new InstanceContext(sourceObject);

        var sourceFactory = new DuplexChannelFactory<TChannel>(sourceContext, endpointName);

        TChannel sourceProxy = sourceFactory.CreateChannel();

        var remoteOnlyFilter = new RemoteOnlyMessagePropagationFilter();

        var peerNode = ((IClientChannel)sourceProxy).GetProperty<PeerNode>();
        peerNode.MessagePropagationFilter = remoteOnlyFilter;
        try
        {
            sourceProxy.Open();
        }
        catch (Exception)
        {
            sourceProxy.TryCloseOrAbort();
            throw;
        }
票数 2
EN

Stack Overflow用户

发布于 2013-12-19 14:26:29

我能想到的最直接的答案是使用一个身份识别方案,并确保你没有发送给自己。一旦确定了所有连接到的对等点(可能是托管列表?)只需对其进行迭代,并将数据包发送到每个包。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20683529

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档