Вот уже больше 20 лет мы смотрим веб-странички по протоколу HTTP. Большинство пользователей вообще не задумывается о том, что это такое и как оно работает. Другие знают, что где-то под HTTP есть TLS, а под ним TCP, под которым IP и так далее. А третьи – еретики – считают, что TCP – это прошлый век, им хочется чего-то более быстрого, надёжного и защищённого. Но в своих попытках изобрести новый идеальный протокол они вернулись к технологиям 80-х годов и пытаются построить на них свой дивный новый мир.


Немного истории: HTTP/1.1


В 1997 году протокол обмена текстовой информацией HTTP версии 1.1 обрёл свой RFC. На тот момент протокол использовался браузерами уже несколько лет, а новый стандарт продержался ещё пятнадцать. Протокол работал только по принципу запрос-ответ и предназначался, главным образом, для передачи текстовой информации.

HTTP был спроектирован для работы поверх протокола TCP, гарантирующего надежную доставку пакетов до адресата. Работа TCP основана на установлении и поддержании надежного соединения между конечными точками и разбиении трафика на сегменты. Сегменты имеют свой последовательный номер и контрольную сумму. Если вдруг какой-то из сегментов не придёт или придёт с неверной контрольной суммой, то передача остановится, пока не будет восстановлен потерянный сегмент.

В HTTP/1.0 TCP-соединение закрывалось после каждого запроса. Это было крайне расточительно, т.к. установление TCP-соединения (3-Way-Handshake) это небыстрый процесс. В HTTP/1.1 представили механизм keep-alive, который позволяет переиспользовать одно соединение для нескольких запросов. Однако поскольку оно может легко стать бутылочным горлышком, в разных имплементациях HTTP/1.1 допускается открытие нескольких TCP-соединений к одному хосту. Например, в Chrome и в последних версиях Firefox допускается до шести соединений.

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

Иллюстрация Cloudflare

Таким образом HTTP/1.1 обладал рядом проблем:

  • Медленная установка соединения.
  • Данные передаются в текстовом виде, а значит передача картинок, видео и прочей нетекстовой информации неэффективна.
  • Одно TCP-соединение используется для одного запроса, а значит остальные запросы должны либо найти себе другое соединение, либо ждать, пока текущий запрос его отпустит.
  • Поддерживается только pull-модель. В стандарте нет ничего о server-push.
  • Заголовки передаются текстом.

Если server-push худо-бедно реализуется с помощью протокола WebSocket, то с остальными проблемами предстояло разбираться более радикально.

Немного современности: HTTP/2


В 2012-м году в недрах Google началась работа над протоколом SPDY (произносится «спиди»). Протокол был призван решить основные проблемы HTTP/1.1 и при этом должен был сохранить обратную совместимость. В 2015 году рабочая группа IETF представила спецификацию HTTP/2, основанную на протоколе SPDY. Вот какие отличия были в HTTP/2:

  • Бинарная сериализация.
  • Мультиплексирование нескольких HTTP-запросов в одно TCP-соединение.
  • Server-push из коробки (без WebSocket).

Протокол стал большим шагом вперед. Он сильно выигрывает у первой версии по скорости и не требует создания нескольких TCP-соединений: все запросы к одному хосту мультиплексируются в одно. То есть в одном соединении есть несколько так называемых стримов, каждый из которых имеет свой ID. Бонусом идет коробочный server-push.

Однако мультиплексация ведёт к другой краеугольной проблеме. Представьте, что мы асинхронно выполняем 5 запросов к одному серверу. При использовании HTTP/2 все эти запросы будут выполняться в рамках одного TCP-соединения, а значит, если один из сегментов любого запроса потеряется или придёт неверно, передача всех запросов и ответов остановится, пока не будет восстановлен потерявшийся сегмент. Очевидно, что чем хуже качество соединения, тем медленнее работает HTTP/2. По оценке Дениела Стенберга, в условиях, когда потерянные пакеты составляют 2% от всех, HTTP/1.1 в браузере показывает себя лучше, чем HTTP/2 за счёт того, что открывает 6 соединений, а не одно.

Эта проблема называется «head-of-line blocking» и, к сожалению, решить её при использовании TCP не представляется возможным.

Иллюстрация Daniel Steinberg

Как итог, разработчики стандарта HTTP/2 проделали огромную работу и сделали практически всё, что можно было сделать на прикладном уровне модели OSI. Пришло время спускаться на транспортный уровень и изобретать новый транспортный протокол.

Нам нужен новый протокол: UDP vs TCP


Довольно быстро стало понятно, что внедрить совсем новый протокол транспортного уровня – задача в сегодняшних реалиях нерешаемая. Дело в том, что о транспортном уровне знают железки или middle-boxes (роутеры, файрволы, NAT-серверы...), а научить их чему-то новому крайне непростая задача. Кроме того, поддержка транспортных протоколов зашита в ядро операционных систем, а ядра тоже меняются не то чтобы очень охотно.

И тут можно было бы опустить руки и сказать «Мы, конечно, изобретём новый HTTP/3 с преферансом и куртизанками, но внедряться он будет 10-15 лет (примерно через такое время будет заменено большинство железок)», но есть ещё один не самый очевидный вариант: использовать протокол UDP. Да-да, тот самый протокол, по которому мы кидались файликами по локалке в конце девяностых-начале нулевых. Практически все сегодняшние железки умеют с ним работать.

