private void ConnectSingleIpAsync(string ip, [NotNull] TaskCompletionSource <IChannel> tcs, ICollection <string> candidateIps) { Task.Run(async() => { bool socketAdopted = false; var client = new TcpClient(); Action disposeTcpClient = () => { // ReSharper disable once AccessToModifiedClosure if (socketAdopted) { return; } client?.Dispose(); client = null; Env.Logger.Log($"clean up [{ip}]", nameof(ChannelManager)); }; try { Env.Logger.Log($"Try to connect to [{ip}]", nameof(ChannelManager)); await client.ConnectAsync(ip, port); //这个耗时的过程不能取消,cancel token就没多大意义了。 if (!tcs.IsEnded() && client.Connected) { IPEndPoint remote = client.Client.RemoteEndPoint as IPEndPoint; if (remote != null) { socketAdopted = true; TcpChannel channel = new TcpChannel(client) { IsInitiative = true, RemoteIP = remote.Address.ToString() }; socketAdopted = tcs.TrySetResult(channel); if (socketAdopted) { Env.Logger.Log($"Connected to [{ip}] successfully", nameof(ChannelManager)); } } } //如果这个不成功,不要设置result,让别的连接尝试做这个工作。 } catch (Exception e) { //如果全都失败应该早点退出。 Env.Logger.Log($"Create TCP Client failed {ip} reason {e.Message}", nameof(ChannelManager)); } finally { if (!socketAdopted) { candidateIps.Remove(ip); if (candidateIps.Count == 0) { tcs.TrySetResult(null); } disposeTcpClient(); } } }); }
protected internal sealed override bool Process(ConversationMessage message) { switch (State) { case RequesterState.RequestRecovering: if (message is ConversationRecoverAgreedMessage) { //对方同意恢复会话。 State = RequesterState.Running; OnRecoverAgreed(message as ConversationRecoverAgreedMessage); RecoverAgreed?.Invoke(); } else if (message is ConversationRejectMessage) { var rm = message as ConversationRejectMessage; State = RequesterState.Rejected; End(); OnRecoverRejected(rm); RecoverRejected?.Invoke(rm.RejectCode); } else { //对方再ConversationAgree或者Reject之前发来的消息,到底要不要处理?怎样才能保证对方不在我准备好之前发消息过来? //其他消息,不理会。 OnMessageReceived(message); } break; case RequesterState.Requesting: if (message is ConversationAgreeMessage) { WasAgreed = true; State = RequesterState.Running; OnRequestAgreed(message as ConversationAgreeMessage); Agreed?.Invoke(); if (!Response.IsEnded()) { Response?.SetResult(message); } else { End(); } } else if (message is ConversationRejectMessage) { if (!Response.IsEnded()) { Response?.SetResult(message); } State = RequesterState.Rejected; //终止此会话 End(); Rejected?.Invoke(); } else { //对方再ConversationAgree或者Reject之前发来的消息,到底要不要处理?怎样才能保证对方不在我准备好之前发消息过来? //其他消息,不理会。 OnMessageReceived(message); } break; case RequesterState.Running: OnMessageReceived(message); break; } return(true); }