예제 #1
0
        public NodeSet CreateNodeSet(int size)
        {
            if (size > 1000)
            {
                throw new ArgumentOutOfRangeException("size", "size should be less than 1000");
            }
            TraceCorrelation trace = new TraceCorrelation(NodeServerTrace.Trace, "Creating node set of size " + size);
            NodeSet          set   = new NodeSet();

            using (trace.Open())
            {
                while (set.Count() < size)
                {
                    var peerToGet   = size - set.Count();
                    var activePeers = PeerTable.GetActivePeers(1000);
                    activePeers = activePeers.Where(p => !set.Contains(p.NetworkAddress.Endpoint)).ToArray();
                    if (activePeers.Length < peerToGet)
                    {
                        DiscoverPeers(size);
                        continue;
                    }
                    NodeServerTrace.Information("Need " + peerToGet + " more nodes");

                    BlockingCollection <Node> handshakedNodes = new BlockingCollection <Node>(peerToGet);
                    CancellationTokenSource   handshakedFull  = new CancellationTokenSource();

                    try
                    {
                        Parallel.ForEach(activePeers,
                                         new ParallelOptions()
                        {
                            MaxDegreeOfParallelism = 10,
                            CancellationToken      = handshakedFull.Token
                        }, p =>
                        {
                            if (set.Contains(p.NetworkAddress.Endpoint))
                            {
                                return;
                            }
                            Node node = null;
                            try
                            {
                                node = GetNodeByPeer(p, handshakedFull.Token);
                                node.VersionHandshake(handshakedFull.Token);
                                if (node != null && node.State != NodeState.HandShaked)
                                {
                                    node.Disconnect();
                                }
                                if (!handshakedNodes.TryAdd(node))
                                {
                                    handshakedFull.Cancel();
                                    node.Disconnect();
                                }
                                else
                                {
                                    var remaining = (size - set.Count() - handshakedNodes.Count);
                                    if (remaining == 0)
                                    {
                                        handshakedFull.Cancel();
                                    }
                                    else
                                    {
                                        NodeServerTrace.Information("Need " + remaining + " more nodes");
                                    }
                                }
                            }
                            catch (Exception)
                            {
                                if (node != null)
                                {
                                    node.Disconnect();
                                }
                            }
                        });
                    }
                    catch (OperationCanceledException)
                    {
                    }
                    set.AddNodes(handshakedNodes.ToArray());
                }
            }
            return(set);
        }
예제 #2
0
 public bool IsConnectedTo(IPEndPoint endpoint)
 {
     return(_Nodes.Contains(endpoint));
 }