Pull to refresh
2
0
Send message

Это хорошо.
А с Qt что? strings на статически слинкованном бинаре (например отсюда) показывает qt_lcnsprod=OpenSource and qt_lcnsuser=Open Source. Использование статической линковки требует либо предоставления исходников, либо платной лицензии Qt. У mail.ru бюджета на это не хватает?

Ложь. В Telegram Desktop для интерфейса используются Qt Widgets. Вот код:
https://github.com/telegramdesktop/tdesktop/blob/dev/Telegram/SourceFiles/history/view/history_view_message.cpp

В Telegram в информацию о пользователе включаются ссылки на файлы большой и маленькой аватарки, если она вообще есть. Ссылка на файл — 24 байта.
Весь профиль – это флаги (контакт, бот, заблокирован и т.д.) + {first,last,user}name + phone (если доступен) + online status — от 40 до 320 байт при максимально длинных именах (по 64 символа по 4 байта utf8) и заданной аватарке.
В большинстве случаев, профиль (тип User) занимает меньше 100 байт. Сервер Telegram сам решает (в зависимости от типа чата и другихпараметров), какую дополнительную информацию включать в событие и может не отправлять одни и те же данные без необходимости.

Количество прикрепляемых диалогов приходит параметром конфигурации сервера, то есть его легко могут увеличить в любой момент для всех клиентов сразу.
Единственное ограничение на уровне протокола заключается в том, что запрос прикреплённых диалогов (getPinnedDialogs) не поддерживает "пагинацию", но можно без проблем воспользоваться и обычным getDialogs (ну да, результат может включать и обычные диалоги, не велика проблема).

Чат на 200к в группе, ну онлайн пусть около 20-30к. Телеграм использует ленивую загрузку списка участников и да, вместо загрузки 200 000 vcard при подключении, он отправляет аналог vcard отправителя (100-250 байт) в событие добавления сообщения в группу. При ленивой загрузке (участников) это всё-равно следующее, что запросили бы клиенты.


Именно включение данных о контексте, на мой взгляд, является той фичей, которой было бы здорово научиться остальным (XMPP/Matrix).
Например, когда мы запрашиваем историю сообщений мега-группы, мы, опять-таки, вместе с сообщениями получаем информацию обо всех упомянутых пользователях. И смысл тут не в экономии трафика, а в экономии round-trip'ов и максимально быстрой работе клиентов (из этого предложения не следует, что все клиенты Телеграм работают быстро. Я говорю о возможностях протокола.)


Я сравниваю с XMPP и Matrix, потому что знаком с их протоколами, хотя и не так детально, как с Telegram.
IRC, при всём уважении и при том, что я им пользуюсь, не отвечает современным представлениям об удобстве. Ни картинку (inline) не отправить, ни даже сообщение отредактировать. О поиске сообщений в канале за определённую дату и от определённого пользователя даже мечтать не приходится.


Я занимаюсь разработкой коммерческого IM и у меня была задача разобраться, как приблизить наш протокол (закрытый, бинарный) по скорости к протоколу Телеграм. Так что я сужу не только по своему клиенту/серверу Телеграм, но и по недельному целенаправленному анализу моих коллег (работа при потере пакетов и больших задержках и т.д.). При больших сетевых задержках (не редкость при работе по 2G/3G в местах с плохим покрытием) всё становится просто очевидно.

Это – публичные RSA ключи сервера. Худшее, что может произойти (если в Telegram LLC произойдёт утечка) — подмена сервера.

Я говорю о большом количестве пользователей в одном групповом чате (в одной комнате, если говорить в терминах XMPP), а не просто на сервере.


Например, вот тут пишут, что 10k на комнату не заработало:
https://stackoverflow.com/questions/41748148/what-is-the-max-number-of-users-per-room-on-ejabberd


Даже в редакции от 2019-05-15, XEP-0045: Multi-User Chat говорит о том, что:


