This topic resembles this thread and this thread. Also I have read this example But, in any of this thread I can't find clear example how organize p2p connection across the internet. All examples good working in local network.
I made a small program, you can see it below. It works good in local network.
Main question: After peer registration how to open Wcf host and wait calls from another peers? In this topic I have read that:
When a peer is resolved on the global cloud, it is typically resolved to an IPv6 address
So I need open my WCF on this IPv6 address? How I can receive it? Please give me some coding tips.
My program:
namespace FileShare
{
internal class Program
{
private static void Main()
{
Console.WriteLine("Hello enter your username");
IPeerRegistrationRepository peerRegistrationRepository = new PeerRegistrationRepository();
IPeerNameResolverRepository peerNameResolverRepository = new PeerNameResolverRepository();
ServiceHost host = null;
try
{
string username = Console.ReadLine();
int port = PeerUtils.FindFreePort();
peerRegistrationRepository.StartRegistration("Max951Peer", port, PeerNameType.Secured);
string serviceUrl = $"net.tcp://{peerRegistrationRepository.PeerName.PeerHostName}:{port}/Max951P2PService";
IP2PService localService = new P2PService();
host = new ServiceHost(localService, new Uri(serviceUrl));
host.AddServiceEndpoint(typeof(IP2PService), new NetTcpBinding { Security = { Mode = SecurityMode.None } }, serviceUrl);
try
{
host.Open();
Console.WriteLine($"Host opened on { serviceUrl }");
}
catch (Exception e)
{
Console.WriteLine($"Error { e }");
return;
}
Console.WriteLine($"Registered peer. PeerHostName: { peerRegistrationRepository.PeerName.PeerHostName }, Classifier: { peerRegistrationRepository.PeerName.Classifier }");
PeerNameRecordCollection results = peerNameResolverRepository.ResolvePeerName(peerRegistrationRepository.PeerName, Cloud.Global);
Console.WriteLine("{0} Peers Found:", results.Count.ToString());
int i = 1;
foreach (PeerNameRecord peer in results)
{
Console.WriteLine("{0} Peer:{1}", i++, peer.PeerName);
foreach (IPEndPoint ip in peer.EndPointCollection)
{
Console.WriteLine("\t Endpoint: {0}", ip);
string endpointUrl = $"net.tcp://[{ip.Address}]:{ip.Port}/Max951P2PService";
NetTcpBinding binding = new NetTcpBinding { Security = { Mode = SecurityMode.None } };
try
{
IP2PService serviceProxy = ChannelFactory<IP2PService>.CreateChannel(binding, new EndpointAddress(endpointUrl));
serviceProxy.SendMessage("Hello!", username);
}
catch (Exception)
{
// ignored
}
}
}
Console.ReadLine();
}
catch (Exception e)
{
Console.WriteLine(e);
}
finally
{
peerRegistrationRepository.StopRegistration();
host?.Close();
}
//serviceModelClient.Stop();
}
}
[ServiceContract]
public interface IP2PService
{
[OperationContract(IsOneWay = true)]
void SendMessage(string message, string from);
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class P2PService : IP2PService
{
/// <inheritdoc />
public void SendMessage(string message, string from)
{
Console.WriteLine($"{from} says: { message }");
}
}
}
namespace Utils.PeerToPeer
{
public class PeerNameResolverRepository : IPeerNameResolverRepository
{
private readonly PeerNameResolver peerNameResolver;
public PeerNameResolverRepository()
{
this.peerNameResolver = new PeerNameResolver();
}
/// <inheritdoc />
public PeerNameRecordCollection ResolvePeerName(string name, PeerNameType peerNameType, Cloud cloud)
{
if (string.IsNullOrEmpty(name))
{
throw new ArgumentNullException(nameof(name));
}
return this.peerNameResolver.Resolve(new PeerName(name, peerNameType), cloud);
}
/// <inheritdoc />
public PeerNameRecordCollection ResolvePeerName(PeerName peerName, Cloud cloud)
{
return this.peerNameResolver.Resolve(peerName, cloud);
}
}
}
namespace Utils.PeerToPeer
{
public class PeerRegistrationRepository : IPeerRegistrationRepository
{
private PeerNameRegistration peerNameRegistration;
/// <inheritdoc />
public bool IsRegistered => this.peerNameRegistration != null && this.peerNameRegistration.IsRegistered();
/// <inheritdoc />
public string PeerUri => GetPeerUri();
/// <inheritdoc />
public PeerName PeerName { get; set; }
/// <inheritdoc />
public void StartRegistration(string name, int port, PeerNameType peerNameType)
{
this.PeerName = new PeerName(name, peerNameType);
this.peerNameRegistration = new PeerNameRegistration(PeerName, port, Cloud.Global);
this.peerNameRegistration.Start();
}
/// <inheritdoc />
public void StopRegistration()
{
this.peerNameRegistration?.Stop();
this.peerNameRegistration = null;
}
private string GetPeerUri()
{
return this.peerNameRegistration?.PeerName.PeerHostName;
}
}
}