public async Task DiscoveryJs() { var serviceName = $"_{Guid.NewGuid()}._udp"; serviceName = "_foo._udp"; var peer1 = new Peer { Id = "QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ", Addresses = new MultiAddress[] { "/ip4/104.131.131.82/tcp/4001/ipfs/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ" } }; var peer2 = new Peer { Id = "QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuK", Addresses = new MultiAddress[] { "/ip4/104.131.131.82/tcp/4001/ipfs/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuK" } }; var done = new ManualResetEvent(false); var mdns1 = new MdnsJs { MulticastService = new MulticastService(), ServiceName = serviceName, LocalPeer = peer1 }; var mdns2 = new MdnsJs { MulticastService = new MulticastService(), ServiceName = serviceName, LocalPeer = peer2 }; mdns1.PeerDiscovered += (s, e) => { if (e.Id == peer2.Id) { done.Set(); } }; await mdns1.StartAsync(); mdns1.MulticastService.Start(); await mdns2.StartAsync(); mdns2.MulticastService.Start(); try { Assert.IsTrue(done.WaitOne(TimeSpan.FromSeconds(2)), "timeout"); } finally { await mdns1.StopAsync(); await mdns2.StopAsync(); mdns1.MulticastService.Stop(); mdns2.MulticastService.Stop(); } }
/// <summary> /// Starts the network services. /// </summary> /// <returns> /// A task that represents the asynchronous operation. /// </returns> /// <remarks> /// Starts the various IPFS and PeerTalk network services. This should /// be called after any configuration changes. /// </remarks> /// <exception cref="Exception"> /// When the engine is already started. /// </exception> public async Task StartAsync() { if (stopTasks.Count > 0) { throw new Exception("IPFS engine is already started."); } var localPeer = await LocalPeer.ConfigureAwait(false); log.Debug("starting " + localPeer.Id); // Everybody needs the swarm. var swarm = await SwarmService.ConfigureAwait(false); stopTasks.Add(async() => { await swarm.StopAsync().ConfigureAwait(false); }); await swarm.StartAsync().ConfigureAwait(false); // Start the primary services. var tasks = new List <Func <Task> > { async() => { var bitswap = await BitswapService.ConfigureAwait(false); stopTasks.Add(async() => await bitswap.StopAsync().ConfigureAwait(false)); await bitswap.StartAsync().ConfigureAwait(false); }, async() => { var dht = await DhtService.ConfigureAwait(false); stopTasks.Add(async() => await dht.StopAsync().ConfigureAwait(false)); await dht.StartAsync().ConfigureAwait(false); }, async() => { var pubsub = await PubSubService.ConfigureAwait(false); stopTasks.Add(async() => await pubsub.StopAsync().ConfigureAwait(false)); await pubsub.StartAsync().ConfigureAwait(false); }, }; log.Debug("waiting for services to start"); await Task.WhenAll(tasks.Select(t => t())).ConfigureAwait(false); // Starting listening to the swarm. var json = await Config.GetAsync("Addresses.Swarm").ConfigureAwait(false); var numberListeners = 0; foreach (string a in json) { try { await swarm.StartListeningAsync(a).ConfigureAwait(false); ++numberListeners; } catch (Exception e) { log.Warn($"Listener failure for '{a}'", e); // eat the exception } } if (numberListeners == 0) { log.Error("No listeners were created."); } // Now that the listener addresses are established, the discovery // services can begin. MulticastService multicast = null; if (!Options.Discovery.DisableMdns) { multicast = new MulticastService(); #pragma warning disable CS1998 stopTasks.Add(async() => multicast.Dispose()); #pragma warning restore CS1998 } var autodialer = new AutoDialer(swarm) { MinConnections = Options.Swarm.MinConnections }; #pragma warning disable CS1998 stopTasks.Add(async() => autodialer.Dispose()); #pragma warning restore CS1998 tasks = new List <Func <Task> > { // Bootstrap discovery async() => { var bootstrap = new PeerTalk.Discovery.Bootstrap { Addresses = await this.Bootstrap.ListAsync() }; bootstrap.PeerDiscovered += OnPeerDiscovered; stopTasks.Add(async() => await bootstrap.StopAsync().ConfigureAwait(false)); await bootstrap.StartAsync().ConfigureAwait(false); }, // New multicast DNS discovery async() => { if (Options.Discovery.DisableMdns) { return; } var mdns = new PeerTalk.Discovery.MdnsNext { LocalPeer = localPeer, MulticastService = multicast }; if (Options.Swarm.PrivateNetworkKey != null) { mdns.ServiceName = $"_p2p-{Options.Swarm.PrivateNetworkKey.Fingerprint().ToHexString()}._udp"; } mdns.PeerDiscovered += OnPeerDiscovered; stopTasks.Add(async() => await mdns.StopAsync().ConfigureAwait(false)); await mdns.StartAsync().ConfigureAwait(false); }, // Old style JS multicast DNS discovery async() => { if (Options.Discovery.DisableMdns || Options.Swarm.PrivateNetworkKey != null) { return; } var mdns = new PeerTalk.Discovery.MdnsJs { LocalPeer = localPeer, MulticastService = multicast }; mdns.PeerDiscovered += OnPeerDiscovered; stopTasks.Add(async() => await mdns.StopAsync().ConfigureAwait(false)); await mdns.StartAsync().ConfigureAwait(false); }, // Old style GO multicast DNS discovery async() => { if (Options.Discovery.DisableMdns || Options.Swarm.PrivateNetworkKey != null) { return; } var mdns = new PeerTalk.Discovery.MdnsGo { LocalPeer = localPeer, MulticastService = multicast }; mdns.PeerDiscovered += OnPeerDiscovered; stopTasks.Add(async() => await mdns.StopAsync().ConfigureAwait(false)); await mdns.StartAsync().ConfigureAwait(false); }, async() => { if (Options.Discovery.DisableRandomWalk) { return; } var randomWalk = new RandomWalk { Dht = Dht }; stopTasks.Add(async() => await randomWalk.StopAsync().ConfigureAwait(false)); await randomWalk.StartAsync().ConfigureAwait(false); } }; log.Debug("waiting for discovery services to start"); await Task.WhenAll(tasks.Select(t => t())).ConfigureAwait(false); multicast?.Start(); log.Debug("started"); }
/// <summary> /// Starts the network services. /// </summary> /// <returns> /// A task that represents the asynchronous operation. /// </returns> /// <remarks> /// Starts the various IPFS and PeerTalk network services. This should /// be called after any configuration changes. /// </remarks> /// <exception cref="Exception"> /// When the engine is already started. /// </exception> public async Task StartAsync() { if (stopTasks.Count > 0) { throw new Exception("IPFS engine is already started."); } var localPeer = await LocalPeer; log.Debug("starting " + localPeer.Id); // Everybody needs the swarm. var swarm = await SwarmService; stopTasks.Add(async() => await swarm.StopAsync()); await swarm.StartAsync(); var multicast = new MulticastService(); #pragma warning disable CS1998 stopTasks.Add(async() => multicast.Dispose()); #pragma warning restore CS1998 var tasks = new List <Func <Task> > { async() => { var bootstrap = new PeerTalk.Discovery.Bootstrap { Addresses = await this.Bootstrap.ListAsync() }; bootstrap.PeerDiscovered += OnPeerDiscovered; stopTasks.Add(async() => await bootstrap.StopAsync()); await bootstrap.StartAsync(); }, async() => { var mdns = new PeerTalk.Discovery.MdnsNext { LocalPeer = localPeer, MulticastService = multicast }; mdns.PeerDiscovered += OnPeerDiscovered; stopTasks.Add(async() => await mdns.StopAsync()); await mdns.StartAsync(); }, async() => { var mdns = new PeerTalk.Discovery.MdnsJs { LocalPeer = localPeer, MulticastService = multicast }; mdns.PeerDiscovered += OnPeerDiscovered; stopTasks.Add(async() => await mdns.StopAsync()); await mdns.StartAsync(); }, async() => { var mdns = new PeerTalk.Discovery.MdnsGo { LocalPeer = localPeer, MulticastService = multicast }; mdns.PeerDiscovered += OnPeerDiscovered; stopTasks.Add(async() => await mdns.StopAsync()); await mdns.StartAsync(); }, async() => { var bitswap = await BitswapService; stopTasks.Add(async() => await bitswap.StopAsync()); await bitswap.StartAsync(); }, async() => { var dht = await DhtService; stopTasks.Add(async() => await dht.StopAsync()); await dht.StartAsync(); }, }; log.Debug("waiting for services to start"); await Task.WhenAll(tasks.Select(t => t())); // TODO: Would be nice to make this deterministic. //await Task.Delay(TimeSpan.FromMilliseconds(100)); //log.Debug("all service started"); // Starting listening to the swarm. var json = await Config.GetAsync("Addresses.Swarm"); var numberListeners = 0; foreach (string a in json) { try { await swarm.StartListeningAsync(a); ++numberListeners; } catch (Exception e) { log.Warn($"Listener failure for '{a}'", e); // eat the exception } } if (numberListeners == 0) { log.Error("No listeners were created."); } // Now that the listener addresses are established, the mdns discovery can begin. // TODO: Maybe all discovery services should be start here. multicast.Start(); log.Debug("started"); }