the service MUST then return the full member list to the admin

https://xmpp.org/extensions/xep-0045.html#modifymember


Многие места в протоколе XMPP не рассчитаны на огромное количество пользователей и приводят к большой нагрузке на сервер. Например, в Telegram сообщение из mega-группы (на усмотрение сервера; практически всегда) приходит сразу с информацией как о чате (на случай, если он не был загружен вместе со списком недавних диалогов), так и о контакте-отправителе сообщения. Это позволяет клиенту сразу отображать новое сообщение без дополнительных задержек и лишней нагрузки на сервер. Разве XMPP позволяет серверу «просто так» или вместе с сообщением передать клиенту информацию об отправителе?


В общем я не вижу какой-то rocket science в том что они делают ;)

Решение использовать ленивую загрузку списка участников чата и упреждающее включение информации (об отправителе и чате; first/last name, avatar, online status и т.д.) в сообщение сервера о новом сообщение — является простым и эффективным.
Rocket science я бы это не назвал, но, например, Matrix так не делает (клиент вынужден отдельным запросом получать информацию об отправителе). Используя пример Telegram, разработчики могут оптимизировать протокол Matrix и это здорово!

Я во многом согласен с технической частью статьи. Вы (утверждаете, что) написали клиент, я же настолько намучился с реверсом и с официальным сервером Telegram, что написал как клиент, так и свой (простой) сервер.
Я не привожу ссылку, потому что считаю неуместным рекламировать (а многие сочтут ссылку именно так) свой клиент и сервер в комментариях к чужой статье. Кому нужно — без проблем могут найти на github. Кому не нужно — спокойно пройдут мимо.


Вместо того, чтобы обмениться опытом, вы пытаетесь ставить мне двойки и предполагать, что у меня «кругозор не велик». Я мог бы вам помочь. Мой сервер мог бы упростить вам разработку. Вместо этого вы хотите «с садистской ухмылкой давить еще сильнее».
Ну и флаг вам в руки. :)

явственно видно, что Телеграм-команда мешает людям реализовывать свои API эффективно, то есть, они делают людям плохо, а следовательно, их надо наказывать за это, безжалостно и беспощадно

в следующем комменте, с садистской ухмылкой, пожалуй стану давить еще сильнее

чем более выпукло обнажать неадекват, тем тоже лучше для лечения.

Не могу не признать, что вам удалось достаточно выпукло обнажить неадекват.


Вы не сообщили мне ничего нового, интересного или полезного. Похоже, что и я не смог вам ничего объяснить. Я бы продолжил разговор, если бы вы соблюдали «принятые в среде профессионалов» нормы поведения (например — не переходили на личности), но в данном случае считаю продолжение беседы бессмысленным и нецелесообразным.

Мы щас про андроид так то )

Статья — про протокол Telegram. Я комментировал и продолжаю комментировать протокол. В частности — функцию ping_with_disconnect. Когда и как разговор стал про Android?

Это так не работает. Ты либо тратишь батарейку на поддержание wakelock-ов и keepalive-трафик, либо отваливаешься.

Ну, у меня — работает на Sailfish OS. Настраиваю ping_with_disconnect на 45 секунд и пробуждение приложения на каждые 30 секунд.


https://git.merproject.org/mer-core/nemo-keepalive/blob/master/lib/backgroundactivity.h#L54

архитектура насквозь велосипедная

Что есть — то есть. :) У Telegram куча своих велосипедов, зато ездят быстро.


Как выглядит подключение приложение после пробуждения в Telegram?
Клиент: сессия-123456-дай-диалоги
Сервер: ОК-первый-контакт-556-второй-738-третий-129-кстати-первый-это-вася, второй-дима, третий-саша,-от-васи-пять-непрочитанных-последнее-сообщение-ты-тут?-от-димы-...


