Pular para o conteúdo principal

Chat

Trabalhar com Atualizações no Telegram


Trabalhar com atualizações

Quando um cliente está sendo usado ativamente, ocorrem eventos que afetam o usuário atual e sobre os quais ele deve ser informado o mais rápido possível, por exemplo, quando uma nova mensagem é recebida. Para eliminar a necessidade de o próprio cliente baixar periodicamente esses eventos, existe um mecanismo de entrega de atualização no qual o servidor envia notificações ao usuário por meio de uma de suas conexões disponíveis com o cliente.

Inscrever-se para atualizações

Os eventos de atualização são enviados para um usuário autorizado na última conexão ativa (exceto para conexões necessárias para download / upload de arquivos).

Portanto, para começar a receber atualizações, o cliente precisa iniciar a conexão e chamar o método API, por exemplo, para buscar o estado atual .

Sequências de eventos

Todos os eventos são recebidos do soquete como uma sequência de objetos Updates serializados em TL , que podem ser opcionalmente compactados com gzip da mesma forma que as respostas às consultas .

Cada objeto Updates pode conter um ou vários objetos Update , representando diferentes eventos acontecendo.

Para aplicar todas as atualizações em ordem precisa e garantir que nenhuma atualização seja perdida ou aplicada duas vezes, há um seqatributo nos construtores de atualizações e pts(com pts_count) ou qtsatributos nos construtores de atualização . O cliente deve usar esses valores de atributos em combinação com o estado armazenado localmente para aplicar corretamente as atualizações recebidas.

Quando ocorre uma lacuna na sequência de atualizações, ela deve ser preenchida chamando um dos métodos da API. Mais abaixo »

Sequência de atualizações

Como disse anteriormente, cada carga com atualizações tem um tipo TL Updates . Pode-se ver no esquema abaixo que este tipo possui vários construtores.

updatesTooLong#e317af7e = Updates;
updateShort#78d4dec1 update:Update date:int = Updates;
updateShortMessage#2296d2c8 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true id:int user_id:int message:string pts:int pts_count:int date:int fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?int reply_to:flags.3?MessageReplyHeader entities:flags.7?Vector<MessageEntity> = Updates;
updateShortChatMessage#402d5dbb flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true id:int from_id:int chat_id:int message:string pts:int pts_count:int date:int fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?int reply_to:flags.3?MessageReplyHeader entities:flags.7?Vector<MessageEntity> = Updates;
updateShortSentMessage#11f1331c flags:# out:flags.1?true id:int pts:int pts_count:int date:int media:flags.9?MessageMedia entities:flags.7?Vector<MessageEntity> = Updates;
updatesCombined#725b04c3 updates:Vector<Update> users:Vector<User> chats:Vector<Chat> date:int seq_start:int seq:int = Updates;
updates#74ae4240 updates:Vector<Update> users:Vector<User> chats:Vector<Chat> date:int seq:int = Updates;

updatesTooLong indica que há muitos eventos pendentes para serem enviados ao cliente, então é necessário buscá-los manualmente .

Os eventos dentro dos construtores updateShort , normalmente, têm prioridade mais baixa e são transmitidos para um grande número de usuários, ou seja, um dos participantes do chat começou a inserir texto em uma grande conversa ( updateChatUserTyping ).

Os construtores updateShortMessage , updateShortSentMessage e updateShortChatMessage são redundantes, mas ajudam a reduzir significativamente o tamanho da mensagem transmitida para 90% das atualizações. Eles devem ser transformados em updateShort ao receber.

Duas atualizações de construtores restantes updatesCombined fazem parte da sequência Updates. Ambos possuem seqatributo, que indica o estado das Atualizações remotas após a geração das Atualizações e seq_startindica o estado das Atualizações remotas após a primeira das Atualizações no pacote ser gerada. Para atualizações , o seq_startatributo é omitido, porque é assumido que é sempre igual a seq.

Sequências de eventos relacionados a mensagens

Cada evento relacionado a uma caixa de mensagem (mensagem criada, mensagem editada, mensagem excluída, etc) é identificado por um único autoincremented pts (ou qts em caso de chats secretos).

Cada caixa de mensagem pode ser considerada como uma tabela de banco de dados do lado do servidor que armazena mensagens e eventos associados a elas. Todas as caixas são completamente independentes e cada sequência de pts está ligada a apenas uma caixa (veja abaixo).

O objeto de atualização pode conter informações sobre vários eventos (por exemplo, updateDeleteMessages ). É por isso que todas as atualizações individuais podem ter o parâmetro pts_count indicando o número de eventos contidos na atualização recebida (com algumas exceções, neste caso, o pts_count é considerado 0).

Cada canal e supergrupo tem sua caixa de mensagem e sua sequência de eventos como resultado; chats privados e grupos legados de um usuário têm outra sequência de eventos comum . Os bate-papos secretos do usuário têm outra sequência de eventos secretos comuns .

