Пример #1
0
        /// <summary>
        /// Attempts to handle the message on our side in the case it's a backend update
        /// </summary>
        /// <param name="Message">The update in question</param>
        /// <returns>True if the message was handled.  Otherwise, false.</returns>
        private async Task <bool> ProcessUpdate(TLObject Message)
        {
            Logger.Log(Logger.Level.Info, $"Beginning internal update processing of \"{(string)Message["body"]["_"]}\"");

            try
            {
                if (((int)Message["seqno"] & 0x01) != 0)
                {
                    Logger.Log(Logger.Level.Debug, $"Adding \"{(long)Message["msg_id"]}\" to be acked");
                    PendingAcks.Add((long)Message["msg_id"]);
                }

                var args = new object[] { this, new TLObjectEventArgs(new TLObject(Message["body"])) };
                UpdateReceivedEvent.RaiseEventSafe(ref args);

                return((Message["body"].Value <string>("_")) switch
                {
                    "bad_server_salt" => ProcessBadSalt(Message),
                    "bad_msg_notification" => ProcessBadMsgNotification(Message),
                    "future_salts" => ProcessFutureSalts(Message),
                    "gzip_packed" => await ProcessGzipPacked(Message),
                    "msg_container" => ProcessMessageContainer(Message),
                    "msg_detailed_info" => ProcessMessageDetailedInfo(Message),
                    "msg_new_detailed_info" => ProcessNewMessageDetailedInfo(Message),
                    "msg_resend_req" => ProcessMessageResendRequest(Message),
                    "msgs_ack" => ProcessMessageAck(Message),
                    "msgs_all_info" => ProcessMessageInfoAll(Message),
                    "msgs_state_req" => ProcessMessageStateReqest(Message),
                    "new_session_created" => ProcessNewSessionCreated(Message),
                    "pong" => ProcessPong(Message),
                    "rpc_result" => await ProcessRPCResult(Message),
                    _ => true,
                });
            }
Пример #2
0
        private async Task AckHandlerMethod(CancellationToken cancellationToken)
        {
            while (!cancellationToken.IsCancellationRequested)
            {
                try
                {
                    // Send every three minutes
                    await Task.Delay(3 * 60 * 1000, cancellationToken);

                    // Don't run this time if there aren't any messages to acknowledge
                    if (!PendingAcks.Any())
                    {
                        continue;
                    }

                    // Take all the required acks out of the bag
                    var acks = new List <long>();
                    while (PendingAcks.TryTake(out var ack))
                    {
                        acks.Add(ack);
                    }

                    Logger.Log(Logger.Level.Debug, $"Found {acks.Count} messages that need acknowledgement.  Adding them to the payload.");

                    // Create a request that contains the list of acks
                    var Acks_Request = new RequestState(Schema.msgs_ack(new { msg_ids = acks }));

                    // Add the request to both the send queue (to be sent to the server) and
                    // the sent acks queue (in case we need to resend.  We don't want to place
                    // in pending since there shouldn't be a response.
                    SendQueue.Add(Acks_Request);
                    SentAcks.Put(Acks_Request);

                    // Send the acks to the server
                    // ToDo: If the user will be polling for updates, can we skip this line
                    // and let the acks be sent for us?
                    Task unawaited = Task.Run(() => ProcessSendQueue());
                }
                catch (TaskCanceledException)
                {
                    // We don't really care if the task was cancelled.
                    break;
                }
                catch (ObjectDisposedException)
                {
                    // We don't really care if the task was cancelled.
                    break;
                }
                catch (Exception ex)
                {
                    // ToDo: Do we really want to skip all acks when this happens?  Likely we
                    // will encounter the same error again if we reprocess...
                    Logger.Log(Logger.Level.Error, $"An error occurred process acks.  Skipping.\n\n{ex.Message}");
                }
            }
        }