Esempio n. 1
0
        /// <inheritdoc />
        public async Task <Peer> FindPeerAsync(MultiHash id, CancellationToken cancel = default)
        {
            // Can always find self.
            if (SwarmService.LocalPeer.Id == id)
            {
                return(SwarmService.LocalPeer);
            }

            // Maybe the swarm knows about it.
            var found = SwarmService.KnownPeers.FirstOrDefault(p => p.Id == id);

            if (found != null && found.Addresses.Any())
            {
                return(found);
            }

            // Ask our peers for information on the requested peer.
            var dQuery = new DistributedQuery <Peer>
            {
                QueryType     = MessageType.FindNode,
                QueryKey      = id,
                Dht           = this,
                AnswersNeeded = 1
            };

            await dQuery.RunAsync(cancel).ConfigureAwait(false);

            // If not found, return the closest peer.
            return(!dQuery.Answers.Any() ? RoutingTable.NearestPeers(id).FirstOrDefault() : dQuery.Answers.First());
        }
Esempio n. 2
0
        /// <inheritdoc />
        public async Task <IEnumerable <Peer> > FindProvidersAsync(Cid id,
                                                                   int limit                = 20,
                                                                   Action <Peer> action     = null,
                                                                   CancellationToken cancel = default)
        {
            var dQuery = new DistributedQuery <Peer>
            {
                QueryType     = MessageType.GetProviders,
                QueryKey      = id.Hash,
                Dht           = this,
                AnswersNeeded = limit,
            };

            if (action != null)
            {
                dQuery.AnswerObtained += (s, e) => action.Invoke(e);
            }

            // Add any providers that we already know about.
            var providers = ContentRouter
                            .Get(id)
                            .Select(pid => pid == SwarmService.LocalPeer.Id
                    ? SwarmService.LocalPeer
                    : SwarmService.RegisterPeer(new Peer {
                Id = pid
            }));

            foreach (var provider in providers)
            {
                dQuery.AddAnswer(provider);
            }

            // Ask our peers for more providers.
            if (limit > dQuery.Answers.Count())
            {
                await dQuery.RunAsync(cancel).ConfigureAwait(false);
            }

            return(dQuery.Answers.Take(limit));
        }