/// <summary> /// Adds a new connection. /// </summary> /// <param name="connection"> /// The <see cref="PeerConnection"/> to add. /// </param> /// <returns> /// The connection that should be used. /// </returns> /// <remarks> /// If a connection already exists to the peer, the specified /// <paramref name="connection"/> is closed and existing connection /// is returned. /// </remarks> public PeerConnection Add(PeerConnection connection) { if (connection == null) { throw new ArgumentNullException(nameof(connection)); } if (connection.RemotePeer == null) { throw new ArgumentNullException(nameof(connection.RemotePeer)); } if (connection.RemotePeer.Id == null) { throw new ArgumentNullException(nameof(connection.RemotePeer.Id)); } _connections.AddOrUpdate( Key(connection.RemotePeer), key => new List <PeerConnection> { connection }, (key, conns) => { if (!conns.Contains(connection)) { conns.Add(connection); } return(conns); } ); if (connection.RemotePeer.ConnectedAddress == null) { connection.RemotePeer.ConnectedAddress = connection.RemoteAddress; } connection.Closed += (s, e) => Remove(e); return(connection); }
/// <summary> /// Remove a connection. /// </summary> /// <param name="connection"> /// The <see cref="PeerConnection"/> to remove. /// </param> /// <returns> /// <b>true</b> if the connection was removed; otherwise, <b>false</b>. /// </returns> /// <remarks> /// The <paramref name="connection"/> is removed from the list of /// connections and is closed. /// </remarks> public bool Remove(PeerConnection connection) { if (connection == null) { return(false); } if (!_connections.TryGetValue(Key(connection.RemotePeer), out var originalConns)) { connection.Dispose(); return(false); } if (!originalConns.Contains(connection)) { connection.Dispose(); return(false); } var newConns = new List <PeerConnection>(); newConns.AddRange(originalConns.Where(c => c != connection)); _connections.TryUpdate(Key(connection.RemotePeer), newConns, originalConns); connection.Dispose(); if (newConns.Count > 0) { var last = newConns.Last(); last.RemotePeer.ConnectedAddress = last.RemoteAddress; } else { connection.RemotePeer.ConnectedAddress = null; PeerDisconnected?.Invoke(this, connection.RemotePeer.Id); } return(true); }
/// <summary> /// Is invoked by the <see cref="SwarmService"/> when a peer is connected to. /// </summary> private void Swarm_ConnectionEstablished(object sender, PeerConnection connection) { SetReachable(connection.RemotePeer); }