public void EnableAutoSearch(bool allowListener = true, bool allowClient = true) { if (announceResponseEnabled) { throw new InvalidOperationException("Already started."); } announceResponseEnabled = true; var announceMessage = new DiscoveryAnnounceMessage() { PeerId = app.InstanceHash.Hash, Version = app.Version, ServicePort = app.NetworkSettings.TcpServicePort }; if (allowListener) { // enable announcer udpAnnouncer = new UdpPeerDiscoveryListener(app.LoggerFactory, app.CompatibilityChecker, peerRegistry, app.NetworkSettings, announceMessage); udpAnnouncer.Start(); } if (allowClient) { // timer discovery udpDiscovery = new UdpPeerDiscoveryClient(app.LoggerFactory, app.CompatibilityChecker, app.NetworkSettings, announceMessage, peerRegistry); udpDiscoveryTimer = new Timer(DiscoveryTimerCallback, null, TimeSpan.Zero, Timeout.InfiniteTimeSpan); } }
public UdpPeerDiscoveryListener(ILoggerFactory loggerFactory, CompatibilityChecker compatibilityChecker, IPeerRegistry registry, NetworkSettings settings, DiscoveryAnnounceMessage announce) { this.logger = (loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory))).CreateLogger <UdpPeerDiscoveryListener>(); this.compatibilityChecker = compatibilityChecker ?? throw new ArgumentNullException(nameof(compatibilityChecker)); this.registry = registry ?? throw new ArgumentNullException(nameof(registry)); this.settings = settings ?? throw new ArgumentNullException(nameof(settings)); this.announce = announce ?? throw new ArgumentNullException(nameof(announce)); this.announceBytes = settings.MessageSerializer.Serialize(announce); }
public async Task Discover() { using (client = new UdpClient()) { var ip = new IPEndPoint(IPAddress.Broadcast, settings.UdpAnnouncePort); Debug.Assert(announceBytes.Length > 0); var lengthSent = await client.SendAsync(announceBytes, announceBytes.Length, ip); if (lengthSent != announceBytes.Length) { throw new InvalidOperationException("Cannot send discovery datagram."); } var timeout = new CancellationTokenSource(settings.UdpDiscoveryTimeout); while (!timeout.IsCancellationRequested) { DiscoveryAnnounceMessage response = null; try { var responseData = await client.ReceiveAsync().WithCancellation(timeout.Token); response = settings.MessageSerializer.Deserialize <DiscoveryAnnounceMessage>(responseData.Buffer); var endpoint = new IPEndPoint(responseData.RemoteEndPoint.Address, response.ServicePort); if (!compatibilityChecker.IsCompatibleWith(endpoint, response.Version)) { continue; } PeerDiscoveryMode mode = PeerDiscoveryMode.UdpDiscovery; bool isLoopback = response.PeerId.Equals(announce.PeerId); if (isLoopback) { mode |= PeerDiscoveryMode.Loopback; } registry.UpdatePeers(new PeerUpdateInfo[] { new PeerUpdateInfo(endpoint, mode, TimeSpan.Zero) }); } catch (OperationCanceledException) { break; } catch (Exception e) { logger.LogDebug($"Cannot deserialize discovery response: {e}"); } } } }