Para recapitular, o cliente deve cuidar da integridade das seguintes sequências para lidar adequadamente com as atualizações:

  • Sequência de atualizações (seq)
    • Sequência de caixa de mensagem comum (pts)
    • Sequência de caixa de mensagem secreta (qts)
    • Sequência 1 da caixa de mensagem do canal (pts)
    • Sequência 2 da caixa de mensagem do canal (pts)
    • Sequência 3 da caixa de mensagem do canal (pts)
    • e assim por diante...

Buscando estado

estado de atualização comum é representado pelo construtor updates.State . Quando o usuário efetua login pela primeira vez, é necessário chamar updates.getState para armazenar o estado de atualização mais recente (que não será o estado inicial absoluto, apenas o estado mais recente no momento atual). O estado de atualização comum também pode ser obtido em updates.differenceTooLong .

estado de atualização do canal é representado simplesmente pelos pontos da sequência de eventos: ao fazer login pela primeira vez, o estado do canal inicial pode ser obtido a partir do construtor de diálogo ao buscar diálogos, a partir das informações completas do canal ou pode ser recebido como uma atualização updateChannelTooLong .

estado de atualização de bate-papo secreto é representado pelos qts da sequência de eventos secretos, ele está contido em updates.State do estado de atualização comum .

estado da sequência de atualizações é representado pela data e seq da sequência de atualizações , ele está contido em updates.State do estado de atualização comum .

Tratamento de atualização

O tratamento de atualizações em clientes Telegram consiste em receber eventos, certificando-se de que não houve gaps e nenhum evento foi perdido com base no estado armazenado localmente da sequência de eventos correspondente e, em seguida, atualizar o estado armazenado localmente com base nos parâmetros recebidos.

Quando o cliente recebe carga útil com atualizações serializadas, em primeiro lugar, ele precisa percorrer todos os objetos Update aninhados e verificar se eles pertencem a alguma das sequências de caixa de mensagem (têm ptsou qtsparâmetros). Essas atualizações precisam ser tratadas separadamente de acordo com o estado local correspondente e novos ptsqtsvalores. Detalhes abaixo "

Depois que as atualizações da caixa de mensagem forem tratadas, se houver alguma outra atualização restante, o cliente precisará tratá-la seqDetalhes abaixo "

pts: verificando e aplicando

Aqui, local_ptsserá o estado local, ptsserá o estado remoto, pts_countserá o número de eventos na atualização.

Se local_pts + pts_count === pts, a atualização pode ser aplicada. Se local_pts + pts_count > pts, a atualização já foi aplicada e deve ser ignorada. Se local_pts + pts_count < ptshouver uma lacuna de atualização que deve ser preenchida .

Por exemplo, vamos supor que o cliente tenha o seguinte estado local para o canal 123456789:

local_pts = 131

Agora vamos supor que um updateNewChannelMessage do canal 123456789seja recebido com pts = 132pts_count=1Uma vez que local_pts + pts_count === pts, o número total de eventos desde o último estado armazenado é, de fato, igual a pts_count: isso significa que a atualização pode ser aceita com segurança e o controle remoto ptsaplicado:

local_pts = 132

Desde a:

  • ptsindica o estado do servidor após os novos eventos de mensagem do canal serem gerados
  • pts_count indica o número de eventos na nova atualização do canal
  • O estado do servidor antes da geração do novo evento de mensagem do canal deve ser:, pts_before = pts - pts_count = 131que é, de fato, igual ao nosso estado local.

Agora vamos supor que um updateNewChannelMessage do canal 123456789seja recebido com pts = 132pts_count=1Desde local_pts + pts_count > pts133 > 132), a atualização é ignorada porque já tratamos dessa atualização (na verdade, nossa atual local_ptsfoi definida por esta mesma atualização e foi reenviada duas vezes devido a problemas de rede ou outros problemas).

Agora vamos supor que um updateDeleteChannelMessages do canal 123456789seja recebido com pts = 140pts_count=5Como local_pts + pts_count < pts137 < 140), isso significa que as atualizações foram perdidas e a lacuna deve ser recuperada.

Bate-papos secretos

Todo o processo é muito semelhante para bate-papos secretos, mas existe em qtsvez de ptse os eventos nunca são agrupados, portanto, presume-se que qts_counté sempre igual a 1.

seq: verificando e aplicando

No nível superior, ao lidar com atualizações recebidas updatesCombined, há três casos possíveis: Se local_seq + 1 === seq_start, as atualizações podem ser aplicadas. Se local_seq + 1 > seq_start, as atualizações já foram aplicadas e devem ser ignoradas. Se local_seq + 1 < seq_starthouver uma lacuna de atualizações que deve ser preenchida (updates.getDifference deve ser usado como com sequências de eventos comuns e secretas).

Se as atualizações foram aplicadas, o estado das atualizações locais deve ser atualizado com seqe a datepartir do construtor.

Para todos os outros construtores do tipo Updates, não há necessidade de verificar seqou alterar um estado local.

Recuperando lacunas

