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); }
public bool IsConnectedTo(IPEndPoint endpoint) { return(_Nodes.Contains(endpoint)); }