private async Task <IConnection> GetTransferConnectionOutboundIndirectAsync(string username, int token, CancellationToken cancellationToken) { Diagnostic.Debug($"Soliciting indirect transfer connection to {username} with token {token}"); var solicitationToken = SoulseekClient.GetNextToken(); try { PendingSolicitationDictionary.TryAdd(solicitationToken, username); await SoulseekClient.ServerConnection .WriteAsync(new ConnectToPeerRequest(solicitationToken, username, Constants.ConnectionType.Transfer).ToByteArray(), cancellationToken) .ConfigureAwait(false); using (var incomingConnection = await SoulseekClient.Waiter .Wait <IConnection>(new WaitKey(Constants.WaitKey.SolicitedPeerConnection, username, solicitationToken), SoulseekClient.Options.TransferConnectionOptions.ConnectTimeout, cancellationToken) .ConfigureAwait(false)) { var connection = ConnectionFactory.GetConnection( incomingConnection.IPEndPoint, SoulseekClient.Options.TransferConnectionOptions, incomingConnection.HandoffTcpClient()); Diagnostic.Debug($"Indirect transfer connection to {username} ({incomingConnection.IPEndPoint}) handed off. (old: {incomingConnection.Id}, new: {connection.Id})"); connection.Type = ConnectionTypes.Outbound | ConnectionTypes.Indirect; connection.Disconnected += (sender, e) => Diagnostic.Debug($"Transfer connection for token {token} ({incomingConnection.IPEndPoint}) disconnected. (type: {connection.Type}, id: {connection.Id})"); Diagnostic.Debug($"Indirect transfer connection for {token} ({connection.IPEndPoint}) established. (type: {connection.Type}, id: {connection.Id})"); return(connection); } } catch (Exception ex) { Diagnostic.Debug($"Failed to establish an indirect transfer connection to {username} with token {token}: {ex.Message}"); throw; } finally { PendingSolicitationDictionary.TryRemove(solicitationToken, out var _); } }
private async Task <IConnection> GetTransferConnectionOutboundDirectAsync(IPEndPoint ipEndPoint, int token, CancellationToken cancellationToken) { Diagnostic.Debug($"Attempting direct transfer connection for token {token} to {ipEndPoint}"); var connection = ConnectionFactory.GetConnection(ipEndPoint, SoulseekClient.Options.TransferConnectionOptions); connection.Type = ConnectionTypes.Outbound | ConnectionTypes.Direct; connection.Disconnected += (sender, e) => Diagnostic.Debug($"Transfer connection for token {token} to {ipEndPoint} disconnected. (type: {connection.Type}, id: {connection.Id})"); try { await connection.ConnectAsync(cancellationToken).ConfigureAwait(false); } catch (Exception ex) { Diagnostic.Debug($"Failed to establish a direct transfer connection for token {token} to ({ipEndPoint}): {ex.Message}"); connection.Dispose(); throw; } Diagnostic.Debug($"Direct transfer connection for {token} to {connection.IPEndPoint} established. (type: {connection.Type}, id: {connection.Id})"); return(connection); }