В чём преимущества UDP по сравнению с TCP? В первую очередь в том, что у нас нет сессии транспортного уровня, о которой знает железо. Это позволяет нам самим определять сессию на конечных точках и там же разруливать возникающие конфликты. То есть мы не ограничены одной или несколькими сессиями (как в TCP), а можем насоздавать их столько, сколько нам нужно. Во-вторых, передача данных по UDP происходит быстрее, чем по TCP. Таким образом, в теории, мы можем пробить сегодняшний потолок скорости, достигнутый в HTTP/2.

Однако UDP не гарантирует надёжность передачи данных. Фактически мы просто посылаем пакеты, надеясь, что на другом конце их получат. Не получили? Ну не повезло… Этого было достаточно для передачи видео для взрослых, но для более серьёзных вещей нужна надёжность, а значит придётся накрутить что-то ещё поверх UDP.

Как и в случае с HTTP/2, работа по созданию нового протокола началась в Google в 2012-м году, то есть примерно в одно время с началом работы над SPDY. В 2013-м Джим Роскинд представил широкой общественности протокол QUIC (Quick UDP Internet Connections), а уже в 2015-м был внесен Internet Draft для стандартизации в IETF. Уже на тот момент протокол, разработанный Роскиндом в Google сильно отличался от вынесенного на стандарт, поэтому гугловскую версию стали называть gQUIC.

Что такое QUIC


Во-первых, как уже было сказано, это обёртка над UDP. Поверх UDP поднимается QUIC-connection, в котором по аналогии с HTTP/2 могут существовать несколько стримов. Эти стримы существуют только на конечных точках и обслуживаются независимо. Если потеря пакета произошла в одном стриме, другие это никак не затронет.

Иллюстрация Daniel Steinberg

Во-вторых, шифрование теперь реализовано не отдельным уровнем, а включено в протокол. Это позволяет устанавливать соединение и обмениваться публичными ключами за одно рукопожатие, а также позволяет использовать хитрый механизм 0-RTT handshake и вообще избежать задержек при рукопожатии. Кроме того, теперь можно шифровать отдельные пакеты данных. Это позволяет не ждать завершения приёма данных из стрима, а расшифровывать полученные пакеты независимо. Такой режим работы был вообще невозможен в TCP, т.к. TLS и TCP работали независимо друг от друга, и TLS не мог знать, на какие куски будет рубить данные TCP. А следовательно, не мог подготовить свои сегменты так, чтобы они укладывались в сегменты TCP один к одному и могли быть расшифрованы независимо. Все эти улучшения позволяют QUIC снизить latency по сравнению с TCP.

В-третьих, концепция лёгких стримов позволяет отвязать соединение от IP-адреса клиента. Это важно, например, когда клиент переключается с одной Wi-Fi точки доступа на другую, изменяя свой IP. В этом случае при использовании TCP происходит длительный процесс, в ходе которого существующие TCP-соединения отваливаются по таймауту и создаются новые соединения с нового IP. В случае с QUIC, клиент просто продолжает посылать серверу пакеты с нового IP со старым ID стрима. Т.к. ID стрима теперь уникален и не переиспользуется, сервер понимает, что клиент сменил IP, досылает потерянные пакеты и продолжает коммуникацию по новому адресу.

В-четвертых, QUIC реализуется на уровне приложения, а не операционной системы. Это, с одной стороны, позволяет быстрее вносить изменения в протокол, т.к. чтобы получить обновление достаточно просто обновить библиотеку, а не ждать новую версию ОС. С другой стороны, это ведёт к сильному увеличению потребления процессора.

Ну и напоследок, заголовки. Компрессия заголовков как раз относится к моментам, которые отличаются в QUIC и gQUIC. Не вижу смысла посвящать этому много времени, скажу только, что в версии, поданной на стандартизацию, компрессию заголовков сделали максимально похожей на компрессию заголовков в HTTP/2. Подробнее можно прочитать здесь.

Насколько оно быстрее?


Это сложный вопрос. Дело в том, что пока у нас нет стандарта, особо нечего измерять. Пожалуй, единственные статистические данные, которыми мы располагаем – статистика Гугла, который использует gQUIC с 2013 года и в 2016 отчитался перед IETF, что около 90% трафика, идущего к их серверам от браузера Chrome, теперь использует QUIC. В этой же презентации они сообщают, что через gQUIC страницы загружаются примерно на 5% быстрее, а в потоковом видео на 30% меньше подвисаний по сравнению с TCP.

В 2017-м году группа исследователей во главе с Arash Molavi Kakhki опубликовала большую работу по изучению производительности gQUIC по сравнению с TCP.
Исследование выявило несколько слабых сторон gQUIC, таких как неустойчивость к перемешиванию сетевых пакетов, жадность (unfairness) к пропускной способности канала и более медленная передача небольших (до 10 кб) объектов. Последнее, впрочем, удается компенсировать использованием 0-RTT. Во всех остальных исследованных случаях gQUIC показал рост скорости по сравнению с TCP. О конкретных цифрах тут говорить сложно. Лучше почитать само исследование или короткий пост.

Здесь нужно сказать, что это данные именно о gQUIC, и они неактуальны для разрабатываемого стандарта. Что будет для QUIC: пока тайна за семью печатями, но есть надежда, что слабые стороны, выявленные у gQUIC, будут учтены и исправлены.

Немного будущности: а что с HTTP/3?


А вот тут всё кристально ясно: API никак не изменится. Всё останется ровно так же, как и было в HTTP/2. Ну а если API остаётся прежним, переход на HTTP/3 должен будет решаться использованием на бэкенде свежей версии библиотеки, поддерживающей транспорт по QUIC. Правда, довольно долго ещё придётся держать фоллбэк на старые версии HTTP, т.к. интернет сейчас не готов к полному переходу на UDP.

Кто уже поддерживает


Вот список существующих реализаций QUIC. Несмотря на отсутствие стандарта, список неплохой.

Ни один браузер сейчас не поддерживает QUIC в прод-релизе. Недавно была информация, что в Chrome включили поддержку HTTP/3, но пока только в Canary.

Из бэкендов HTTP/3 поддерживает только Caddy и Cloudflare, но пока экспериментально. NGINX в конце весны 2019-го объявили, что начали работу над поддержкой HTTP/3, но пока не закончили.

Какие есть проблемы


Мы с вами живём в реальном мире, где ни одна большая технология не может пройти в массы, не встретив сопротивления, и QUIC тут не исключение.

Самое важное, нужно как-то объяснить браузеру, что “https://” теперь не факт, что ведёт на 443-ий TCP-порт. Там вообще может не быть TCP. Для этого используется заголовок Alt-Svc. Он позволяет сообщить браузеру, что этот веб-сайт также доступен на таком-то протоколе по такому-то адресу. В теории это должно работать как часы, но на практике мы наткнёмся на то, что UDP может быть, например, запрещён на файрволе во избежание DDoS атак.

Но даже если UDP не запрещён, клиент может находиться за NAT-роутером, который настроен на удержание TCP-сессии по IP адресу, а т.к. мы используем UDP, в котором нет аппаратной сессии, NAT не будет удерживать соединение, и QUIC-сессия будет постоянно обрываться.

Все эти проблемы связаны с тем, что UDP раньше не использовался для передачи интернет-контента, и производители железок не могли предвидеть, что такое когда-то случится. Точно так же админы пока не очень понимают, как правильно настроить свои сети для работы QUIC. Эта ситуация будет потихоньку меняться, и, в любом случае, подобные изменения займут меньше времени, чем внедрение нового протокола транспортного уровня.

Кроме того, как уже было описано, QUIC сильно увеличивает использование процессора. Daniel Stenberg оценил рост по процессору до трёх раз.

Когда наступит HTTP/3


Стандарт хотят принять к маю 2020 года, но, учитывая, что на текущий момент недоделанными остаются документы, запланированные на июль 2019, можно сказать, что дату скорее всего отодвинут.

Ну а Гугл использует свою реализацию gQUIC с 2013-го года. Если посмотреть HTTP-запрос, который отправляется гугловому поисковику, можно увидеть вот это:


Выводы


QUIC сейчас выглядит как довольно сырая, но очень перспективная технология. Учитывая, что последние 20 лет все оптимизации протоколов транспортного уровня касались в основном TCP, QUIC, в большинстве случаев выигрывающий по производительности, выглядит уже сейчас крайне неплохо.

Однако пока ещё остаются нерешённые проблемы, с которыми предстоит справляться в ближайшие несколько лет. Процесс может затянуться из-за того, что вовлечено железо, которое никто не любит обновлять, но тем не менее все проблемы выглядят вполне решаемыми, и рано или поздно у всех нас будет HTTP/3.

Будущее не за горами!

Комментарии (90)


  1. VBKesha
    31.10.2019 17:24

    Интересно когда же взоры людей привлечет сам стэк HTML+CSS+JS. И придумают(возбмут что нибудь готовое типа PDF и нзовут новым именем) что нибудь новое, что не будет в итоге жрать столько памяти/процессора, и тянуть такое количество костылей.


    1. ypastushenko Автор
      31.10.2019 17:32

      Уже есть WebAssembly.


      1. VBKesha
        31.10.2019 17:48

        Он разве чтото делает с CSS+HTML?


        1. ypastushenko Автор
          31.10.2019 18:27

          Насколько я знаю, нет. Он только про замену js.


          1. Hippolot
            01.11.2019 21:45
            +1

            Он не про замену JS, он про замену медленного кода на JS.


        1. vladbarcelo
          01.11.2019 12:30

          Формально — нет, но под него есть QT...


          1. maxzhurkin
            03.11.2019 09:10

            Qt


      1. ice2heart
        31.10.2019 18:16

        Вебасембли сделает все хуже… Люди начнут писать фронтенд на джаве со спрингом…


        1. pehat
          31.10.2019 19:29

          То есть, Java Applets вы не помните. Слезли ж как-то.


          1. ice2heart
            01.11.2019 21:29
            +2

            Помню… вот поэтому и страшно.


            1. gotozero
              31.10.2019 23:24
              +2

              Справедливости ради стоит вспомнить, что давали(возможность) эти апплеты в соотношении производительности процессоров тех лет.

              На современных процессорах эти апплеты могли бы работать совсем по другому. Возьмем и представим современный Intellij Idea и его гипотетический аналог на JS.

              Спрингу может там не место, но камон, джава была бы там не так плоха, как вы описываете.

              Давайте сделайте нечто подобное как-то иначе, а мы посмотрим.


            1. domix32
              01.11.2019 15:07
              +1

              https://sandspiel.club/
              вроде не шибко страшно. плюс отсутcтвие gc пока не прочит java в браузере.


              1. SlimShaggy
                01.11.2019 19:55

                Ну вон MS это не остановило, они завезли свой GC (вместе с остальным дотнетом): https://dotnet.microsoft.com/apps/aspnet/web-apps/blazor


                1. domix32
                  01.11.2019 22:31

                  Так это proof of concept. Есть еще скомпиленные в wasm CPython (см. Pyodide), который тоже с каким-то там управлением памятью. Поэтому и написал пока не прочит. Когда-нибудь найдется извращенец.


                  1. SlimShaggy
                    01.11.2019 22:38

                    Ну Blazor WebAssembly-то не proof of concept, а вполне рабочая бета. В .Net Core 3.1 уже релизная версия войдет.


                    1. domix32
                      03.11.2019 01:01

                      То есть вы уже можете представить куда можно попытаться применить этого монстра?


                1. domix32
                  01.11.2019 22:33

                  А так там пытаются заимплементить Flash на Rust который потом будет поверх canvas рендерить. Учитывая, что EcmaScript обычно живет с гц, то и там что-то почти наверняка есть похожее.


      1. sHaggY_caT
        31.10.2019 23:51

        Память и процессор пока ещё дешевеют. Скорее нужно решение, которое ещё дешевле для разработчика будет масштабироваться по увеличивающемуся количеству CPU ядер.


        1. nuclight
          01.11.2019 01:37

          Это ненадолго.


    1. ice2heart
      31.10.2019 18:16

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


      1. achekalin
        01.11.2019 23:54
        +1

        Выкинуть-то надо, да только не бросать старых клиентов, вот что важно.


        А то взял тут старый телефон, к которому обновлений не было уже годы, попробовал на имеющемся там браузере зайти на Яндекс — ой, сказал браузер, сервер не умеет то шифрование, которое умею я (на деле было-то всё наоборот, но важно, что они не договорились; при этом обновлений для телефона не было и не предвиделось от слова совсем).


        Не то чтобы я сильно "за" тащить легаси и поддерживать всё и вся бесконечно. Однако говорить юзерам "меняй устройство, а то нам день легамюси тащить"… Может, тогда эти устройства ещё и купить им, а то геморрой индустрия привносит, юзер как бы не виноват.


        1. ice2heart
          02.11.2019 09:09
          -1

          Ну можно еще взять ие6 и долго возмущаться, что интернет не хочет поддерживать ие6.


          1. Anrikigai
            02.11.2019 09:35

            ПК, где IE6 — последний работающий браузер, и невозможно установить никакой поновее, да так, чтобы на нем кто-то реально хотел на нем работать — редкость, мне кажется.
            Я вон хотел свой старый IBM ThinkPad (2005 года) под домашнюю автоматизацию заюзать. Даже Linux поставил не с первой попытки. Оказалось, что последние дистрибутивы без поддержки 64битного режима не работают. Потом померял энергопотребление и решил, что выгоднее использовать более свежее старье (или, возможно, одноплатник с минимальным энергопотреблением и приличной производительностью).

            А вот смартфонов старых вполне рабочих навалом. И для каких-то узкоспециализированных задач я бы их вполне использовал.
            К примеру, взял HTC One, визуально нормальный смартфон, вполне себе работает, показывает. Но, к примеру, Google Assistent на нем уже не завелся толком. Есть смартфоны, куда Youtube Music не встает! А я хотел как раз в комнате его кинуть просто для голосового управления.

            А уж как я с iPad2 прокололся в отпуске в связи с тем, что куча программ уже не работает на iOS ниже 10, которая на этот iPad не устанавливается… Такой подставы не ожидал от них.


          1. nuclight
            03.11.2019 14:42

            А где был IE6, давайте вспомним? В WinXp? Так на неё устанавливается Firefix 52 ESR, а это 2017 год. Смотрите, 15 лет разницы, железо 2002 года уже скорее всего сдохло — а теперь сравним, сколько этому телефону, на который установить новее уже почему-то вдруг нельзя?..


    1. vlreshet
      31.10.2019 18:34
      +1

      Пожалуйста, не надо. Хоть тут нет зоопарка — каким бы не был сайт, на фронте всегда HTML и CSS. Да, с легаси костылями, да, с вендорными префиксами, но всё же. А вопрос тормозов и жрущей памяти обычно надо задавать фронтендерам, а не разработчикам спецификации HTML и CSS.


      1. epishman
        01.11.2019 10:30
        +1

        Ванильная императивщина и innerHTML фантастически быстры, но считается дурным тоном, а RX с виртуальным Домом это модно, но далеко небесплатно.


    1. nuclight
      31.10.2019 19:47
      +1

      Да хоть прямо сейчас. Только одна проблема — куда деть миллионы обезь фронтендеров, которые ничего больше не умеют?


      1. ti1
        01.11.2019 11:47
        +1

        Маск там в США Старшипы строит, про колонизацию Марса что-то рассказывал…


        1. nuclight
          03.11.2019 14:30

          Предлагаете удобрить ими почву Красной Планеты, дабы сделать её плодородной? Хитро!


      1. maxzhurkin
        03.11.2019 09:19

        В дворники тех, кто учиться не хочет :)
        А если серьёзно и без экстремизма, то нежелание учиться, на самом деле — проблема того, кто не хочет — всегда так было и всегда так будет.
        Раньше их выкашивал естественный отбор, теперь рыночная экономика удерживает их на нижних ступенях социальной лестницы, в будущем появится ещё что-нибудь


        1. nuclight
          03.11.2019 14:29

          А нежелание прививаться проблема тех, кто не хочет прививаться, да-да...


    1. bgnx
      31.10.2019 20:01
      +2

      Уже лет 10 как есть webgl, где есть полная свобода и максимальная производительность. Только никто не хочет этим заниматься потому это максимально низкий уровень графического стека — там даже рендер текста нужно делать самому (разбивая текст на глифы а глифы на кривые безье и т.д не говоря уже про поддержку юникода и всех этих сложностей с многоязычным вводом). Но с другой стороны для некоторых кейсов как например редактор кода где многоязычность не нужна и есть только английский моноширинный шрифт задача уже упрощается. Вот тут человек для редактора кода заменил весь этот стек (html/css/svg/2d-canvas) на webgl — https://makepad.github.io/makepad — написал свой рендер текста, рендер прямоугольников и других ui-примитивов, написал алгоритм лейаута подобно флексбоксам и теперь уже пишет высокоуровневые компоненты, логику, фичи и постоянно пишет в твиттере (https://twitter.com/rikarends) как все стало намного удобнее и на порядок быстрее чем с html/css


      1. Gugic
        31.10.2019 20:17

        Вот это круто.


      1. kekekeks
        01.11.2019 01:17
        +1

        WebGL как бы маловато для UI-тулкита. Контрольчики отрисовать не проблема, веселье начинается на тексте и его вводе. Причём у браузеров нет вообще никаких API для интеграции с системой ввода текста. Совсем. Можно более-менее работать только с европейскими локалями, где всё работает на раскладках клавиатуры.


        1. Gugic
          01.11.2019 05:37
          +1

          Да там еще миллион и один нюанс — начиная от того, как оно все будет работать с какими-нибудь скринридерами или полезными расширениями браузера (никак) и заканчивая суровой механической необходимостью пробрасывать туда и обратно вообще все, потому что API сурово изолирован (посмотрите на github.com/makepad/makepad/blob/master/render/src/cx_webgl.js это).

          Но тем не менее — это круто, это огромная работа с весьма сомнительной полезностью сейчас, но немного раздвигающая границы того, что можно будет делать потом. (и да, я знаю про миллион портированных через emscripten приложений, но ведь это не порт, это концептуально такая разработка).


      1. gadfly
        01.11.2019 16:31

        Зачем с нуля, если это уже много раз сделано? Просто портировать существующие тулкиты.


    1. norguhtar
      01.11.2019 09:00
      +2

      Меня больше интересует когда люди перестанут втаскивать приложения в HTML+CSS. Он делался совсем для другого. То как он сейчас используется совместно с JS делает меня грустной пандой.


      1. gadfly
        01.11.2019 16:33

        Как только появится замена, за которой будет стоять большая корпорация.


        1. nuclight
          01.11.2019 23:07

          Необязательно именно корпорация. Но кто-то должен оплатить банкет, да...


    1. epishman
      01.11.2019 10:23

      Flutter это и есть полностью новый стек. Только неудобен по причине принудительной декларативщины и слегка глючен.


      1. george3
        01.11.2019 12:40

        Интересно про где принудительная декларативщина…


        1. epishman
          01.11.2019 13:58

          Ну вы же не можете любой виджет по id достать и что-то с ним сделать, нету там querySelector, хотя всем хочется. Тот же Provider.of это частичный откат к императивщина, хоть и а рамках предков.


          1. george3
            01.11.2019 16:32

            Ну вы же не можете любой виджет по id достать и что-то с ним сделать

            из коробки не могу. надстройку сделал — все могу. фрагмент:

            Map<dynamic, UpdateState> _stateMap = {};
            
            void registerState(UpdateState state){ _stateMap[state.widget.data] = state;}
            
            void unregisterState(UpdateState state){ 
              for(var kv in _stateMap.entries)
                if (kv.value == state)
                {   
                  _stateMap.remove(kv.key);      
                  break;
                }
            }


            1. epishman
              01.11.2019 17:24

              Согласен, хотя они во всех методичках кричат что так нельзя, может боятся, что если все будут писать императивно — продукт не покажет сказочной производительности, которую нам обещают? Собственно, получим ту проблему, которую побеждал React — непредсказуемые обновления больших кусков DOM. Хотя непонятно, такая ли уж это проблема сегодня, когда даже в web-компонентах считается незазорным использовать innerHTML.


              1. george3
                01.11.2019 18:14
                +1

                Мне пофиг на то что там думают. в моей схеме я обновляю именно те виджеты/области, которые должны обновится и автоматом. для этого написал два класса сверху и все мои виждеты/состояния наследуются от них и все становится прозрачно и доступно.

                abstract class UpdateWidget extends StatefulWidget with SizeInfo{
                  UpdateWidget(this.data);
                  final dynamic data;
                  String get name{ return data['name'];}
                }
                
                abstract class UpdateState<T extends UpdateWidget> extends State<T>{
                  String get name{ return widget.data['name'];}
                  void updateData(dynamic data)
                  {
                    setState(() => data.forEach((k,v) => widget.data[k] = v));
                  }
                  @override
                  void initState() {
                    registerState(this);
                    super.initState();
                  }
                  @override
                  void dispose(){
                    unregisterState(this);
                    super.dispose();
                  }
                  @override
                  void didUpdateWidget (covariant T oldWidget){
                     super.didUpdateWidget(oldWidget);
                     unregisterState(this);
                     registerState(this);
                  }
                }

                Все эту с прокидыванием через провайдеры, GlobalStates,… не использую, ибо с ней все становится мутно для меня.


                1. epishman
                  02.11.2019 10:08

                  Нормальный подход. Только поддерево вашего зарегистрированного стейта будет обновляться целиком, а Provider (он же по сути InheritedWidget) ведет внутренний реестр зависимостей, и может обновить только корень поддерева (ваш стейт), и какой-нибудь дальний лист, все остальное оставляя нетронутым. Особенно актуально, если у вас один StatefullWidget вложен в другой. Хотя, в случае вложенных стейтфулов я не уверен, сам не тестировал.


                  1. george3
                    02.11.2019 12:16

                    Нет. внутренние оптимизации Flutter продолжают работать. команда на отрисовку(обновление) приводит к пересчету кодопредствления в build. обновляется графика только там (в тех частях) где код перестал совпадать с пред. состоянием от build.


    1. Alexus819
      01.11.2019 16:01

      был уже и flash и поделие мс silverlight или как то так… и все это не взошло. Хотя флэш был местами хорош, но не сильно безопасен.


  1. nuclight
    31.10.2019 19:46

    И как всегда, про SCTP эти велосипедисты не подумали.


    1. Revertis
      01.11.2019 21:21

      Ну так у других протоколов «фатальный недостаток» ;)


    1. pakager
      31.10.2019 23:16
      +2

      А с какой версии Windows/MacOS/Android/iOS SCTP поддерживается из коробки?


      1. nuclight
        01.11.2019 01:36

        Никто не мешает притащить с собой usersctp


        1. Hippolot
          01.11.2019 04:12
          +2

          Он требует режима администратора, т.к. сырыми сокетами управляет. Это может стать трудностью.


          1. nuclight
            01.11.2019 23:04

            В режиме UDP-туннеля не требуется.


      1. DreamingKitten
        01.11.2019 22:12

        в линуксовом ядре он давным давно есть


    1. dartraiden
      01.11.2019 01:15

      1. nuclight
        01.11.2019 01:36

        Уже разбирали в одном из летних постов по теме. Недостоверная информация там местами.


  1. Oreolek
    31.10.2019 20:47

    Вот то, что браузер теперь передаёт ваш ID даже между IPшниками (в HTTP/2 он может только сохранять соединение между сессиями) и то, что браузер захватывает ещё и сетевой драйвер вместо операционной системы — это адская смесь. Ещё и увеличение нагрузки на процессор в три раза как подарок.

    Гугл в принципе очень хочет превратить браузер в мега-операционку, они уже пилят стандарт USB-драйвера, драйвера серийных портов и распознавания лиц на видео.

    Кстати, QUIC откроет UDP-протокол самим сайтам, чтобы трафика стало ещё больше. Бегите обновлять мобильные, трёх гигабайт оперативки уже скоро будет мало.


    1. DrunkBear
      01.11.2019 15:28

      Спасибо, теперь я смогу ответить, на кой чёрт мне нужно 8 гигов оперативки в мобильнике и 32 на домашнем компьютере, если я не кручу там тяжёлые БД. /irony


  1. Chupaka
    01.11.2019 13:41

    > Все эти проблемы связаны с тем, что UDP раньше не использовался для передачи интернет-контента, и производители железок не могли предвидеть, что такое когда-то случится.

    У меня дежавю. Такое уже было при запуске uTP! Отрицание, гнев, ....., принятие.


    1. Paul_Nice
      01.11.2019 22:35

      UDP используется в SRT для передачи видео через Интернет уже несколько лет как.


      1. Chupaka
        01.11.2019 22:48

        Ну, uTP в своё время укладывал провайдерские роутеры на лопатки, именно это я и имел в виду.
        SRT вряд ли таким похвастается :)


        1. sumanai
          02.11.2019 00:22

          Ну, uTP в своё время укладывал провайдерские роутеры на лопатки, именно это я и имел в виду.

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


  1. stepuncius
    01.11.2019 13:55

    Интересно, насколько хорошо будет работать провайдерское оборудования для блокировки с QUIC?
    Будет весело, если эти системы накроются медным тазом. (а, в идеале, будут накрываться раз в 5 лет из-за какого-нибудь нового стандарта, например IPv6 everywhere coming soon )
    Или у нас все новые интернет технологии запретят?)


    1. rPman
      01.11.2019 14:08

      Скорее всего все запретят, по другим областям видно


    1. Anrikigai
      01.11.2019 14:18

      В компаниях наверняка QUIC будет тупо блокироваться. Ибо фаерволы и прочие решения фиг его проинспектируют.
      И сайты/браузеры просто будут откатываться на старый добрый способ.
      Причем, насколько я понял из статьи, пользователи визуально врядли заметят замедление. Выигрыш в скорости копеечный.


      1. blind_oracle
        02.11.2019 23:11

        А что HTTPS сейчас как то инспектируется кроме SNI? Ну про MITM через анальное внедрение доверенных сертификатов сотрудникам я не говорю, тут полная свобода.


        1. Anrikigai
          03.11.2019 08:34

          Да, я про корпоратов.
          Таких, что разрешают бесконтрольный доступ в Интерент крайне мало. А без проверки HTTPS он фактически бесконтрольный.
          Есть такие, кто удовлетворяется проверкой сертифкатов. Типа «заправшиваемый сайт вернул сертифкат *.facebook.com, социальные сети разрешы, значит на разрешенный сайт идешь, проходи».
          И очень много делающих полный MITM, благо сертифкат распространить на корпоративные компы не проблема.
          С QUIC такой возможности не вижу, проще заблокировать его.


          1. blind_oracle
            03.11.2019 11:49

            Ну сертификаты, допустим, уже нельзя прочитать из TLS 1.3 сессии, обмен теперь зашифрован. Только повторяя соединение параллельно на тот же IP и с тем же SNI. Это если нет eSNI, с ним — уже увы.


            С QUIC такой возможности не вижу, проще заблокировать его.

            Не вижу принципиальной разницы MITMить QUIC или TLS. Как выйдет стандарт — появятся и инструменты.


            1. nuclight
              03.11.2019 14:47

              А она есть. В случае с HTTP прокси были частью стандарта изначально. А в случае с QUIC?


              1. blind_oracle
                03.11.2019 15:29

                Причем тут прокси?


                HTTPS MITM-ится перехватом TCP соединения, заворачиванием его на какой-нибудь Squid, генерацией там фейкового сертификата и оттуда уже строится второе соединение на целевой хост от имени клиента.


                Никакой "прокси из стандарта" не участвует, клиент не видит разницы.


                1. nuclight
                  03.11.2019 15:57

                  При том, что протокол был построен так, что запрос на прокси и на конечный сервер почти не отличаются. Поэтому перехватить TCP-соединение — легко, хотя в корпоративной среде для plain HTTP лучше было прописать как прокси, чтоб браузер учитывал это.


                  А тут у вас ни TCP, ни TLS, для начала, а потом роуминг еще.


                  1. blind_oracle
                    03.11.2019 19:04

                    Ну так это вопрос инструментов. Само собой под новый протокол нужны новые диссекторы.


                    Но семантика HTTP, насколько я вижу, внутри третьей версии не поменялась никак относительно второй, поэтому нужно просто разобрать внешние слои а внутри всё останется как и раньше.


  1. lizergil
    01.11.2019 14:02
    +3

    По моему сейчас проблема в тормозных сайтах и приложениях, а не в протоколе. Эти спиди и квики никому не нужны кроме гугла — корпоративное лоббирование ради собственных интересов. Очень надеюсь, что у нас не будет никакого HTTP/3 пока мы в нем откровенно не нуждаемся. Если кто-то хочет возразить, приведите живой пример, какую конкретно проблему решает HTTP/3 против HTTP/1.1.


    1. domix32
      01.11.2019 15:25

      Так оно же много кому выгодно. В первую очередь мобильным оператором.


      1. lizergil
        01.11.2019 16:00

        Каким боком? Приведите, пожалуйста, конкретный пример в чем выгодно.


        1. domix32
          01.11.2019 20:08

          Короткое восстановление сессий в нерегулярных мобильных сетях в первую очередь. Чуть меньше трафика который уходит на все эти хэндшейки -> снижение пинга в сети -> повышение плотности трафика в сети -> удешевление трафика. Тут же на хабре была статья от какой-то кампании(кажется эта), про внедрение quic в мобильное приложение.


          1. lizergil
            01.11.2019 21:59

            Не уверен, что мобильные операторы вообще заинтересованы в удешевлении трафика. Это важно только большим компаниям для их больших бизнесов. По ссылке пример внедрения QUIC в Uber, по итогам которого можно сказать одно — стало лучше. Все. Никакой проблемы не решено, потому как настоящей проблемы то и нет (не знаю зачем им в приложении real time, о котором они упоминают). Улучшили они latency на 30% (которая в реале будет 15%), что это за цифра в мобильных сетях? Ничто, было 200мс, стало 140мс. Этого все равно недостаточно для Real Time. Требуется улучшение на порядок, чтобы об этом можно было серьезно говорить.


            1. domix32
              01.11.2019 22:24

              Подразумевалось удешевление трафика для оператора, то бишь ему придется меньше тратиться. Думаю любой бизнес порадуется сократившимся расходам при неизменном доходе.
              Уменьшение задержек/таймаута — вполне себе способ несколько нивелировать регуляторный ахтунг, например. При повсеместном распространении, конечно же.


    1. lopatoid
      01.11.2019 17:05

      1. lizergil
        01.11.2019 17:44
        +1

        Отличный пример как делать не надо:
        1. Хайлоад ради хайлоада.
        2. Сами придумали проблему и так ее и не решили.
        3. Внедрили сомнительное решение на транспортном уровне, получили статистическое увеличение скорости загрузки и колоссальную потерю пропускной способности.


    1. GrigoryPerepechko
      02.11.2019 13:48

      Проблемы только у вас в голове.

      А общее время реакции приложения состоит как из тормозов приложения, так и из тормозов сетевого стека. И если первое легко фиксится, а у нормальных программистов и не появляется — то второе забито гвоздями в железо маршрутизаторов. И Гугл молодцы что своей силой вытащат всю протокольную логику из их прошивок в user-space где она понемногу может развиваться. Кроме них на такое способны немногие.


      1. nuclight
        03.11.2019 14:49

        Не молодцы, а наоборот, диверсия. У них не тот уровень компетенции, чтобы диктовать нижнему уровню. И так и выходит — огромное количество усилий с довольно скромным выхлопом.


    1. billyevans
      03.11.2019 09:51

      Удержание единого соединения при смене ip адресов и сетей. Когда едет, например, машина на скорости 80 миль/ч и частенько переезжает из сети в сеть, то иногда WiFi ловит. То иметь по сути одно соединение без постоянных реконнектов и миганий прям сильно улучшит консистентность статуса машины online/offline.


      1. lizergil
        03.11.2019 14:36

        > сильно улучшит консистентность статуса машины online/offline
        Где, в сферическом коне? Приведите реальный пример, где это имеет критическое значение.

        > Удержание единого соединения при смене ip адресов и сетей.
        Ну физически соединение меняется в любом случае, тут мы ничего не экономим. Логически, поддержание сессии при смене соединения обеспечивается авторизацией клиента на прикладном уровне, причем это является требованием безопасности. Следовательно никого выигрыша мы тут тоже не получаем.


        1. billyevans
          03.11.2019 18:22
          +1

          Где, в сферическом коне? Приведите реальный пример, где это имеет критическое значение.

          Реальный пример, который вижу часто. Стоит машина на парковке и блокирует другую. Ее начинают двигать мобильным телефоном, в какой-то момент машина переезжает из зоны wifi и начинает переподключаться по LTE в этот момент она останавливается на пару секунд, тк сервер думает, что она offline и перестает слать команды. Что очень неприятный опыт. Это можно улучшить текущими технологиями, сильно усложнив логику всего.


  1. Leoalba22
    01.11.2019 14:16

    Это довольно интересно для всех новых пользователей.


  1. SamOwaR
    01.11.2019 17:15
    +2

    Данные передаются в текстовом виде, а значит передача картинок, видео и прочей нетекстовой информации неэффективна.
    Тут видимо стоит сделать уточнение, что бинарные данные переводятся в текст только при отправке с клиента на сервер, например POST-е формы.
    В остальных случаях (которых большинство) бинарные данные идут как есть, а текстовые только заголовки.


  1. Vazovec
    01.11.2019 18:24

    Здравствуйте Юрий. Статья конечно интересная. Если я правильно понял вашу статью, всё что предлагают «товарищи» это как бы делать всё то что делает TCP, только программным способом.
    Нужно так же как-то резать «данные» на пакеты определённого размера (ведь буфер сетевой Ethernet карты не бесконечен). Метить эти пакеты (порядковый номер в потоке). Поднимать флаг установки нового соединения\сеанса связи. Считать контрольную сумму пакета.
    Тоесть получается всё то что сейчас делает аппаратная часть TCP переложить на хост процессор. Конечно реализация аппаратной части UDP намного проще.

    В связи с этим такой вопрос, как вы думаете не связано ли это «движение» с заблаговременной подготовкой ко встрече 5G ???
    Тоесть это всё начинают проектировать не для проводного Etherneta ???
    Поэтому на первый взгляд всё кажется немного бестолковым ?!
    Ведь в радиосреде практически все пакеты данных по своей сути UDP. Причём до определённой меры, широковещательные пакеты UDP. На радио тракте бессмысленно существование аппаратуры TCP. То что есть сейчас это появилось как радиоэкспадеры для обычных проводных сетей.
    А в сенсорных мэш радиосетях ничего близкого под TCP нет. Там везде по сути UDP.
    Ну и с учётом того что активно всех сгоняют в «облака». «Облака» сгонят в одну «тучу» (дата центр\центры), наподобие как Гугл или Фейсбук.
    И все будут «говорить» с этой тучей через массивы антенн 5 G посредством своих гаджетов.
    А провода будут постепенно везде скручивать. И всех убеждать что мол крайне не модно по проводам в соц.сетях сидеть.


    1. ypastushenko Автор
      01.11.2019 20:24

      Если я правильно понял вашу статью, всё что предлагают «товарищи» это как бы делать всё то что делает TCP, только программным способом.

      Не совсем. QUIC ещё должен решить проблему «head-of-line blocking» и предоставить лёгкий способ поддержания соединения при изменении IP-адреса клиента.

      В связи с этим такой вопрос, как вы думаете не связано ли это «движение» с заблаговременной подготовкой ко встрече 5G ???


      Не думаю, что у меня достаточно компетенций, чтобы уверенно отвечать на этот вопрос. Могу только сказать, что тесты производительности для gQUIC в случае работы через смартфон по мобильной сети, показывают, что gQUIC в этом случае имеет меньший отрыв от  TCP, чем при использовании десктопного компьютера и кабельного интернета. Да, тут больше важна производительность смартфона, но всё-равно, думаю, что развитие мобильных сетей в меньшей степени оказывает влияние на развитие QUIC, чем упоротость создателей и желание решить указанные выше проблемы :)