То есть через сетевой пинг до сервера и обратно, буквально с первого пакета, Telegram готов отобразить начало списока диалогов со всеми данными и последними сообщениями. Разве что без аватарок (они обычно есть в кеше). Быстрее просто некуда и больше никто из IM так не умеет.


TLS

Достаточно быстрое и безопасное кеширование сессий появилось только в TLS 1.3. См, например, https://blog.cloudflare.com/introducing-0-rtt/


+JSON — и погнали.

Telegram экономят каждый байт трафика, так что на json они бы явно не согласились. Может CBOR бы подошёл.

Вот! Отличный ответ! Его-то я и ждал :)


Обязана быть спецификация

Знакомы с поговоркой «дарённому коню в зубы не смотрят»? В случае, если вы заказываете/оплачиваете разработку, вы можете выдвигать свои требования. Хоть спецификацию просить, хоть эталонную реализацию («хозяин — барин»).


Telegram LLC вправе сам решать, какие данные о своих разработках он будет (или не будет) публиковать.
Вся статья сквозит идеей о том, что Telegram кому-то чем-то обязаны. Вы ещё к WhatsApp и Facebook Messenger с такими требованиями обратитесь :).


Поймите меня правильно (хотя пока это не удаётся), за время разработки клиента я и сам столкнулся со множеством интересных моментов и могу очень долго рассказывать о проблемах в Telegram. Но перед этим нужно признать, что у Telegram получилось (на практике) лучше, чем у всех остальных. И за документацию, какой бы она ни была, и за открытый код клиентов — нужно в первую очередь сказать спасибо. И только после этого конструктивно (без характеристик, типа «наркомания») рассуждать о технических недостатках протокола. Если бы не Telegram, то в XMPP и Matrix было бы совсем скучно, потому что остальные (Facebook, WhatsApp, Viber и другие) далеко не настолько дружелюбны.


Продолжу по пунктам:


Ротация — да. Терять при этом данные — нет.

Клиент отправил заведомо недостоверные (с точки зрения аутентификации) данные (всё-равно, что накосячил с подписью). С чего бы серверу их сохранять? Сервер предоставляет возможность делать всё эффективно и правильно — можно даже запрашивать соль на несколько часов вперёд.


Нет, это не является обычной практикой, уровень TCP плюс некоторые специальные вещи — единственные, где такая буферизация нормально. В прикладном коде такие слои городить нечего.

В статье правильно написано, что необходимо сохранять, например, исходящие сообщения до получения подтверждения от сервера. Так что в реальном мире в прикладном коде приходится это всё городить, чтобы обеспечить лучший UX для пользователя.


Нет, это не соединение.

Нет, соединение. :-) Если хотите, можете посмотреть общепринятое значение слова «соединение» (только не нужно додумывать что-то, чтобы это опровергать). Я же не написал, например, «TCP соединение».


Нет, нельзя так сказать.

Вы не можете указывать, кому и как можно или нельзя говорить. Я считаю, что выразился достаточно понятно.


Неверное понимание работы TCP

Наверно это потому, что речь не о TCP.


речь в этом месте была о подтверждении получения, т.е. освобождении буферов противоположной стороны

Я процитировал абзац про ping_delay_disconnect с большим интервалом и написал комментарий именно к нему.


Если же нас сворачивают, значит пользователю это неактуально — наоборот, для энергосбережения надо сообщить серверу как можно раньше, что мы оффлайн

Да не хотим мы быть offline! Мы хотим быть online (получать сообщения сразу), но не тратить аккумулятор впустую.


P.S.: С вами трудно поддерживать конструктивный разговор. Пожалуйста, оставьте свои оценки (например — двойки) себе. Я считаю, что статья была бы значительно лучше, если бы техническая часть не была так перемешана с выплеском эмоций.


P.P.S.: При написании сервера я собрал ещё вторую порцию граблей и я тоже в восторге от документации. Вот пример:


https://core.telegram.org/api/optimisation#server-salt


