internal async Task SendAsync(GatewayPayload payload, bool highPriority, WebSocketMessageType msgType, CancellationToken cts) // TODO : заменить CTS на Action { Console.WriteLine($"Sending: {payload.Opcode}"); payload.Sequence = lastSequence; string jsonPayload = JsonConvert.SerializeObject(payload, typeof(GatewayPayload), null); // TODO : сериализацию с помощью внещнего проекта byte[] jsonBytes = Encoding.UTF8.GetBytes(jsonPayload); byte chunksCount = 0; for (int dataLength = jsonBytes.Length; dataLength > 0; dataLength -= chunkSize) { chunksCount++; } PayloadRecovery recovery = new PayloadRecovery(payload, highPriority, msgType); try { using (SocketAccessToken token = highPriority ? socketHelper.GetHighPrioritySendAccess() : socketHelper.GetSendAccess()) { token.OnCancellation(x => ResendPayloadAsync(x), recovery); // TODO : проверить на работоспособность if (chunksCount == 1) { await socket.SendAsync(new ArraySegment <byte>(jsonBytes), msgType, true, token.CancellationToken); } else { for (int i = 0; i < chunksCount; i++) { bool isLastMsg = i == chunksCount; int offset = i * chunkSize, count = isLastMsg ? (jsonBytes.Length - chunkSize * i) : chunkSize; await socket.SendAsync(new ArraySegment <byte>(jsonBytes, offset, count), msgType, isLastMsg, token.CancellationToken); } } } } catch (OperationCanceledException ex) { // TODO : логирование return; } catch (WebSocketException ex) { Reconnect(); return; } Interlocked.Increment(ref payloadSentLastMinute); }
private async Task ResendPayloadAsync(object recoveryData) { PayloadRecovery recovery = recoveryData as PayloadRecovery; await SendAsync(recovery.Payload, recovery.IsHighPriority, recovery.MessageType, CancellationToken.None); }