Para fazer isso, updates.getDifference (estado comum / secreto) ou updates.getChannelDifference (estado do canal) com os respectivos estados locais devem ser chamados. Esses métodos também devem ser chamados na inicialização, para buscar novas atualizações (de preferência com alguns sinalizadores para reduzir a carga do servidor, consulte a documentação do método). A obtenção manual de atualizações também é necessária nas seguintes situações:

  • Perda de sincronia: uma lacuna foi encontrada em seq / pts / qts (conforme descrito acima). Pode ser útil esperar até 0,5 segundo nesta situação e abortar a sincronização caso chegue uma nova atualização que preencha a lacuna.
  • Perda de sessão no servidor: o cliente recebe uma notificação de nova sessão criada . Isso pode ser causado pela coleta de lixo no servidor MTProto ou pela reinicialização do servidor.
  • Atualização incorreta: o cliente não consegue desserializar os dados recebidos.
  • Atualização incompleta: o cliente não possui dados sobre um bate-papo / usuário de um dos construtores encurtados, como updateShortChatMessage , etc.
  • Longo período sem atualizações: sem atualizações por 15 minutos ou mais.
  • O servidor solicita que o cliente busque a diferença usando updateChannelTooLong ou updatesTooLong .

Ao chamar updates.getDifference se o construtor updates.differenceSlice for retornado em resposta, a diferença total era muito grande para ser recebida em uma solicitação. O status intermediário, intermediário_estado , deve ser salvo no cliente e a consulta deve ser repetida, usando o status intermediário como o status atual.

Para buscar a diferença de atualizações de um canal, updates.getChannelDifference é usado. Se a diferença for muito grande para ser recebida em uma solicitação, o finalsinalizador do resultado não será definido (consulte os documentos ). O status intermediário, representado pelos pts , deve ser salvo no cliente e a consulta deve ser repetida, utilizando o status intermediário como o status atual.

Por motivos de desempenho e para uma melhor experiência do usuário, o cliente pode definir o tamanho máximo do gap a ser preenchido: o pts_total_limitparâmetro de updates.getDifference e o limitparâmetro para updates.getChannelDifference podem ser usados.

Se a lacuna for muito grande e houver muitas atualizações para buscar, um *TooLongconstrutor será retornado. Nesse caso, o cliente deve buscar novamente o estado , reiniciar a busca de atualizações desse estado e seguir as instruções que podem ser encontradas aqui .

Recomenda-se usar limite 10-100para canais e 1000-10000outros.

Implementações de exemplo

As implementações também devem ter o cuidado de adiar as atualizações recebidas via socket enquanto preenchem as lacunas nas sequências de eventos e atualizações, bem como evitar o preenchimento das lacunas na mesma sequência.

Implementações de exemplo: tdlib , MadelineProto .

Uma maneira interessante e fácil de implementar isso, em vez de usar vários bloqueios, é executando loops de fundo, como em MadelineProto » .

PUSH Notificações sobre atualizações

Se um cliente não tiver uma conexão ativa no momento de um evento, as Notificações PUSH também serão úteis.


 

Postagens mais visitadas deste blog

Login via Código QR (QR Code) no Telegram

Login via QR code QR code  login flow. Related TL schema: auth.loginToken #629f1980 expires: int token: bytes = auth.LoginToken ; auth.loginTokenMigrateTo #68e9916 dc_id: int token: bytes = auth.LoginToken ; auth.loginTokenSuccess #390d5c5e authorization: auth.Authorization = auth.LoginToken ; updateLoginToken #564fe691 = Update ; authorization #ad01d61d flags: # current:flags.0? true official_app:flags.1? true password_pending:flags.2? true hash: long device_model: string platform: string system_version: string api_id: int app_name: string app_version: string date_created: int date_active: int ip: string country: string region: string = Authorization ; ---functions--- auth.exportLoginToken #b1b41517 api_id: int api_hash: string except_ids: Vector < int > = auth.LoginToken ; auth.acceptLoginToken #e894ad4d token: bytes = Authorization ; auth.importLoginToken #95ac5ce4 token: bytes = auth.LoginToken ; Exporting a login token First of all,  auth.exportL

Versão mais recente do WhatsApp

  Por favor, baixe a versão mais recente do WhatsApp. BAIXAR AGORA Versão 2.21.1.8 Requisitos mínimos Android OS 4.0.3 ou posterior Recomendamos um plano de dados ilimitado Tablets não são compatíveis Fontes desconhecidas qcom.c: LGPL 2.1 ( Modificações do WhatsApp )

Ir para as Configurações no Signal

Android Configurações do aplicativo No Signal, toque seu perfil   para ver as configurações do Signal. Configurações de conversas Abra a conversa com seu contato. Toque no nome ou cabeçalho do contato para ver as configurações de conversas.   iOS Configurações do aplicativo No Signal, toque no seu perfil   para visualizar as configurações do Signal. Configurações de conversas Abra a conversa com seu contato. Toque no nome ou no cabeçalho do contato para visualizar as configurações da conversa. Desktop Configurações do aplicativo No Signal, toque no seu perfil   >   Preferências... para ver as configurações do Signal. Configurações de conversas Veja a conversa com seu contato. Selecione Menu   para ver as configurações de conversa.