At present, a single salt’s lifespan is 1 hour

https://core.telegram.org/mtproto/description#server-salt


{server salt is} periodically (say, every 24 hours) changed (separately for each session)

https://core.telegram.org/mtproto/service_messages#request-for-several-future-salts


a server salt is attached to the authorization key rather than being session-specific

По пунктам:


TL (Type Language) и его схема

Для разработки простого клиента не нужно досконально разбираться в TL. До появления флагов можно было вообще за один вечер написать генератор типов и RPC запросов. Когда появились флаги и стали добавляться сложные типы, то да, пришлось немного пореверсить и почитать код других парсеров TL.


если Ваша соль "протухла", то сообщение (запрос) — просто потеряется. Сервер, конечно, сообщит новую соль, выдав new_session_created — но со старым придется как-то делать перепосылку, например.

Ротация в криптографии — обычное дело. Сервер отправит BadMsgNotification типа bad_server_salt. Запоминать отправляемые сообщения — это обычная практика. «Как-то делать перепосылку» придётся и в случае обрыва TCP соединения.


Серверу разрешено вообще дропать сессии и отвечать таким образом по многим поводам.

Чаще всего, сервер возвращает RPC Error — включая случаи, когда он не может десериализовать сообщение. Если продолжение невозможно (из-за некорректных данных на транспортном уровне), тогда сервер возвращает 4х байтный код ошибки и, действительно, рвёт соединение.


С трудом, но можно представить себе какую-то пользу, если человек занимается отладкой, причем в интерактивном режиме — спросить у сервера, что да как. Но здесь описываются запросы в обе стороны.

Для секретных чатов используется вложенное соединение MTProto, защищённое end-to-end шифрованием. В таких случаях оба клиента могут отправлять друг-другу запросы (можно сказать, что протокол используется в режиме peer-to-peer).


И о пингах: <...> Да вы с ума сошли?! За 60 секунд поезд въедет на станцию… <...> есть алгоритм Нагла <...> дефолтное значение задержи — 200 миллисекунд. Если вам так уж хочется изобразить нечто похожее и сэкономить на возможной паре пакетов — ну отложите, накрайняк, на 5 секунд, или чему там сейчас равен таймаут сообщения "User is typing...". Но не больше.

Ну и зачем пользователям или серверу знать с точностью до 200 мс или 5 с, что пользователь ушёл в offline? Ну и в чём проблема того, что приложение на телефоне скажет ОС, что его нужно будить каждые 30/60 секунд (пробуждение в ряде случаев приводит к увеличению частоты CPU) и будет именно с таким интервалом сообщать серверу о своей работоспособности? Telegram запарился насчёт энергосбережения — ну и молодец.


Транспортный уровень. Нам расскажут аж про 5 вариантов

Никто не заствляет разработчиков поддерживать всё, что сервер. Можно реализовать только Abridged TCP и никаких проблем не будет.


У меня тоже есть опыт написания клиента с нуля. А потом — опыт переписывания клиента и написания (простого, на данный момент обеспечивающего только одиночные чаты) сервера (можно найти на github по словам telegram и qt; поддерживается только Linux).
На мой взгляд, при всех его проблемах, Telegram по прежнему является технически наиболее совершенным и продуманным протоколом. Это подтверждается, например, хорошей масштабируемостью — ни один другой IM не поддерживает групповые чаты на 200 000 пользователей. И даже на порядок меньшая планка в 20к участников чата является практически недостижимой.


Telegram вообще большие молодцы и почти всё делают максимально эффективно. Протокол становится лучше от схемы к схеме. Увы, каким-нибудь XMPP и Matrix (хотя сердцем я именно за них) до подобной эффективности ещё очень и очень далеко. Очень жаль, что к Telegram почти невозможно прикрутить федерализацию не растеряв всю эффективность.

Information

Rating
Does not participate
Registered
Activity