public async Task SubscribedPeers_AllTopics() { var topic1 = Guid.NewGuid().ToString(); var topic2 = Guid.NewGuid().ToString(); var ns = new PubSubService { LocalPeer = self }; var router = new FloodRouter { SwarmService = new SwarmService() }; router.RemoteTopics.AddInterest(topic1, other1); router.RemoteTopics.AddInterest(topic2, other2); ns.Routers.Add(router); await ns.StartAsync(); try { var peers = (await ns.PeersAsync()).ToArray(); Assert.AreEqual(2, peers.Length); } finally { await ns.StopAsync(); } }
public async Task DuplicateMessagesAreIgnored() { var ns = new PubSubService { LocalPeer = self }; ns.Routers.Add(new LoopbackRouter()); await ns.StartAsync(); try { var topic = Guid.NewGuid().ToString(); var cs = new CancellationTokenSource(); var messageCount = 0; await ns.SubscribeAsync(topic, msg => { ++messageCount; }, cs.Token); await ns.PublishAsync(topic, "", cs.Token); Assert.AreEqual(1, messageCount); Assert.AreEqual(2ul, ns.MesssagesReceived); Assert.AreEqual(1ul, ns.DuplicateMesssagesReceived); } finally { await ns.StopAsync(); } }
public async Task Subscribe_HandlerExceptionIsIgnored() { var ns = new PubSubService { LocalPeer = self }; await ns.StartAsync(); try { var topic = Guid.NewGuid().ToString(); var cs = new CancellationTokenSource(); var messageCount = 0; await ns.SubscribeAsync(topic, msg => { ++messageCount; throw new Exception(); }, cs.Token); await ns.PublishAsync(topic, "", cs.Token); Assert.AreEqual(1, messageCount); } finally { await ns.StopAsync(); } }
public async Task MessageID_Increments() { var ns = new PubSubService { LocalPeer = self }; await ns.StartAsync(); try { var a = ns.CreateMessage("topic", new byte[0]); var b = ns.CreateMessage("topic", new byte[0]); Assert.IsTrue(string.Compare(b.MessageId, a.MessageId, StringComparison.Ordinal) > 0); } finally { await ns.StopAsync(); } }
public async Task Topics() { var ns = new PubSubService { LocalPeer = self }; await ns.StartAsync(); try { var topicA = Guid.NewGuid().ToString(); var topicB = Guid.NewGuid().ToString(); var csA = new CancellationTokenSource(); var csB = new CancellationTokenSource(); await ns.SubscribeAsync(topicA, msg => { }, csA.Token); await ns.SubscribeAsync(topicA, msg => { }, csA.Token); await ns.SubscribeAsync(topicB, msg => { }, csB.Token); var topics = (await ns.SubscribedTopicsAsync(csA.Token)).ToArray(); Assert.AreEqual(2, topics.Length); CollectionAssert.Contains(topics, topicA); CollectionAssert.Contains(topics, topicB); csA.Cancel(); topics = (await ns.SubscribedTopicsAsync(csA.Token)).ToArray(); Assert.AreEqual(1, topics.Length); CollectionAssert.Contains(topics, topicB); csB.Cancel(); topics = (await ns.SubscribedTopicsAsync(csA.Token)).ToArray(); Assert.AreEqual(0, topics.Length); } finally { await ns.StopAsync(); } }
public async Task Publish() { var ns = new PubSubService { LocalPeer = self }; await ns.StartAsync(); try { await ns.PublishAsync("topic", "foo"); await ns.PublishAsync("topic", new byte[] { 1, 2, 3 }); await ns.PublishAsync("topic", new MemoryStream(new byte[] { 1, 2, 3 })); Assert.AreEqual(3ul, ns.MesssagesPublished); Assert.AreEqual(3ul, ns.MesssagesReceived); } finally { await ns.StopAsync(); } }
public async Task Sends_Hello_OnConnect() { var topic = Guid.NewGuid().ToString(); var swarm1 = new SwarmService { LocalPeer = self }; var router1 = new FloodRouter { SwarmService = swarm1 }; var ns1 = new PubSubService { LocalPeer = self }; ns1.Routers.Add(router1); await swarm1.StartAsync(); await ns1.StartAsync(); var swarm2 = new SwarmService { LocalPeer = other }; var router2 = new FloodRouter { SwarmService = swarm2 }; var ns2 = new PubSubService { LocalPeer = other }; ns2.Routers.Add(router2); await swarm2.StartAsync(); await ns2.StartAsync(); try { await swarm1.StartListeningAsync("/ip4/127.0.0.1/tcp/0"); await swarm2.StartListeningAsync("/ip4/127.0.0.1/tcp/0"); var cs = new CancellationTokenSource(); await ns1.SubscribeAsync(topic, msg => { }, cs.Token); await swarm1.ConnectAsync(other, cs.Token); var peers = new Peer[0]; var endTime = DateTime.Now.AddSeconds(3); while (peers.Length == 0) { if (DateTime.Now > endTime) { Assert.Fail("timeout"); } await Task.Delay(100, cs.Token); peers = (await ns2.PeersAsync(topic, cs.Token)).ToArray(); } CollectionAssert.Contains(peers, self); } finally { await swarm1.StopAsync(); await ns1.StopAsync(); await swarm2.StopAsync(); await ns2.StopAsync(); } }
public async Task Relays_PublishedMessage() { var topic = Guid.NewGuid().ToString(); var swarm1 = new SwarmService { LocalPeer = self }; var router1 = new FloodRouter { SwarmService = swarm1 }; var ns1 = new PubSubService { LocalPeer = self }; ns1.Routers.Add(router1); await swarm1.StartAsync(); await ns1.StartAsync(); var swarm2 = new SwarmService { LocalPeer = other }; var router2 = new FloodRouter { SwarmService = swarm2 }; var ns2 = new PubSubService { LocalPeer = other }; ns2.Routers.Add(router2); await swarm2.StartAsync(); await ns2.StartAsync(); var swarm3 = new SwarmService { LocalPeer = other1 }; var router3 = new FloodRouter { SwarmService = swarm3 }; var ns3 = new PubSubService { LocalPeer = other1 }; ns3.Routers.Add(router3); await swarm3.StartAsync(); await ns3.StartAsync(); try { IPublishedMessage lastMessage2 = null; IPublishedMessage lastMessage3 = null; await swarm1.StartListeningAsync("/ip4/127.0.0.1/tcp/0"); await swarm2.StartListeningAsync("/ip4/127.0.0.1/tcp/0"); await swarm3.StartListeningAsync("/ip4/127.0.0.1/tcp/0"); var cs = new CancellationTokenSource(); await ns2.SubscribeAsync(topic, msg => lastMessage2 = msg, cs.Token); await ns3.SubscribeAsync(topic, msg => lastMessage3 = msg, cs.Token); await swarm1.ConnectAsync(other, cs.Token); await swarm3.ConnectAsync(other, cs.Token); var peers = new Peer[0]; var endTime = DateTime.Now.AddSeconds(3); while (peers.Length == 0) { if (DateTime.Now > endTime) { Assert.Fail("timeout"); } await Task.Delay(100, cs.Token); peers = (await ns2.PeersAsync(topic, cs.Token)).ToArray(); } CollectionAssert.Contains(peers, other1); await ns1.PublishAsync(topic, new byte[] { 1 }, cs.Token); endTime = DateTime.Now.AddSeconds(3); while (lastMessage2 == null || lastMessage3 == null) { if (DateTime.Now > endTime) { Assert.Fail("timeout"); } await Task.Delay(100, cs.Token); } Assert.IsNotNull(lastMessage2); Assert.AreEqual(self, lastMessage2.Sender); CollectionAssert.AreEqual(new byte[] { 1 }, lastMessage2.DataBytes); CollectionAssert.Contains(lastMessage2.Topics.ToArray(), topic); Assert.IsNotNull(lastMessage3); Assert.AreEqual(self, lastMessage3.Sender); CollectionAssert.AreEqual(new byte[] { 1 }, lastMessage3.DataBytes); CollectionAssert.Contains(lastMessage3.Topics.ToArray(), topic); } finally { await swarm1.StopAsync(); await ns1.StopAsync(); await swarm2.StopAsync(); await ns2.StopAsync(); await swarm3.StopAsync(); await ns3.StopAsync(); } }
/// <summary> /// Starts the network services. /// </summary> /// <returns> /// A task that represents the asynchronous operation. /// </returns> /// <remarks> /// Starts the various IPFS and Lib.P2P 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() { _dfsState.IsStarted = true; if (_stopTasks.Count > 0) { throw new Exception("IPFS engine is already started."); } // Repository must be at the correct version. await MigrationManager.MirgrateToVersionAsync(MigrationManager.LatestVersion).ConfigureAwait(false); Log.Debug("starting " + LocalPeer.Id); // Everybody needs the swarm. _stopTasks.Add(async() => { await SwarmService.StopAsync().ConfigureAwait(false); }); await SwarmService.StartAsync().ConfigureAwait(false); var peerManager = new PeerManager { SwarmService = SwarmService }; await peerManager.StartAsync().ConfigureAwait(false); _stopTasks.Add(async() => { await peerManager.StopAsync().ConfigureAwait(false); }); // Start the primary services. var tasks = new List <Func <Task> > { async() => { _stopTasks.Add(async() => await BitSwapService.StopAsync().ConfigureAwait(false)); await BitSwapService.StartAsync().ConfigureAwait(false); }, async() => { _stopTasks.Add(async() => await DhtService.StopAsync().ConfigureAwait(false)); await DhtService.StartAsync().ConfigureAwait(false); }, async() => { _stopTasks.Add(async() => await PingService.StopAsync().ConfigureAwait(false)); await PingService.StartAsync().ConfigureAwait(false); }, async() => { _stopTasks.Add(async() => await PubSubService.StopAsync().ConfigureAwait(false)); await PubSubService.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 ConfigApi.GetAsync("Addresses.Swarm").ConfigureAwait(false); var numberListeners = 0; foreach (string a in json) { try { await SwarmService.StartListeningAsync(a).ConfigureAwait(false); ++numberListeners; } catch (Exception e) { Log.Warning($"Listener failure for '{a}'", e); } } 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(SwarmService) { 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 Bootstrap { Addresses = await BootstrapApi.ListAsync() }; bootstrap.PeerDiscovered += OnPeerDiscovered; _stopTasks.Add(async() => await bootstrap.StopAsync().ConfigureAwait(false)); await bootstrap.StartAsync().ConfigureAwait(false); }, async() => { if (Options.Discovery.DisableRandomWalk) { return; } var randomWalk = new RandomWalk { Dht = DhtApi }; _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"); }