【问题标题】:WCF duplex P2P, avoid peer calling itself and connect to specific peerWCF双工P2P,避免peer调用自己并连接到特定peer
【发布时间】:2013-12-19 13:54:31
【问题描述】:

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

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 服务名称,这就是为什么存在 将其提供给对等类构造函数的参数?

【问题讨论】:

    标签: c# wcf p2p duplex


    【解决方案1】:

    您需要 RemoteOnlyMessagePropagationFilter:当您创建 Peer 2 Peer Channel 时:

            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】:

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

      【讨论】:

        猜你喜欢
        • 2017-07-19
        • 1970-01-01
        • 2012-10-15
        • 1970-01-01
        • 2019-03-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-08-22
        相关资源
        最近更新 更多