From 005752e7489b4324420b24950d1d241bd5e880c1 Mon Sep 17 00:00:00 2001 From: oneRain Date: Wed, 24 Jun 2020 17:45:27 +0800 Subject: [PATCH] =?UTF-8?q?chore:=20=E6=94=AF=E6=8C=81=20command=20?= =?UTF-8?q?=E8=8A=82=E6=B5=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Internal/Connection/LCConnection.cs | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/Realtime/Realtime/Internal/Connection/LCConnection.cs b/Realtime/Realtime/Internal/Connection/LCConnection.cs index 3b797ac..0c8de85 100644 --- a/Realtime/Realtime/Internal/Connection/LCConnection.cs +++ b/Realtime/Realtime/Internal/Connection/LCConnection.cs @@ -60,6 +60,7 @@ namespace LeanCloud.Realtime.Internal.Connection { /// 请求回调缓存 /// private readonly Dictionary> responses; + private readonly List sendingRequests; private int requestI = 1; @@ -79,6 +80,7 @@ namespace LeanCloud.Realtime.Internal.Connection { internal LCConnection(string id) { this.id = id; responses = new Dictionary>(); + sendingRequests = new List(); heartBeat = new LCHeartBeat(this, OnDisconnect); router = new LCRTMRouter(); ws = new LCWebSocketClient { @@ -127,6 +129,22 @@ namespace LeanCloud.Realtime.Internal.Connection { /// /// internal async Task SendRequest(GenericCommand request) { + if (IsIdempotentCommand(request)) { + GenericCommand sendingReq = sendingRequests.Find(item => { + // TRICK 除了 I 其他字段相等 + request.I = item.I; + return Equals(request, item); + }); + if (sendingReq == null) { + sendingRequests.Add(request); + } else { + LCLogger.Warn("duplicated request"); + if (responses.TryGetValue(sendingReq.I, out TaskCompletionSource waitingTcs)) { + return await waitingTcs.Task; + } + } + } + TaskCompletionSource tcs = new TaskCompletionSource(); request.I = requestI++; responses.Add(request.I, tcs); @@ -187,6 +205,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); @@ -303,5 +324,16 @@ namespace LeanCloud.Realtime.Internal.Connection { internal void Resume() { _ = Reconnect(); } + + private static bool IsIdempotentCommand(GenericCommand command) { + return !( + command.Cmd == CommandType.Direct || + (command.Cmd == CommandType.Session && command.Op == OpType.Open) || + (command.Cmd == CommandType.Conv && + (command.Op == OpType.Start || + command.Op == OpType.Update || + command.Op == OpType.Members)) + ); + } } }