【发布时间】: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
当然,我可以在我的应用程序中使用一些技巧来过滤掉不需要的传入流量,但在此之前我想知道
是否可以将 WCF 配置为不回调对等方 响应自己的号召?
限制对等方仅成对连接的最佳方法是什么? 每个对等点仅连接到特定对等点?我可以考虑使用 每对都有唯一的 P2P 服务名称,这就是为什么存在 将其提供给对等类构造函数的参数?
【问题讨论】: