From 5976f5dbb306d49b3e6a1fe890b42c4a15f9aa40 Mon Sep 17 00:00:00 2001 From: oneRain Date: Sun, 28 Jun 2020 12:30:29 +0800 Subject: [PATCH] =?UTF-8?q?chore:=20=E7=AE=80=E5=8C=96=E7=BC=93=E5=AD=98?= =?UTF-8?q?=E7=9A=84=E8=AF=B7=E6=B1=82/=E5=BA=94=E7=AD=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Internal/Connection/LCConnection.cs | 34 +++++++++++-------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/Realtime/Realtime/Internal/Connection/LCConnection.cs b/Realtime/Realtime/Internal/Connection/LCConnection.cs index c4703fa..1e7732a 100644 --- a/Realtime/Realtime/Internal/Connection/LCConnection.cs +++ b/Realtime/Realtime/Internal/Connection/LCConnection.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using System.Text; using System.Collections.Generic; using System.Threading.Tasks; @@ -12,6 +13,17 @@ namespace LeanCloud.Realtime.Internal.Connection { /// 连接层,只与数据协议相关 /// public class LCConnection { + // 请求/应答比对,即 I 相等 + class RequestAndResponseComparer : IEqualityComparer { + public bool Equals(GenericCommand x, GenericCommand y) { + return true; + } + + public int GetHashCode(GenericCommand obj) { + return obj.I; + } + } + /// /// 连接状态 /// @@ -59,8 +71,7 @@ namespace LeanCloud.Realtime.Internal.Connection { /// /// 请求回调缓存 /// - private readonly Dictionary> responses; - private readonly List sendingRequests; + private readonly Dictionary> requestToResponses; private int requestI = 1; @@ -79,8 +90,8 @@ namespace LeanCloud.Realtime.Internal.Connection { internal LCConnection(string id) { this.id = id; - responses = new Dictionary>(); - sendingRequests = new List(); + requestToResponses = new Dictionary>(new RequestAndResponseComparer()); + heartBeat = new LCHeartBeat(this, OnDisconnect); router = new LCRTMRouter(); ws = new LCWebSocketClient { @@ -130,25 +141,23 @@ namespace LeanCloud.Realtime.Internal.Connection { /// internal async Task SendRequest(GenericCommand request) { if (IsIdempotentCommand(request)) { - GenericCommand sendingReq = sendingRequests.Find(item => { + GenericCommand sendingReq = requestToResponses.Keys.FirstOrDefault(item => { // TRICK 除了 I 其他字段相等 request.I = item.I; return Equals(request, item); }); if (sendingReq != null) { LCLogger.Warn("duplicated request"); - if (responses.TryGetValue(sendingReq.I, out TaskCompletionSource waitingTcs)) { + if (requestToResponses.TryGetValue(sendingReq, out TaskCompletionSource waitingTcs)) { return await waitingTcs.Task; } LCLogger.Error($"error request: {request}"); - } else { - sendingRequests.Add(request); } } TaskCompletionSource tcs = new TaskCompletionSource(); request.I = requestI++; - responses.Add(request.I, tcs); + requestToResponses.Add(request, tcs); try { await SendCommand(request); } catch (Exception e) { @@ -196,7 +205,7 @@ namespace LeanCloud.Realtime.Internal.Connection { if (command.HasI) { // 应答 int requestIndex = command.I; - if (responses.TryGetValue(requestIndex, out TaskCompletionSource tcs)) { + if (requestToResponses.TryGetValue(command, out TaskCompletionSource tcs)) { if (command.HasErrorMessage) { // 错误 ErrorCommand error = command.ErrorMessage; @@ -206,12 +215,9 @@ namespace LeanCloud.Realtime.Internal.Connection { LCException exception = new LCException(code, detail); tcs.TrySetException(exception); } else { - sendingRequests.RemoveAll(item => { - return item.I == command.I; - }); tcs.TrySetResult(command); } - responses.Remove(requestIndex); + requestToResponses.Remove(command); } else { LCLogger.Error($"No request for {requestIndex}"); }