Π Π°Π·Π½ΠΎΠ΅

Π‘ΠΎΠΊΠ΅Ρ‚ Π²Π΅Π±: WebSockets β€” ΠΏΠΎΠ»Π½ΠΎΡ†Π΅Π½Π½Ρ‹ΠΉ асинхронный Π²Π΅Π± / Π₯Π°Π±Ρ€

Π‘ΠΎΠ΄Π΅Ρ€ΠΆΠ°Π½ΠΈΠ΅

HTML5 | Π’Π΅Π±-сокСты

89

Π’Π΅Π±-ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ — HTML5 — Π’Π΅Π±-сокСты

Π‘Π΅Ρ€Π²Π΅Ρ€Π½Ρ‹Π΅ события, рассмотрСнныС Ρ€Π°Π½Π΅Π΅, ΡΠ²Π»ΡΡŽΡ‚ΡΡ ΠΈΠ΄Π΅Π°Π»ΡŒΠ½Ρ‹ΠΌ инструмСнтом, ΠΊΠΎΠ³Π΄Π° трСбуСтся ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ сообщСний с Π²Π΅Π±-сСрвСра. Но ΠΏΡ€ΠΈ этом связь получаСтся ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ одностороннСй. Π‘Ρ€Π°ΡƒΠ·Π΅Ρ€ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΡ‚Π²Π΅Ρ‡Π°Ρ‚ΡŒ Π½Π° сообщСния ΠΈΠ»ΠΈ Π²ΡΡ‚ΡƒΠΏΠ°Ρ‚ΡŒ Π² Π±ΠΎΠ»Π΅Π΅ слоТный Π΄ΠΈΠ°Π»ΠΎΠ³ с сСрвСром.

Если Π²Ρ‹ создаСтС Π²Π΅Π±-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ трСбуСтся ΡΠ΅Ρ€ΡŒΠ΅Π·Π½ΠΎΠ΅ двустороннСС взаимодСйствиС Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π° с Π²Π΅Π±-сСрвСром, Π»ΡƒΡ‡ΡˆΠΈΠΌ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΎΠΌ ΠΊ Π΅Π³ΠΎ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ (Π½Π΅ прибСгая ΠΊ ΠΏΠΎΠΌΠΎΡ‰ΠΈ Flash) Π±ΡƒΠ΄Π΅Ρ‚, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, использованиС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° XMLHttpRequest. Π’ зависимости ΠΎΡ‚ Ρ‚ΠΈΠΏΠ° создаваСмого прилоТСния этот ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ ΠΌΠΎΠΆΠ΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ Ρ‚Π°ΠΊ, ΠΊΠ°ΠΊ трСбуСтся. Но здСсь сущСствуСт ΠΈ достаточноС количСство Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Ρ… ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ.

ΠŸΡ€Π΅ΠΆΠ΄Π΅ всСго, ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ XMLHttpRequest Π½Π΅ ΠΎΡ‡Π΅Π½ΡŒ Ρ…ΠΎΡ€ΠΎΡˆΠΎ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΈΡ‚ для быстрого ΠΎΠ±ΠΌΠ΅Π½Π° мноТСствСнными сообщСниями (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π² Ρ‡Π°Ρ‚Π΅). ΠŸΠΎΡ‚ΠΎΠΌ, Π² Π½Π΅ΠΌ Π½Π΅Ρ‚ возмоТности ΡΠ²ΡΠ·Π°Ρ‚ΡŒ ΠΎΠ΄ΠΈΠ½ Π²Ρ‹Π·ΠΎΠ² с Π΄Ρ€ΡƒΠ³ΠΈΠΌ, поэтому ΠΏΡ€ΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠΌ Π½ΠΎΠ²ΠΎΠΌ запросС ΠΎΡ‚ Π²Π΅Π±-страницы сСрвСр Π΄ΠΎΠ»ΠΆΠ΅Π½ Π²Ρ‹Ρ‡ΠΈΡΠ»ΡΡ‚ΡŒ с самого Π½Π°Ρ‡Π°Π»Π°, ΠΊΠΎΠΌΡƒ эта страница ΠΏΡ€ΠΈΠ½Π°Π΄Π»Π΅ΠΆΠΈΡ‚. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ слоТности ΠΊΠΎΠ΄Π° для ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ ряда связанных запросов ΠΎΡ‚ Π²Π΅Π±-страницы ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΡ‡Π΅Π½ΡŒ быстро вырасти Π΄ΠΎ практичСски Π½Π΅Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠ΅ΠΌΠΎΠΉ.

Для всСх этих ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ Π΅ΡΡ‚ΡŒ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅, хотя ΠΎΠ½ΠΎ Π΅Ρ‰Π΅ Π½Π΅ Π²ΠΏΠΎΠ»Π½Π΅ Π³ΠΎΡ‚ΠΎΠ²ΠΎ. Π­Ρ‚ΠΈΠΌ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ΠΌ являСтся тСхнология Π²Π΅Π±-сокСтов (web sockets), которая позволяСт Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Ρƒ ΡƒΠ΄Π΅Ρ€ΠΆΠΈΠ²Π°Ρ‚ΡŒ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΎΠ΅ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΊ сСрвСру ΠΈ ΠΎΠ±ΠΌΠ΅Π½ΠΈΠ²Π°Ρ‚ΡŒΡΡ сообщСниями Π² Ρ‚Π΅Ρ‡Π΅Π½ΠΈΠ΅ любого Ρ‚Ρ€Π΅Π±ΡƒΠ΅ΠΌΠΎΠ³ΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ.

ВСхнология Π²Π΅Π±-сокСтов Π²Ρ‹Π·Π²Π°Π»Π° большоС Π²ΠΎΠ·Π±ΡƒΠΆΠ΄Π΅Π½ΠΈΠ΅ Π² срСдС Π²Π΅Π±-Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠ², Π½ΠΎ ΠΎΠ½Π° Π΅Ρ‰Π΅ находится Π² процСссС развития, хотя ΡƒΠΆΠ΅ ΠΈΠΌΠ΅Π΅Ρ‚ Π½Π΅ΠΏΠ»ΠΎΡ…ΡƒΡŽ Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π½ΡƒΡŽ ΡΠΎΠ²ΠΌΠ΅ΡΡ‚ΠΈΠΌΠΎΡΡ‚ΡŒ:



ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π°ΠΌΠΈ Π²Π΅Π±-сокСтов
Π‘Ρ€Π°ΡƒΠ·Π΅Ρ€IEFirefoxChromeSafariOperaSafari iOSAndroid
Минимальная вСрсия10614612.16

На Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π»ΡƒΡ‡ΡˆΠ΅ всСго Ρ‚Π΅ΡΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ страницы, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰ΠΈΠ΅ Π²Π΅Π±-сокСты, Π² Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π΅ Chrome, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ прСдоставляСт Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΡƒΡŽ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΡƒ для Π½ΠΈΡ….

ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ доступа ΠΊ Π²Π΅Π±-сокСтам

Π’Π΅Π±-сокСты ΡΠ²Π»ΡΡŽΡ‚ΡΡ спСциализированным инструмСнтом. Они Π°ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹ для Ρ‚Π°ΠΊΠΈΡ… ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ, ΠΊΠ°ΠΊ Ρ‡Π°Ρ‚, массивныС ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠ΅ ΠΈΠ³Ρ€Ρ‹ ΠΈΠ»ΠΈ инструмСнт для ΠΏΠΈΡ€ΠΈΠ½Π³ΠΎΠ²ΠΎΠ³ΠΎ взаимодСйствия. Π’Π΅Π±-сокСты ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ Π½ΠΎΠ²Ρ‹Π΅ Ρ‚ΠΈΠΏΡ‹ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ, Π½ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡ‚ΡŒ ΠΈΡ… Π² Π±ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²Π΅ соврСмСнных Π²Π΅Π±-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ, Π΄Π²ΠΈΠΆΠΈΠΌΡ‹Ρ… JavaScript, скорСС всСго, Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ‚ смысла.

РСшСния Π½Π° основС Π²Π΅Π±-сокСтов ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ Ρ‡Ρ€Π΅Π·Π²Ρ‹Ρ‡Π°ΠΉΠ½ΠΎ слоТны. Π Π°Π·Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ JavaScript-ΠΊΠΎΠ΄ для ΠΎΠ΄Π½ΠΎΠΉ страницы Π±ΡƒΠ΄Π΅Ρ‚ достаточно простой Π·Π°Π΄Π°Ρ‡Π΅ΠΉ. Но для создания сСрвСрного прилоТСния Π²Π°ΠΌ ΠΏΠΎΡ‚Ρ€Π΅Π±ΡƒΡŽΡ‚ΡΡ Π±Π΅ΡˆΠ΅Π½Ρ‹Π΅ знания ΠΈ Π½Π°Π²Ρ‹ΠΊΠΈ программирования, Π²ΠΊΠ»ΡŽΡ‡Π°Ρ ΠΏΠΎΠ½ΠΈΠΌΠ°Π½ΠΈΠ΅ ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ‚ΠΎΠ² многопоточности ΠΈ сСтСвого взаимодСйствия.

Для использования Π²Π΅Π±-сокСтов Π½Π° Π²Π΅Π±-сСрвСрС вашСго сайта Π΄ΠΎΠ»ΠΆΠ½Π° ΠΈΡΠΏΠΎΠ»Π½ΡΡ‚ΡŒΡΡ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Π°Ρ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°, которая Π±ΡƒΠ΄Π΅Ρ‚, ΠΊΠ°ΠΊ оТидаСтся, Π½Π°Π·Ρ‹Π²Π°Ρ‚ΡŒΡΡ сСрвСром Π²Π΅Π±-сокСтов. На эту ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ возлагаСтся ΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²Π΅Π½Π½ΠΎΡΡ‚ΡŒ Π·Π° ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ взаимодСйствия всСх участников, ΠΈ послС запуска ΠΎΠ½Π° Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ бСзостановочно.

МногиС хостинговыС ΠΊΠΎΠΌΠΏΠ°Π½ΠΈΠΈ Π½Π΅ Π΄ΠΎΠΏΡƒΡΠΊΠ°ΡŽΡ‚ Π΄ΠΎΠ»Π³ΠΎ Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‰ΠΈΡ… ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌ, Ссли Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π²Ρ‹ Π½Π΅ ΠΎΠΏΠ»Π°Ρ‚ΠΈΡ‚Π΅ Π²Ρ‹Π΄Π΅Π»Π΅Π½Π½Ρ‹ΠΉ Π²Π΅Π±-сСрвСр, Ρ‚.Π΅. сСрвСр, ΠΎΠ±ΡΠ»ΡƒΠΆΠΈΠ²Π°ΡŽΡ‰ΠΈΠΉ лишь ваш сайт. Если Ρƒ вас ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹ΠΉ ΠΎΠ±Ρ‰ΠΈΠΉ хостинг, Π²Ρ‹, скорСС всСго, Π½Π΅ смоТСтС Ρ€Π°Π·ΠΌΠ΅Ρ‰Π°Ρ‚ΡŒ Π½Π° Π½Π΅ΠΌ страницы, Π² ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ Π²Π΅Π±-сокСты. Π”Π°ΠΆΠ΅ Ссли Π²Ρ‹ ΡƒΠΌΡƒΠ΄Ρ€ΠΈΡ‚Π΅ΡΡŒ Π·Π°ΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ сСрвСр Π²Π΅Π±-сокСтов ΠΈ ΡƒΠ΄Π΅Ρ€ΠΆΠΈΠ²Π°Ρ‚ΡŒ Π΅Π³ΠΎ Π² Ρ€Π°Π±ΠΎΡ‡Π΅ΠΌ состоянии, Π²Π»Π°Π΄Π΅Π»Π΅Ρ† вашСго хостинга, скорСС всСго, выявит ΠΈ Π²Ρ‹ΠΊΠ»ΡŽΡ‡

Π‘ΠΊΠ°Π· ΠΎ Ρ‚ΠΎΠΌ ΠΊΠ°ΠΊ я свой REST Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊ с Π²Π΅Π±-сокСтами писал / Π₯Π°Π±Ρ€

Π­Ρ‚Π° ΡΡ‚Π°Ρ‚ΡŒΡ посвящСна ΠΎΡ‡Π΅Ρ€Π΅Π΄Π½ΠΎΠΌΡƒ REST Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΡƒ (для Python 3), ΠΎΡΠΎΠ±Π΅Π½Π½ΠΎΡΡ‚ΡŒΡŽ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ являСтся использованиС Π²Π΅Π±-сокСтов для ΠΎΠ±ΠΌΠ΅Π½Π° Π΄Π°Π½Π½Ρ‹ΠΌΠΈ ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ ΠΈ сСрвСром. О Ρ‚ΠΎΠΌ ΠΎΡ‚ΠΊΡƒΠ΄Π° ΠΏΡ€ΠΈΡˆΠ»Π° идСя, с Ρ‡Π΅ΠΌ ΠΌΠ½Π΅ ΠΏΡ€ΠΈΡˆΠ»ΠΎΡΡŒ столкнулся ΠΏΡ€ΠΈ написании своСй ΠΏΠ΅Ρ€Π²ΠΎΠΉ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ для Python ΠΈ Ρ‡Ρ‚ΠΎ ΠΈΠ· этого Π² ΠΈΡ‚ΠΎΠ³Π΅ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ»ΠΎΡΡŒ, я расскаТу Π΄Π°Π»Π΅Π΅.
Для Ρ‚Π΅Ρ…, ΠΊΠΎΠΌΡƒ интСрСсна эта ΡΡ‚Π°Ρ‚ΡŒΡ β€” поТалуйста, Π·Π°Ρ…ΠΎΠ΄ΠΈΡ‚Π΅ ΠΏΠΎΠ΄ ΠΊΠ°Ρ‚.

1. ИдСя ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°

ИдСя Π·Π°Ρ€ΠΎΠ΄ΠΈΠ»Π°ΡΡŒ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ Π² сСрСдинС АпрСлС 2015, ΠΊΠΎΠ³Π΄Π° я задСрТался с ΠΊΠΎΠ»Π»Π΅Π³ΠΎΠΉ Π½Π° Ρ€Π°Π±ΠΎΡ‚Π΅, с ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ ΠΌΡ‹ числимся Π½Π° ΠΎΠ΄Π½ΠΎΠΌ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π΅ Π² своСй ΠΊΠΎΠ½Ρ‚ΠΎΡ€Π΅. Π§Ρ‚ΠΎΠ±Ρ‹ ΠΊΠ°ΠΊ-Ρ‚ΠΎ минимально сСбя Ρ€Π°Π·Π²Π»Π΅Ρ‡ΡŒ, ΠΏΠΎΠΊΠ° занимались нСпосрСдствСнно ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ, ΠΌΡ‹ Ρ€Π΅ΡˆΠΈΠ»ΠΈ ΠΏΠΎΠ³ΠΎΠ²ΠΎΡ€ΠΈΡ‚ΡŒ ΠΎ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… интСрСсных питоновских ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°Ρ…. Π’ процСссС общСния ΠΊΠ°ΠΊ-Ρ‚ΠΎ спонтанно подошли ΠΊ Ρ‚Π΅ΠΌΠ΅ ΠΎ собствСнных ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°Ρ… ΠΈ Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ ΠΌΠΎΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ Π±Ρ‹ интСрСсно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π΄Π°Π»Π΅Π΅ Π² своих ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°Ρ… (Π½Π΅ ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ связанных с Ρ€Π°Π±ΠΎΡ‚ΠΎΠΉ). ΠŸΡ€ΠΈ обсуТдСнии нСпосрСдствСнно ΠΈ Π²ΠΎΠ·Π½ΠΈΠΊΠ»Π° идСя Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ Π±Ρ‹Π»ΠΎ Π±Ρ‹ классно ΠΈΠΌΠ΅Ρ‚ΡŒ достаточно Β«Π³ΠΈΠ±ΠΊΠΈΠΉΒ» Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ Π²Π΅Π±-сокСты, Ρ‡Π΅Ρ€Π΅Π· ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ Π² ΠΎΠ±Π΅ стороны Π±Π΅Π· ΠΊΠ°ΠΊΠΈΡ…-Π»ΠΈΠ±ΠΎ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ. ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ запрос ΠΏΡ€ΠΈΡ…ΠΎΠ΄ΠΈΡ‚ Π² JSON Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅ ΠΈ содСрТит Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΏΡ€ΠΈΠ²Ρ‹Ρ‡Π½Ρ‹ ΠΏΡ€ΠΈ использовании REST ΠΈ HTTP ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π°. И Π² качСствС приятного дополнСния прСдоставляСт Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ ΡƒΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠΉ (Π½ΠΎΡ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΉ) со стороны сСрвСра ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ ΠΈΠ· ΠΊΠΎΡ€ΠΎΠ±ΠΊΠΈ ΠΏΠΎ ΠΊΠ°ΠΊΠΎΠΌΡƒ-Ρ‚ΠΎ ΡΠΎΠ±Ρ‹Ρ‚ΠΈΡŽ/Ρ‚Π°ΠΉΠΌ-Π°ΡƒΡ‚Ρƒ.

ЕстСствСнно послС ΡΡ‚ΠΎΠ»ΡŒ ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ обсуТдСния я Ρ€Π΅ΡˆΠΈΠ»ΡΡ Π²ΠΎΠΏΠ»ΠΎΡ‚ΠΈΡ‚ΡŒ эту идСю Π² Тизнь (Π° ΠΏΠΎΡ‡Π΅ΠΌΡƒ Π±Ρ‹ ΠΈ Π΄Π°?). БобствСнный интСрСс, энтузиазм ΠΈ ΠΆΠ΅Π»Π°Π½ΠΈΠ΅ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Ρ‡Ρ‚ΠΎ-Π½ΠΈΠ±ΡƒΠ΄ΡŒ ΠΏΠΎΠ»Π΅Π·Π½ΠΎΠ΅ для развития экосистСмы Ρ‚Ρ€Π΅Ρ‚ΡŒΠ΅Π³ΠΎ Python’Π° Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π΄Π°Π²Π°Π»ΠΎ лишнюю ΠΌΠΎΡ‚ΠΈΠ²Π°Ρ†ΠΈΡŽ побыстрСС ΠΏΡ€ΠΈΡΡ‚ΡƒΠΏΠΈΡ‚ΡŒ ΠΊ Π΄Π΅Π»Ρƒ.

2. ΠŸΠΎΡΡ‚Π°Π½ΠΎΠ²ΠΊΠ° Ρ†Π΅Π»Π΅ΠΉ

Для сСбя, Π»ΠΈΡ‡Π½ΠΎ, я Π²Ρ‹Π΄Π΅Π»ΠΈΠ» Π΅Ρ‰Π΅ нСсколько Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… ΠΌΠΎΠΌΠ΅Π½Ρ‚ΠΎΠ², Π½Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π±Ρ‹Π»ΠΎ Ρ‚Π°ΠΊΠΆΠ΅ Ρ€Π΅ΡˆΠ΅Π½ΠΎ ΡΠΎΡΡ€Π΅Π΄ΠΎΡ‚ΠΎΡ‡ΠΈΡ‚ΡŒ собствСнныС усилия ΠΏΡ€ΠΈ написании Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ, ΠΊΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ Π±Ρ‹ упомянуто Ρ€Π°Π½Π΅Π΅:

  • ΠŸΠΎΡΡ‚Π°Ρ€Π°Ρ‚ΡŒΡΡ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ asyncio ΠΏΡ€ΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅ клиСнтских запросов
  • НС Π±ΠΎΠ»Π΅Π΅ 1-2 зависимых ΠΌΠΎΠ΄ΡƒΠ»Π΅ΠΉ (Ρ‡Π΅ΠΌ мСньшС, Ρ‚Π΅ΠΌ Π»ΡƒΡ‡ΡˆΠ΅)
  • НС Π΄ΠΎΠ»ΠΆΠ½Π° Π±Ρ‹Ρ‚ΡŒ слишком слоТной для понимания
  • Π›Π΅Π³ΠΊΠΎΡΡ‚ΡŒ Π² использовании (см. Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΠΈ Django REST, Flask, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ достаточно простыС ΠΈ Π³ΠΈΠ±ΠΊΠΈΠ΅)
  • ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡΡ‚ ΠΌΠΎΠΆΠ΅Ρ‚ Π·Π°ΠΌΠ΅Π½ΠΈΡ‚ΡŒ практичСски любой ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚, Ρ‚ΠΎΠ³Π΄Π°, ΠΊΠΎΠ³Π΄Π° Π΅ΠΌΡƒ это Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ

ЕстСствСнно, Π²Ρ‹ΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ Π² ΠΏΠ΅Ρ€Π²ΠΎΠΉ ΠΆΠ΅ вСрсии всС Π²Ρ‹ΡˆΠ΅ΡƒΠΏΠΎΠΌΡΠ½ΡƒΡ‚ΠΎΠ΅ для мСня Π±Ρ‹Π»ΠΎ совсСм Ρ‡Π΅ΠΌ-Ρ‚ΠΎ Π½Π΅Ρ€Π΅Π°Π»ΡŒΠ½Ρ‹ΠΌ, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΈΠ· процСсса Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ я просто Π±Ρ‹ Π½Π΅ Π²Ρ‹Ρ…ΠΎΠ΄ΠΈΠ», поэтому Π² цСлях нСбольшого упрощСния Π±Ρ‹Π»ΠΎ принято Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ Ρ€Π°Π·Π±ΠΈΡ‚ΡŒ всС Π½Π° нСбольшиС «кусочки». Π˜Ρ… ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ, ΠΏΡ€ΠΎΡ‚Π΅ΡΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ, ΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ Π² Ρ€Π΅Π»ΠΈΠ·, Π° Π·Π°Ρ‚Π΅ΠΌ ΡƒΠΆΠ΅ Π΄Π΅Π»Π°Ρ‚ΡŒ ΠΏΠΎ Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½ΠΎΠΉ схСмС всС ΠΎΡΡ‚Π°Π²ΡˆΠ΅Π΅ΡΡ. Π‘Π½Π°Ρ‡Π°Π»Π° пишСм Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ являСтся Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ ΠΊΡ€ΠΈΡ‚ΠΈΡ‡Π½Ρ‹ΠΌ для Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ (Ρ€ΠΎΡƒΡ‚ΠΈΠ½Π³, Π²ΡŒΡŽΡ…ΠΈ, аутСнтификация, ΠΈ Ρ‚.Π΄.), Π° ΠΏΠΎΠ·Π΄Π½Π΅Π΅, ΠΏΠΎ ΠΌΠ΅Ρ€Π΅ возмоТностСй, добавляСм Π½ΠΎΠ²Ρ‹ΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π».

3. ΠŸΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²ΠΊΠ° ΠΊ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅: Π²Ρ‹Π±ΠΎΡ€ ΠΌΠ΅ΠΆΠ΄Ρƒ Aiohttp vs Gevent vs Autobahn.ws

Π Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π½Π°Ρ‡Π°Π»Π°ΡΡŒ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ Π² ΠΊΠΎΠ½Ρ†Π΅ АпрСля 2015. Π§Ρ‚ΠΎΠ±Ρ‹ ΠΊΠ°ΠΊ-Ρ‚ΠΎ ΠΎΠ±Π»Π΅Π³Ρ‡ΠΈΡ‚ΡŒ сСбС Ρ€Π°Π±ΠΎΡ‚Ρƒ ΠΏΡ€ΠΈ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°, Π½Π°Ρ‡Π°Π»ΠΈΡΡŒ поиски ΠΊΠ°ΠΊΠΈΡ…-Π»ΠΈΠ±ΠΎ ΡƒΠΆΠ΅ Π³ΠΎΡ‚ΠΎΠ²Ρ‹Ρ… Ρ€Π΅ΡˆΠ΅Π½ΠΈΠΉ (ΠΈΠ»ΠΈ ΡƒΠΆΠ΅ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΡ… Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊ, ΠΎ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Ρ€Π°Π½Π΅Π΅ Π½Π΅ ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π»). Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π±Ρ‹ ΠΈΠΌΠ΅Π»ΠΈ ΡΡ…ΠΎΠΆΡƒΡŽ идСю с ΠΌΠΎΠ΅ΠΉ ΠΈΠ»ΠΈ хотя Π±Ρ‹ минимально ΠΈΠΌΠ΅Π»ΠΈ ΠΈΠ· ΠΊΠΎΡ€ΠΎΠ±ΠΊΠΈ Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ прСдполагаСтся ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ – Π½Π΅ нашлось. Π­Ρ‚ΠΎ ΠΏΡ€ΠΈΠ²Π΅Π»ΠΎ ΠΊ ΡƒΡΠ»ΠΎΠΆΠ½Π΅Π½ΠΈΡŽ Π·Π°Π΄Π°Ρ‡ΠΈ, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Π±ΠΎΠ»ΡŒΡˆΡƒΡŽ Ρ‡Π°ΡΡ‚ΡŒ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Ρ… ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ² потрСбуСтся Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ ΡΠ°ΠΌΠΎΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎ, исходя ΠΈΠ· собствСнного понимания всСх происходящих процСссов.

Π― Ρ€Π΅ΡˆΠΈΠ» Π½Π°Ρ‡Π°Ρ‚ΡŒ нСпосрСдствСнно с Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π΄Π°ΡŽΡ‚ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π²Π΅Π±-сокСты. На Ρ‚ΠΎΡ‚ ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ Π±Ρ‹Π»ΠΎ Π½Π°ΠΉΠ΄Π΅Π½ΠΎ нСсколько Ρ‚Π°ΠΊΠΈΡ… ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΠ²: aiohttp, gevent ΠΈ autobahn.ws. Π£ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ Π΅ΡΡ‚ΡŒ свои достоинства ΠΈ нСдостатки, Π½ΠΎ, Π² ΠΏΠ΅Ρ€Π²ΡƒΡŽ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ, я исходил ΠΈΠ· ΠΈΡ… возмоТностСй ΠΈ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΠ³ΠΎ дальнСйшСго ΠΏΠ΅Ρ€Π΅ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Π½ΠΈΡ ΠΊΠΎΠ΄Π°, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π½Π΅ ΠΏΡ€ΠΈΡ…ΠΎΠ΄ΠΈΠ»ΠΎΡΡŒ Π² ΠΎΡ‡Π΅Ρ€Π΅Π΄Π½ΠΎΠΉ Ρ€Π°Π· Π³ΠΎΡ€ΠΎΠ΄ΠΈΡ‚ΡŒ свои вСлосипСды, особСнно Ρ‚Π°ΠΌ, Π³Π΄Π΅ это Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ.

Aiohttp – Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° для Π²Π΅Π±-Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ, Π±Π°Π·ΠΈΡ€ΡƒΡŽΡ‰Π°Ρ Π½Π° стандартной Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ΅ asyncio ΠΈ разработанная svetlov. НС ΡΠΊΠ°Π·Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ Ρƒ мСня Π±Ρ‹Π» ΠΊΠ°ΠΊΠΎΠΉ-Ρ‚ΠΎ большой Ρ€Π΅Π°Π»ΡŒΠ½Ρ‹ΠΉ ΠΎΠΏΡ‹Ρ‚ использования этой Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ, хотя стоит ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ сдСлано мноТСство Π²Π΅Ρ‰Π΅ΠΉ ΠΎΡ‡Π΅Π½ΡŒ классно. Однако, ΠΏΡ€Π΅Π΄Π»Π°Π³Π°Π΅ΠΌΠΎΠ΅ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ с Π²Π΅Π±-сокСтами показалось ΠΌΠ½Π΅ нСсколько Π½ΠΈΠ·ΠΊΠΎΡƒΡ€ΠΎΠ²Π½Π΅Π²Ρ‹ΠΌ (хотя, Π² рядС случаСв это Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΡƒΠ΄ΠΎΠ±Π½ΠΎ). Π₯ΠΎΡ‚Π΅Π»ΠΎΡΡŒ ΠΊΠ°ΠΊΠΎΠ³ΠΎ-Ρ‚ΠΎ большСго уровня абстракции (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΊΠ°ΠΊ Π² gevent-websocket ΠΈΠ»ΠΈ autobahn.ws, Π³Π΄Π΅ Π² ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π΅/сСрвСрС Π΅ΡΡ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ Π²Ρ€ΠΎΠ΄Π΅ onMessage ΠΈ sendMessage, ΡΡ‚ΠΎΠ»ΡŒ ΠΏΠΎΡ…ΠΎΠΆΠΈΠ΅ Π½Π° ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ ΠΈΠ· событийно-ΠΎΡ€ΠΈΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΠ° Twisted). Π’ ΠΎΡΡ‚Π°Π»ΡŒΠ½ΠΎΠΌ ΠΆΠ΅ – Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° прСкрасна.

Gevent ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π²ΠΎΠΌ рассмотрСнии Π±Ρ‹Π» ΠΎΠ΄Π½ΠΈΠΌ ΠΈΠ· Ρ‚Π΅Ρ… ΠΏΠ΅Ρ€Π²Ρ‹Ρ… ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΠ², Π½Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π±Ρ‹Π»ΠΎ заострСно внимания. И Ρ‚Π°ΠΊΠΆΠ΅ быстро идСя ΠΎ использовании Π΅Ρ‘ Π±Ρ‹Π»Π° ΠΎΡ‚ΠΊΠ»ΠΎΠ½Π΅Π½Π°: Π½Π° ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ Π½Π°Ρ‡Π°Π»Π° ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° (ΠΠΏΡ€Π΅Π»ΡŒ 2015) gevent Π½Π΅ Π±Ρ‹Π» ΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½ ΠΏΠΎΠ΄ Ρ‚Ρ€Π΅Ρ‚ΡŒΡŽ Π²Π΅Ρ‚ΠΊΡƒ языка Python. Π₯отя, Ссли Π±Ρ‹ всС ΠΆΠ΅ ΠΎΠ½Π° Π±Ρ‹Π»Π° ΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Π°, Ρ‚ΠΎ я использовал Π±Ρ‹ ΠΈΠΌΠ΅Π½Π½ΠΎ Π΅Ρ‘, взяв ΠΏΡ€ΠΈ этом Π΅Ρ‰Π΅ Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΠ΅ gevent-websocket ΠΈ всС ΠΌΠΎΠ³Π»ΠΎ Π±Ρ‹ Π²Ρ‹ΠΉΡ‚ΠΈ ΠΎΡ‡Π΅Π½ΡŒ Π΄Π°ΠΆΠ΅ Π½Π΅ΠΏΠ»ΠΎΡ…ΠΎ. На ΠΌΠΎΠΌΠ΅Π½Ρ‚ написания ΡΡ‚Π°Ρ‚ΡŒΠΈ данная Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° ΡƒΠΆΠ΅ ΠΈΠΌΠ΅Π΅Ρ‚ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΡƒ Ρ‚Ρ€Π΅Ρ‚ΡŒΠ΅ΠΉ Π²Π΅Ρ‚ΠΊΠΈ, Π½ΠΎ ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΡ‚ΡŒ Π½Π° Π½Π΅Π΅ сСйчас я Π½Π΅ Π²ΠΈΠΆΡƒ Π½ΠΈΠΊΠ°ΠΊΠΎΠ³ΠΎ смысла.

Autobahn.ws – это Ρ‚Π° Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°, с ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΠΌΠ½Π΅ ΡƒΠΆΠ΅ Ρ€Π°Π½Π΅Π΅ ΠΏΡ€ΠΈΡ…ΠΎΠ΄ΠΈΠ»ΠΎΡΡŒ Π½Π΅ΠΎΠ΄Π½ΠΎΠΊΡ€Π°Ρ‚Π½ΠΎ ΡΡ‚Π°Π»ΠΊΠΈΠ²Π°Ρ‚ΡŒΡΡ ΠΏΡ€ΠΈ написании своих Π½Π΅Π±ΠΎΠ»ΡŒΡˆΠΈΡ… pet-ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΎΠ² ΠΈ с ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ Ρƒ мСня ΡƒΠΆΠ΅ имССтся Π½Π΅ΠΊΠΈΠΉ ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ ΠΎΠΏΡ‹Ρ‚ использования. Достаточно Π½Π΅ΠΏΠ»ΠΎΡ…ΠΎΠ΅ ΠΊΠΎΠΌΠΌΡŒΡŽΠ½ΠΈΡ‚ΠΈ, плюс Π°Π²Ρ‚ΠΎΡ€ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ всСгда Π³ΠΎΡ‚ΠΎΠ² ΠΏΠΎΠΌΠΎΡ‡ΡŒ Π² случаС Π²ΠΎΠ·Π½ΠΈΠΊΡˆΠΈΡ… ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΊΠΎΠ³Π΄Π° Ρƒ мСня Π½Π΅ ΠΏΠΎΠ»ΡƒΡ‡Π°Π»ΠΎΡΡŒ ΡΠΎΠ²ΠΌΠ΅ΡΡ‚ΠΈΡ‚ΡŒ Π΅Π΅ с Twisted + wxPython, Вобиас ΠΎΡ‡Π΅Π½ΡŒ Ρ…ΠΎΡ€ΠΎΡˆΠΎ объяснил ΠΌΠ½Π΅ ΠΊΠ°ΠΊ это ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ). ПослСдниС вСрсии совмСстимы с asyncio, достаточно Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€Ρ‹ Π² Ρ‚Ρ€Π΅Π±ΡƒΠ΅ΠΌΡ‹Ρ… мСстах. ΠŸΡ€ΠΈΡΡ‚Π½ΠΎΠΉ ΠΎΡΠΎΠ±Π΅Π½Π½ΠΎΡΡ‚ΡŒΡŽ Π΅Ρ‰Π΅ Π±Ρ‹Π»ΠΎ соотвСтствиС Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Ρƒ RFC6455 ΠΈ Π½Π°Π»ΠΈΡ‡ΠΈΠ΅ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ входящих/исходящих Π΄Π°Π½Π½Ρ‹Ρ… (поступили/ΠΎΡ‚ΠΏΡ€Π°Π²Π»Π΅Π½Ρ‹ Π»ΠΈ ΠΎΠ½ΠΈ Π² UTF-8 ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²ΠΊΠ΅, Ρ‡Ρ‚ΠΎ я ΡΡ‡ΠΈΡ‚Π°ΡŽ достаточно ΡƒΠ΄ΠΎΠ±Π½ΠΎ). ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ Π±Ρ‹Π»ΠΎ принято Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΈΠΌΠ΅Π½Π½ΠΎ Π΅Ρ‘ Π² качСствС основы для Π±ΡƒΠ΄ΡƒΡ‰Π΅ΠΉ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ.

4. ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹, возникшиС ΠΏΡ€ΠΈ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅

ΠŸΡ€ΠΈ написании ΠΏΠ΅Ρ€Π²ΠΎΠΉ вСрсии Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ я просто Π½Π΅ Π·Π½Π°Π» ΠΊΠ°ΠΊ ΠΏΠΎΠ΄ΡΡ‚ΡƒΠΏΠΈΡ‚ΡŒΡΡ ΠΊ Ρ€Π΅ΡˆΠ΅Π½ΠΈΡŽ ряда Π·Π°Π΄Π°Ρ‡. ПослС Π½Π΅ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… Ρ€Π°Π·ΠΌΡ‹ΡˆΠ»Π΅Π½ΠΈΠΉ я Ρ€Π΅ΡˆΠΈΠ» просто ΠΈΠ΄Ρ‚ΠΈ ΠΏΡ€ΠΈ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΏΠΎ ΠΏΡƒΡ‚ΠΈ Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ сСрвСр ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π» Π±Ρ‹ ΠΏΠΎΡΡ‚ΡƒΠΏΠΈΠ²ΡˆΠΈΠΉ запрос ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°, Π²Ρ€ΠΎΠ΄Π΅:

1) ΠŸΠΎΠ»ΡƒΡ‡ΠΈΠ»ΠΈ запрос

2) ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΈΠ»ΠΈ Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΈΡˆΠ»ΠΈ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅, Π½Π° основС ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… станСт понятно ΠΊΠ°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ запрос (Ρ‚ΠΈΠΏ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ, ΠΊΡƒΠ΄Π° обращаСмся, ΠΈ Ρ‚.Π΄.)

3) Π˜Ρ‰Π΅ΠΌ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ, ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ ΠΏΠΎΡΡ‚ΡƒΠΏΠΈΠ²ΡˆΠ΅ΠΌΡƒ запросу (ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΡƒΡŽ Ρ‚ΠΎΡ‡ΠΊΡƒ Π²Ρ…ΠΎΠ΄Π° ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒΡΡ). Если Π½ΠΈΡ‡Π΅Π³ΠΎ Π½Π΅ нашли – Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌ ΠΎΡˆΠΈΠ±ΠΊΡƒ. Если ΠΆΠ΅ всС ΠΎΡ‚Π»ΠΈΡ‡Π½ΠΎ, Ρ‚ΠΎ Π²Ρ‹Π±ΠΈΡ€Π°Π΅ΠΌ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ ΠΈ Π² Π½Π΅Π³ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Π΅ΠΌ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹Π΅ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹

4) Π‘Ρ„ΠΎΡ€ΠΌΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ ΠΎΡ‚Π²Π΅Ρ‚ ΠΏΡ€ΠΈΠ²Π΅Π»ΠΈ ΠΊ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠΌΡƒ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Ρƒ (JSON, XML, ΠΈ Ρ‚.Π΄.)

5) Π’Π΅Ρ€Π½ΡƒΠ»ΠΈ ΠΎΡ‚Π²Π΅Ρ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ

Π’ Ρ‚Π΅ΠΎΡ€ΠΈΠΈ всС Π·Π²ΡƒΡ‡ΠΈΡ‚ довольно просто, Π½Π° Π΄Π΅Π»Π΅ всС оказалось всС Π² точности Π½Π°ΠΎΠ±ΠΎΡ€ΠΎΡ‚. ЕдинствСнноС, Ρ‡Ρ‚ΠΎ ΠΌΠ½Π΅ ΠΏΡ€ΠΈΡ…ΠΎΠ΄ΠΈΠ»ΠΎ Π² Π³ΠΎΠ»ΠΎΠ²Ρƒ, это ΠΈΠ΄Ρ‚ΠΈ ΠΎΡ‚ высокого уровня абстракции ΠΊ Π½ΠΈΠΆΠ½ΠΈΠΌ. Π’ΠΎ Π΅ΡΡ‚ΡŒ я шСл ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, ΠΊΠΎΠ³Π΄Π° ΠΌΡ‹ Ρ€Π°Π±ΠΎΡ‚Π°Π΅ΠΌ с Autobahn.ws ΠΈ asyncio loop:

1) Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ экзСмпляр Β«Ρ„Π°Π±Ρ€ΠΈΠΊΠΈΒ», ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ asyncio loop ΠΈ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Ρ‚ΡŒ входящиС ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ ΠΈ ΠΎΠ±ΡΠ»ΡƒΠΆΠΈΠ²Π°Ρ‚ΡŒ ΠΈΡ…. ПослС Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½Π½ΠΎΠ³ΠΎ «процСсса рукопоТатия» ΠΌΡ‹ Π³ΠΎΡ‚ΠΎΠ²Ρ‹ ΠΏΠΎΠ»ΡƒΡ‡Π°Ρ‚ΡŒ запросы ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ ΠΈΡ… ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ.

2) ΠŸΠΎΠ»ΡƒΡ‡ΠΈΠ»ΠΈ запрос ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° Π² ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠΌ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅. Π’ нашСм случаС ΠΌΡ‹ Π±ΡƒΠ΄Π΅ΠΌ ΠΏΠΎΠ»ΡƒΡ‡Π°Ρ‚ΡŒ Π΅Π³ΠΎ Π² Π²ΠΈΠ΄Π΅ JSON ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ:

{
   'method': 'POST', 
   'url': '/users/create',
   'args': {
       'token': 'aGFicmFoYWJyX2FkbWlu'
   },
   'data': {
       'username': 'habrahabr',
       'password': 'mysupersecretpassword',
   }
}

Π­Ρ‚ΠΎΡ‚ JSON ΠΈΠΌΠ΅Π΅Ρ‚ достаточно ΠΏΡ€ΠΎΡΡ‚ΡƒΡŽ структуру. ΠšΠ»ΠΈΠ΅Π½Ρ‚ достаточно ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ нСсколько Π²Π°ΠΆΠ½Ρ‹Ρ… для нас ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ²:

  • method – Ρ‚ΠΈΠΏ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ Π½Π°Π΄ рСсурсом (ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎ Ρ‚ΠΎΠΌΡƒ, ΠΊΠ°ΠΊ это сдСлано Π² HTTP).
  • url – ΠΏΡƒΡ‚ΡŒ ΠΊ рСсурсу, с ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ Ρ…ΠΎΡ‚ΠΈΠΌ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ.
  • args (ΠΎΠΏΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎ) – Π½Π°Π±ΠΎΡ€ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ², отсылаСмых сСрвСру. НаиболСС близкая аналогия это опрСдСляСмыС ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ Π² URL’Π΅ HTTP запроса с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ «?» ΠΈ «&» символов, Π²Ρ€ΠΎΠ΄Π΅ Β«habrahabr.ru/?page=2&paginate_by=25Β». Π­Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΊΠ°ΠΊΠΎΠΉ-Ρ‚ΠΎ список Π³ΠΎΡ‚ΠΎΠ²Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ… (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Ρ‹ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ Π½Π°Π΄ΠΎ Π½Π°Π·Π½Π°Ρ‡ΠΈΡ‚ΡŒ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΡƒΡŽ Π³Ρ€ΡƒΠΏΠΏΡƒ) ΠΈΠ»ΠΈ просто Π½Π°Π±ΠΎΡ€ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² для ΠΊΠ°ΠΊΠΈΡ…-Π»ΠΈΠ±ΠΎ Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ΠΎΠ², ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Ρ… Π½Π° сторонС сСрвСра Π² процСссС ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ запроса.
  • data (ΠΎΠΏΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎ) – Π½Π°Π±ΠΎΡ€ Π΄Π°Π½Π½Ρ‹Ρ…, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Ρ… ΠΏΡ€ΠΈ Ρ€Π°Π±ΠΎΡ‚Π΅ с рСсурсом. Π’ Ρ†Π΅Π»ΠΎΠΌ, ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΡΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ это Π½Π΅ΠΊΠΈΠΉ Π°Π½Π°Π»ΠΎΠ³ Ρ‚Π΅Π»Ρƒ HTTP запроса.
  • event_name (ΠΎΠΏΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎ) β€” Π½Π΅ΠΊΠΈΠΉ ΡƒΠ½ΠΈΠΊΠ°Π»ΡŒΠ½Ρ‹ΠΉ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€, с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ½ΡΡ‚ΡŒ ΠΎΡ‚ ΠΊΠ°ΠΊΠΎΠ³ΠΎ endpoint’Π° Π²Π΅Ρ€Π½ΡƒΠ»ΠΈΡΡŒ Π΄Π°Π½Π½Ρ‹Π΅.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ Ρ‚Π°ΠΊΠΎΠ³ΠΎ Π²ΠΈΠ΄Π° запросы Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠΆΠΈΠ΄Π°Ρ‚ΡŒ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ наш сСрвСр. Если ΠΊΠ°ΠΊΠΎΠ³ΠΎ-Π»ΠΈΠ±ΠΎ ΠΈΠ· ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² Π½Π΅Ρ‚Ρƒ – Π³ΠΎΠ²ΠΎΡ€ΠΈΠΌ ΠΎΠ± этом сразу (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π·Π°Π±Ρ‹Π»ΠΈ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ method). Π’ ΠΏΡ€ΠΎΡ‚ΠΈΠ²Π½ΠΎΠΌ случаС ΠΈΠ΄Π΅ΠΌ Π΄Π°Π»Π΅Π΅ ΠΏΠΎ Π½Π°ΡˆΠ΅ΠΌΡƒ списку.

3) Π˜Ρ‚Π°ΠΊ, запрос доставлСн сСрвСру, ΠΎΠ½ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎΠΌ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅ ΠΈ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π΅Π½. Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΌΡ‹ Ρ…ΠΎΡ‚ΠΈΠΌ Π΅Π³ΠΎ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ ΠΈ Π²Π΅Ρ€Π½ΡƒΡ‚ΡŒ ΠΎΡ‚Π²Π΅Ρ‚. Однако, Ρ‡Ρ‚ΠΎ Π½Π°ΠΌ для этого Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ? Π‘ ΠΌΠΎΠ΅ΠΉ Ρ‚ΠΎΡ‡ΠΊΠΈ зрСния, Π½Π° ΠΏΠ΅Ρ€Π²ΠΎΠ΅ врСмя Π±ΡƒΠ΄Π΅Ρ‚ достаточно Π½Π°Π»ΠΈΡ‡ΠΈΠ΅ систСмы Ρ€ΠΎΡƒΡ‚ΠΈΠ½Π³Π°, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‰Π΅ΠΉ Π·Π°Ρ€Π΅Π³ΠΈΡΡ‚Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π½Π° ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹ΠΉ URL Ρ‚Ρ€Π΅Π±ΡƒΠ΅ΠΌΡ‹ΠΉ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±Ρ‹ Ρ„ΠΎΡ€ΠΌΠΈΡ€ΠΎΠ²Π°Π» ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ ΠΎΡ‚Π²Π΅Ρ‚, ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Ρ‹Π²Π°Π» Π΅Π³ΠΎ Π² JSON, XML (ΠΈΠ»ΠΈ любой Π΄Ρ€ΡƒΠ³ΠΎΠΉ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚) ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π» Π΅Π³ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ.

Π’ этом ΠΏΡƒΠ½ΠΊΡ‚Π΅ Ρ…ΠΎΡ‡Ρƒ я ΠΎΠ±Ρ€Π°Ρ‚ΠΈΡ‚ΡŒ вашС Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° Ρ€ΠΎΡƒΡ‚ΠΈΠ½Π³. Π­Ρ‚ΠΎ достаточно Π²Π°ΠΆΠ½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Π½Π°ΠΌ Ρ…ΠΎΡ‚Π΅Π»ΠΎΡΡŒ Π±Ρ‹ ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΡ‚ΡŒ доступ ΠΏΠΎ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌΡƒ фиксированному URL, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠ»ΡƒΡ‡Π°Ρ‚ΡŒ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, список Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΡ… ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ (Π²Ρ€ΠΎΠ΄Π΅ «/users/»). Π‘ Π΄Ρ€ΡƒΠ³ΠΎΠΉ стороны ΠΏΠΎΠ»ΡƒΡ‡Π°Ρ‚ΡŒ доступ ΠΈ ΠΏΠΎ URL ΠΈΠΌΠ΅ΡŽΡ‰ΠΈΡ… Π²ΠΈΠ΄ «/users//», ΠΏΠΎ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ трСбуСтся ΠΏΠΎΠ»ΡƒΡ‡Π°Ρ‚ΡŒ Π΄Π΅Ρ‚Π°Π»ΡŒΠ½ΡƒΡŽ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅. Π’ΠΎ Π΅ΡΡ‚ΡŒ Ρ€ΠΎΡƒΡ‚ΠΈΠ½Π³ ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ Π²ΠΈΠ΄Π° ΠΌΡ‹ Π±ΡƒΠ΄Π΅ΠΌ Ρ€Π°ΡΡΠΌΠ°Ρ‚Ρ€ΠΈΠ²Π°Ρ‚ΡŒ ΠΊΠ°ΠΊ простой, статичСский, Π° Π²Ρ‚ΠΎΡ€ΠΎΠΉ – ΠΊΠ°ΠΊ динамичСский, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Π² ΠΏΡƒΡ‚ΠΈ ΠΊ рСсурсу присутствуСт ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€, ΠΌΠ΅Π½ΡΡŽΡ‰ΠΈΠΉΡΡ ΠΎΡ‚ запроса ΠΊ запросу.

Для Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ этой Π·Π°Π΄Π°Ρ‡ΠΈ Π½Π°ΠΌ ΠΏΠΎΠΌΠΎΠ³ΡƒΡ‚ рСгулярныС выраТСния. ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ€Π°Π·, ΠΊΠΎΠ³Π΄Π° ΠΎΠ±ΡŠΡΠ²Π»ΡΠ΅Ρ‚ΡΡ ΠΏΡƒΡ‚ΡŒ ΠΊ рСсурсу, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€:

router = SimpleRouter()
router.register('/auth/login', LogIn, 'POST')
router.register('/users/{pk}', UserDetail, ['GET', 'PATCH'])

ΠœΡ‹ Π±ΡƒΠ΄Π΅ΠΌ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ Π°Π½Π°Π»ΠΈΠ· ΠΏΡƒΡ‚ΠΈ ΠΊ Ρ‚Π°ΠΊΠΎΠΌΡƒ рСсурсу. И ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ endpoint, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ запросы Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ° ΠΈ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΠΎ ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΌΡƒ ΠΏΡƒΡ‚ΠΈ. Когда ΠΏΡ€ΠΈΠ΄Π΅Ρ‚ запрос Π½Π° этот рСсурс, Π½Π°ΠΌ Π±ΡƒΠ΄Π΅Ρ‚ достаточно ΠΏΡ€ΠΎΠΉΡ‚ΠΈΡΡŒ ΠΏΠΎ ΡΠ»ΠΎΠ²Π°Ρ€ΡŽ, Π³Π΄Π΅ ΠΊΠ»ΡŽΡ‡ΠΎΠΌ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΡƒΡ‚ΡŒ, Π° Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ – ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ. Π’ случаС, Ссли ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠ΅Π½ динамичСский ΠΏΡƒΡ‚ΡŒ, Π² ΠΌΠΎΠΌΠ΅Π½Ρ‚ получСния запроса, ΠΈ ΠΌΡ‹ нашли Ρ‚Ρ€Π΅Π±ΡƒΠ΅ΠΌΡ‹ΠΉ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ, Ρ‚ΠΎ Π±ΡƒΠ΄Π΅ΠΌ ΠΏΡ€ΠΎΠ±Ρ€Π°ΡΡ‹Π²Π°Ρ‚ΡŒ ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠ΅Π½Π½Ρ‹ΠΉ динамичСский ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ Π² мСсто ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ запроса, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π±Ρ‹Π»ΠΎ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹ΠΌ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΏΠΎ ΠΊΠ»ΡŽΡ‡Ρƒ Π»ΠΈΠ±ΠΎ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ ΠΊΠ°ΠΊΡƒΡŽ-Ρ‚ΠΎ ΠΈΠ½ΡƒΡŽ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ с использованиСм этого ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°.

Ну ΠΈ ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎ ΠΆΠ΅ ΡƒΡ‡ΠΈΡ‚Ρ‹Π²Π°Π΅ΠΌ случай, ΠΊΠΎΠ³Π΄Π° ΠΏΡ€ΠΈΡ…ΠΎΠ΄ΠΈΡ‚ запрос Π½Π° Π½Π΅ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ URL. Для Π½Π΅Π³ΠΎ достаточно Π±ΡƒΠ΄Π΅Ρ‚ Π²Π΅Ρ€Π½ΡƒΡ‚ΡŒ ΠΎΡˆΠΈΠ±ΠΊΡƒ с ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹ΠΌ описаниСм.

4) Π—Π΄ΠΎΡ€ΠΎΠ²ΠΎ, Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ ΠΊΠΎΠ΅ Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΎΡΡΠ½ΠΈΠ»ΠΎΡΡŒ. Π£ΠΌΠ΅Π΅ΠΌ Π½Π°Ρ…ΠΎΠ΄ΠΈΡ‚ΡŒ Ρ‚Ρ€Π΅Π±ΡƒΠ΅ΠΌΡ‹Π΅ ΠΏΡƒΡ‚ΠΈ, ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ для Π½ΠΈΡ…, Π° с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ рСгулярок Π½Π°Ρ…ΠΎΠ΄ΠΈΡ‚ΡŒ ΠΈ ΠΏΡ€ΠΎΠ±Ρ€Π°ΡΡ‹Π²Π°Ρ‚ΡŒ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ (для случая Ссли попался динамичСский ΠΏΡƒΡ‚ΡŒ). Π”Π°Π»Π΅Π΅ ΠΌΡ‹ смотрим Π½Π° ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ method, ΡƒΠΊΠ°Π·Π°Π½Π½Ρ‹ΠΉ Π² JSON ΠΈ стараСмся Π½Π°ΠΉΡ‚ΠΈ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄ класса с вьюшки. Если ΠΎΠ½ отсутствуСт – Π³ΠΎΠ²ΠΎΡ€ΠΈΠΌ ΠΎΠ± этом сразу ΠΈ Π½Π΅ выполняСм ΠΊΠ°ΠΊΠΈΡ…-Π»ΠΈΠ±ΠΎ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ. Π’ ΠΏΡ€ΠΎΡ‚ΠΈΠ²Π½ΠΎΠΌ случаС Π΄Π΅Π»Π°Π΅ΠΌ Π²Ρ‹Π·ΠΎΠ² ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠ΅Π½Π½ΠΎΠ³ΠΎ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° ΠΈ Ρ„ΠΎΡ€ΠΌΠΈΡ€ΡƒΠ΅ΠΌ ΠΎΡ‚Π²Π΅Ρ‚.

5) Π”Π°Π»Π΅Π΅ выполняСм ΡΠ΅Ρ€ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ Π΄Π°Π½Π½Ρ‹Ρ… (Π² Ρ‚ΠΎΠΌ числС ΠΈ для случаСв с ошибками) Π² Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚. По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ всС прСобразуСтся Π² JSON Ρ„ΠΎΡ€ΠΌΠ°Ρ‚.

6) ΠŸΠ΅Ρ€Π΅Π΄Π°Π΅ΠΌ сформированный ΠΎΡ‚Π²Π΅Ρ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ ΠΏΠΎ Π²Π΅Π±-сокСту.

И Π²ΠΎΡ‚ ΠΏΠΎ этому ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎΠΌΡƒ ΠΏΠ»Π°Π½Ρƒ я слСдовал Π΄ΠΎ Ρ€Π΅Π»ΠΈΠ·Π° 1.0. Π‘Ρ‹Π»ΠΎ достаточно интСрСсно Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ свои вьюшки, систСму Ρ€ΠΎΡƒΡ‚ΠΈΠ½Π³Π° ΠΈ ΠΏΡ€ΠΎΡ‡ΠΈΠΉ интСрСсный Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π». Π₯отя Π² процСссС написания ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ Ρ€Π΅Π»ΠΈΠ·Π°, ΠΏΠΎ Ρ…ΠΎΠ΄Ρƒ развития этого pet-ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°, ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΎΠ²Π°Π»ΠΈΡΡŒ ΠΌΠΎΠ΄ΡƒΠ»ΠΈ с конфигурациями (Π² нашСм случаС это Π±Ρ‹Π» ΠΌΠΎΠ΄ΡƒΠ»ΡŒ Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½Ρ‹ΠΉ Ρ‚ΠΎΠΌΡƒ, Ρ‡Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ Π² Django). Или, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΡΡ‚ΠΎΠ»ΡŒ нСобходимая ΠΌΠ½Π΅ аутСнтификация ΠΌΠ΅Π΄Π»Π΅Π½Π½ΠΎ ΠΏΡ€ΠΈΠ²Π΅Π»Π° ΠΊ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ middleware ΠΈ JSON Web Token ΠΌΠΎΠ΄ΡƒΠ»Π΅ΠΉ. Как ΠΈ ΡƒΠΏΠΎΠΌΠΈΠ½Π°Π»ΠΎΡΡŒ Ρ€Π°Π½Π΅Π΅ – Π΄Π΅Π»Π°Π΅ΠΌ всСвозмоТныС ΠΌΠΎΠ΄ΡƒΠ»ΠΈ ΡΠ°ΠΌΠΎΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎ, Π½Π΅ стараСмся Ρ‚ΡΠ½ΡƒΡ‚ΡŒ Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ лишнСС.

Π’Π°ΠΊ ΠΈΠ»ΠΈ ΠΈΠ½Π°Ρ‡Π΅, написаниС Β«ΠΎΡ‡Π΅Ρ€Π΅Π΄Π½ΠΎΠ³ΠΎ вСлосипСда» для мСня Π²Ρ‹Π»ΠΈΠ²Π°Π»ΠΎΡΡŒ Π² Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ усилия ΠΈ Π·Π°Ρ‚Ρ€Π°Ρ‚Ρ‹ ΠΏΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ. Π₯отя, чСстно говоря, я совсСм Π½Π΅ ТалСю, Ρ‡Ρ‚ΠΎ пошСл Ρ‚Π°ΠΊΠΈΠΌ ΠΏΡƒΡ‚Π΅ΠΌ, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ врСмя Π·Π°Ρ‚Ρ€Π°Ρ‡Π΅Π½Π½ΠΎΠ΅ Π½Π° написаниС, ΠΎΡ‚Π»Π°Π΄ΠΊΡƒ ΠΈ рСгулярныС Π΄ΠΎΠ΄Π΅Π»ΠΊΠΈ Π΄Π°Π΅Ρ‚ ΠΎ сСбС Π·Π½Π°Ρ‚ΡŒ: сСйчас стал Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ Π»ΡƒΡ‡ΡˆΠ΅ ΠΏΠΎΠ½ΠΈΠΌΠ°Ρ‚ΡŒ, ΠΊΠ°ΠΊ это Π²ΠΎΠΎΠ±Ρ‰Π΅ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚.

Если ΠΏΡ€ΠΈ написании ΠΏΠ΅Ρ€Π²ΠΎΠΉ вСрсии написаниС ΠΊΠΎΠ΄Π° ΠΈ Π΅Π³ΠΎ ΠΎΡ‚Π»Π°Π΄ΠΊΠ° шла достаточно Π½Π΅ΠΏΠ»ΠΎΡ…ΠΎ, Ρ‚ΠΎ ΠΏΡ€ΠΈ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ вСрсии 1.1 я просто Π½Π°Π΄ΠΎΠ»Π³ΠΎ повяз Π² ΠΎΡ‚Π»Π°Π΄ΠΊΠ΅. НаписаниС ΠΈ ΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΊΠΎΠ΄Π° Π½Π΅ Π·Π°Π½ΠΈΠΌΠ°Π»ΠΎ ΡΡ‚ΠΎΠ»ΡŒ ΠΌΠ½ΠΎΠ³ΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ, сколько поиск ΠΈ Π΄Π΅Ρ‚Π°Π»ΡŒΠ½Ρ‹ΠΉ Π°Π½Π°Π»ΠΈΠ· Ρ‚ΠΎΠ³ΠΎ Ρ‡Ρ‚ΠΎ происходит, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€:

1) Анализ исходной ΠΊΠΎΠ΄ΠΎΠ²ΠΎΠΉ Π±Π°Π·Ρ‹ Django REST Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΠ° Π½Π° ΠΏΡ€Π΅Π΄ΠΌΠ΅Ρ‚ Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ ΠΈ ΠΊΠ°ΠΊ происходит Β«ΠΏΠΎΠ΄ ΠΊΠ°ΠΏΠΎΡ‚ΠΎΠΌΒ»: Ρ‡Ρ‚ΠΎ Π΄Π΅Π»Π°Π΅ΠΌ ΠΊΠΎΠ³Π΄Π° Ρ…ΠΎΡ‚ΠΈΠΌ Π·Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ ΠΈΠ»ΠΈ ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚; ΠΊΠΎΠ³Π΄Π° ΠΈ ΠΊΠ°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ ΠΏΠΎΠ½ΠΈΠΌΠ°Π΅ΠΌ, Ρ‡Ρ‚ΠΎ Π·Π° поля Π±Ρ‹Π»ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Ρ‹ (ΠΈ ΠΈΠΌΠ΅ΡŽΡ‚ Π»ΠΈ ΠΎΠ½ΠΈ Π²ΠΎΠΎΠ±Ρ‰Π΅ ΠΊΠ°ΠΊΠΈΠ΅-Ρ‚ΠΎ связи с Π΄Ρ€ΡƒΠ³ΠΈΠΌΠΈ модСлями) ΠΈ Π²ΠΎ Ρ‡Ρ‚ΠΎ трСбуСтся ΠΈΡ… ΡΠ΅Ρ€ΠΈΠ°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ/Π΄Π΅ΡΠ΅Ρ€ΠΈΠ°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ.

2) БСриализация ΠΌΠΎΠ΄Π΅Π»Π΅ΠΉ SQLAlchemy ΠΏΠΎ Π°Π½Π°Π»ΠΎΠ³ΠΈΠΈ с Ρ‚Π΅ΠΌ, ΠΊΠ°ΠΊ это происходит ΠΌΠ΅ΠΆΠ΄Ρƒ Django REST ΠΊΠΎΠ΄ΠΎΠΌ ΠΈ Django ORM.

3) Π˜ΠΌΠ΅Ρ‚ΡŒ Ρ‚Π°ΠΊΡƒΡŽ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ Ρ€Π°Π±ΠΎΡ‚Ρ‹ с Ρ€ΠΎΡƒΡ‚ΠΈΠ½Π³ΠΎΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΌΠΎΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΏΡƒΡ‚ΡŒ Π΄ΠΎ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Ρ‡Π΅Ρ€Π΅Π· ΡƒΠΆΠ΅ написанный API (Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΌΠΎΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ ΠΈ ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ, ΠΈ Π·Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ ΠΊΠ°ΠΊΠΈΠ΅-Ρ‚ΠΎ Π΄Π°Π½Π½Ρ‹Π΅ ΠΏΠΎ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹ΠΌ URL).

ΠŸΡ€ΠΈ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅ этой части Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»Π° ΠΌΠ½Π΅ вСсьма сильно ΠΏΠΎΠΌΠΎΠ³Π»ΠΈ исходныС ΠΊΠΎΠ΄Ρ‹ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ ΠΊΠ°ΠΊ Django REST (которая Π²ΠΎ ΠΌΠ½ΠΎΠ³ΠΎΠΌ являлась основой для ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ вСрсии), Ρ‚Π°ΠΊ ΠΈ исходники SQLAlchemy + marshmallow-sqlalchemy Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π²ΠΎ ΠΌΠ½ΠΎΠ³ΠΎΠΌ ΠΏΠΎΠΌΠΎΠ³Π»ΠΈ Π²ΠΎΠΏΠ»ΠΎΡ‚ΠΈΡ‚ΡŒ всС Π·Π°Π΄ΡƒΠΌΠΊΠΈ Π² Тизнь.

Π₯ΠΎΡ‚ΡŒ ΠΈ Π±Ρ‹Π»ΠΎ Π·Π°Ρ‚Ρ€Π°Ρ‡Π΅Π½ΠΎ ΠΎΡ‡Π΅Π½ΡŒ ΠΌΠ½ΠΎΠ³ΠΎ рСсурсов, Π½ΠΎ ΠΊΠΎΠ½Π΅Ρ‡Π½Ρ‹ΠΉ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ ΠΎΠΏΡ€Π°Π²Π΄Π°Π» всС Π·Π°Ρ‚Ρ€Π°Ρ‚Ρ‹ – Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ ΠΌΡ‹ ΠΈΠΌΠ΅Π΅ΠΌ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с SQLAlchemy Ρ‚Π°ΠΊ, ΠΊΠ°ΠΊ ΠΌΡ‹ ΠΏΡ€ΠΈΠ²Ρ‹ΠΊΠ»ΠΈ это Π΄Π΅Π»Π°Ρ‚ΡŒ Π² Django REST. Π Π°Π±ΠΎΡ‚Π° с Π΄Π°Π½Π½Ρ‹ΠΌΠΈ осущСствляСтся ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²ΠΎ ΠΈ практичСски Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ‚ ΡΠΈΠ»ΡŒΠ½Ρ‹Ρ… ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠΉ. Π—Π΄ΠΎΡ€ΠΎΠ²ΠΎ, Π΄Π°ΠΆΠ΅ практичСски ΠΏΠ΅Ρ€Π΅ΡƒΡ‡ΠΈΠ²Π°Ρ‚ΡŒΡΡ Π½Π΅Ρ‚ нСобходимости: доступный API Π²ΠΎ ΠΌΠ½ΠΎΠ³ΠΎΠΌ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ‡Π΅Π½ Ρ‚ΠΎΠΌΡƒ, Ρ‡Ρ‚ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Π² Django REST.

5. Π’Π΅ΠΊΡƒΡ‰Π΅Π΅ состояниС ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°

На Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° прСдоставляСт ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ возмоТности:

  • Π ΠΎΡƒΡ‚ΠΈΠ½Π³
  • ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° function- ΠΈ class-based вьюшСк
  • АутСнтификация Ρ‡Π΅Ρ€Π΅Π· JSON Web Token (Ρ…ΠΎΡ‚ΡŒ ΠΈ Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΎ)
  • ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° Ρ„Π°ΠΉΠ»Π° с ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠ΅ΠΉ, ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎΠΉ Ρ‚ΠΎΠΉ, Ρ‡Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ Π² Django Framework
  • Π‘ΠΆΠ°Ρ‚ΠΈΠ΅ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Π΅ΠΌΡ‹Ρ… сообщСний (Ссли поддСрТиваСтся Π±Ρ€Π°ΡƒΠ·Π΅Ρ€ΠΎΠΌ ΠΈ установлСно Π½ΡƒΠΆΠ½ΠΎΠ΅ Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΠ΅)
  • БСриализация ΠΌΠΎΠ΄Π΅Π»Π΅ΠΉ Django ΠΈ SQLAlchemy ORM
  • ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° SSL

6. ΠŸΡ€ΠΈΠΌΠ΅Ρ€ использования

Π’ качСствС ΠΊΡ€Π°Ρ‚ΠΊΠΎΠ³ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° ΠΌΠΎΠΆΠ½ΠΎ привСсти ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ ΠΊΠΎΠ΄, Π³Π΄Π΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΡ€ΠΎΠΈΡΡ…ΠΎΠ΄ΠΈΡ‚ΡŒ Ρ€Π°Π±ΠΎΡ‚Π° с ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡΠΌΠΈ ΠΈ email адрСсами. НачнСм Ρ‚Π°Π±Π»ΠΈΡ†, описанных с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ SQLAlchemy ORM:

# -*- coding: utf-8 -*-
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship, validates

Base = declarative_base()


class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    name = Column(String(50), unique=True)
    fullname = Column(String(50), default='Unknown')
    password = Column(String(512))
    addresses = relationship("Address", back_populates="user")

    @validates('name')
    def validate_name(self, key, name):
        assert '@' not in name
        return name

    def __repr__(self):
        return "<User(name='%s', fullname='%s', password='%s')>" % (self.name, self.fullname, self.password)


class Address(Base):
    __tablename__ = 'addresses'
    id = Column(Integer, primary_key=True)
    email_address = Column(String, nullable=False)
    user_id = Column(Integer, ForeignKey('users.id'))
    user = relationship("User", back_populates="addresses")

    def __repr__(self):
        return "<Address(email_address='%s')>" % self.email_address

Π’Π΅ΠΏΠ΅Ρ€ΡŒ опишСм ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠ΅ сСриализаторы для этих Π΄Π²ΡƒΡ… ΠΌΠΎΠ΄Π΅Π»Π΅ΠΉ:

# -*- coding: utf-8 -*-
from app.db import User, Address
from aiorest_ws.db.orm.sqlalchemy import serializers

from sqlalchemy.orm import Query


class AddressSerializer(serializers.ModelSerializer):

    class Meta:
        model = Address
        fields = ('id', 'email_address')


class UserSerializer(serializers.ModelSerializer):
    addresses = serializers.PrimaryKeyRelatedField(queryset=Query(Address), many=True, required=False)

    class Meta:
        model = User

Как ΠΌΠ½ΠΎΠ³ΠΈΠ΅ ΠΈΠ· успСли Π·Π°ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ, Π² мСстС, Π³Π΄Π΅ ΠΌΡ‹ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΠ»ΠΈ класс для сСриализации ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ, ΡƒΠΊΠ°Π·Π°Π½ΠΎ ΠΏΠΎΠ»Π΅ addresses, с Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠΌ queryset=Query(Address) Π² конструкторС класса PrimaryKeyRelatedField. Π­Ρ‚ΠΎ сдСлано для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ сСриализатор для SQLAlchemy ORM ΠΌΠΎΠ³ Π²Ρ‹ΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ связь ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΏΠΎΠ»Π΅ΠΌ addresses ΠΈ Ρ‚Π°Π±Π»ΠΈΡ†Π΅ΠΉ, пСрСдавая Π² этот класс ΠΏΡ€ΠΈ сСриализации ΠΏΠ΅Ρ€Π²ΠΈΡ‡Π½Ρ‹Π΅ ΠΊΠ»ΡŽΡ‡ΠΈ. Π’ ΠΊΠ°ΠΊΠΎΠΉ-Ρ‚ΠΎ стСпСни это Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½ΠΎ QuerySet ΠΈΠ· Django Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΠ°.

Π’Π΅ΠΏΠ΅Ρ€ΡŒ Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠ΅ΠΌ вьюшки, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‰ΠΈΠ΅ Ρ‡Π΅Ρ€Π΅Π· Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ доступный API Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с Π΄Π°Π½Π½Ρ‹ΠΌΠΈ Π² этих Ρ‚Π°Π±Π»ΠΈΡ†Π°Ρ…:

# -*- coding: utf-8 -*-
from aiorest_ws.conf import settings
from aiorest_ws.db.orm.exceptions import ValidationError
from aiorest_ws.views import MethodBasedView

from app.db import User
from app.serializers import AddressSerializer, UserSerializer


class UserListView(MethodBasedView):

    def get(self, request, *args, **kwargs):
        session = settings.SQLALCHEMY_SESSION()
        users = session.query(User).all()
        data = UserSerializer(users, many=True).data 
        session.close()
        return data

    def post(self, request, *args, **kwargs):
        if not request.data:
            raise ValidationError('You must provide arguments for create.')

        if not isinstance(request.data, list):
            raise ValidationError('You must provide a list of objects.')

        serializer = UserSerializer(data=request.data, many=True)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return serializer.data


class UserView(MethodBasedView):

    def get(self, request, id, *args, **kwargs):
        session = settings.SQLALCHEMY_SESSION()
        instance = session.query(User).filter(User.id == id).first()
        data = UserSerializer(instance).data 
        session.close()
        return data

    def put(self, request, id, *args, **kwargs):
        if not request.data:
            raise ValidationError('You must provide an updated instance.')

        session = settings.SQLALCHEMY_SESSION()
        instance = session.query(User).filter(User.id == id).first()
        if not instance:
            raise ValidationError('Object does not exist.')

        serializer = UserSerializer(instance, data=request.data, partial=True)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        session.close()
        return serializer.data


class CreateUserView(MethodBasedView):

    def post(self, request, *args, **kwargs):
        serializer = UserSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return serializer.data


class AddressView(MethodBasedView):

    def get(self, request, id, *args, **kwargs):
        session = settings.SQLALCHEMY_SESSION()
        instance = session.query(User).filter(User.id == id).first()
        session.close()
        return AddressSerializer(instance).data


class CreateAddressView(MethodBasedView):

    def post(self, request, *args, **kwargs):
        serializer = AddressSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        session.close()
        return serializer.data

На Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ ΠΌΡ‹ пишСм ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎ вьюшки для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌΠΈ ΠΈ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎ со списком ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ². Π’ ΠΊΠ°ΠΆΠ΄ΠΎΠΌ ΠΈΠ· Ρ‚Π°ΠΊΠΈΡ… подклассов, унаслСдованных ΠΎΡ‚ MethodBasedView, Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΡŽΡ‚ΡΡ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½Ρ‹Π΅ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π±ΡƒΠ΄ΡƒΡ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ. Для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ° запроса (get/post/put/patch/ ΠΈ Ρ‚.ΠΏ.) ΠΏΠΈΡˆΠ΅Ρ‚ΡΡ свой ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ.

ПослСдним шагом являСтся рСгистрация этого API, ΠΈ Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ½ Π±Ρ‹Π» доступСн Π½Π°ΠΌ ΠΈΠ·Π²Π½Π΅:

# -*- coding: utf-8 -*-
from aiorest_ws.routers import SimpleRouter

from app.views import UserListView, UserView, CreateUserView, AddressView, \
    CreateAddressView

router = SimpleRouter()
router.register('/user/list', UserListView, 'GET')
router.register('/user/{id}', UserView, ['GET', 'PUT'], name='user-detail')
router.register('/user/', CreateUserView, ['POST'])
router.register('/address/{id}', AddressView, ['GET', 'PUT'], name='address-detail')
router.register('/address/', CreateAddressView, ['POST'])

Π’ΠΎΠΎΠ±Ρ‰Π΅ΠΌ-Ρ‚ΠΎ здСсь всС Π³ΠΎΡ‚ΠΎΠ²ΠΎ, остаСтся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π·Π°ΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ сСрвСр ΠΈ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒΡΡ Ρ‡Π΅Ρ€Π΅Π· ΠΊΠ°ΠΊΠΎΠΉ-Π½ΠΈΠ±ΡƒΠ΄ΡŒ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ (Python + Autobahn.ws, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ JavaScript, ΠΈ Ρ‚Π°ΠΊ Π΄Π°Π»Π΅Π΅, Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ΠΎΠ² мноТСство). Для ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° я просто ΠΏΠΎΠΊΠ°ΠΆΡƒ ΠΏΠ°Ρ€ΠΎΡ‡ΠΊΡƒ простых запросов с использованиСм Python + Authobahn.ws (ΠΎΠ³ΠΎΠ²ΠΎΡ€ΡŽΡΡŒ Π·Π°Ρ€Π°Π½Π΅Π΅, ΠΏΡ€ΠΈΠΌΠ΅Ρ€ с ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ Π½Π΅ ΠΈΠ΄Π΅Π°Π»Π΅Π½, здСсь Π·Π°Π΄Π°Ρ‡Π° просто ΠΏΡ€ΠΎΠ΄Π΅ΠΌΠΎΠ½ΡΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠ°ΠΊ ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ это Π΄Π΅Π»Π°Ρ‚ΡŒ):

# -*- coding: utf-8 -*-
import asyncio
import json

from hashlib import sha256
from autobahn.asyncio.websocket import WebSocketClientProtocol, \
    WebSocketClientFactory


def hash_password(password):
    return sha256(password.encode('utf-8')).hexdigest()


class HelloClientProtocol(WebSocketClientProtocol):

    def onOpen(self):
        # Create new address
        request = {
            'method': 'POST',
            'url': '/address/',
            'data': {
                "email_address": '[email protected]'
            },
            'event_name': 'create-address'
        }
        self.sendMessage(json.dumps(request).encode('utf8'))

        # Get users list
        request = {
            'method': 'GET',
            'url': '/user/list/',
            'event_name': 'get-user-list'
        }
        self.sendMessage(json.dumps(request).encode('utf8'))

        # Create new user with address
        request = {
            'method': 'POST',
            'url': '/user/',
            'data': {
                'name': 'Neyton',
                'fullname': 'Neyton Drake',
                'password': hash_password('123456'),
                'addresses': [{"id": 1}, ]
            },
            'event_name': 'create-user'
        }
        self.sendMessage(json.dumps(request).encode('utf8'))

        # Trying to create new user with same info, but we have taken an error
        self.sendMessage(json.dumps(request).encode('utf8'))

        # Update existing object
        request = {
            'method': 'PUT',
            'url': '/user/6/',
            'data': {
                'fullname': 'Definitely not Neyton Drake',
                'addresses': [{"id": 1}, {"id": 2}]
            },
            'event_name': 'partial-update-user'
        }
        self.sendMessage(json.dumps(request).encode('utf8'))


    def onMessage(self, payload, isBinary):
        print("Result: {0}".format(payload.decode('utf8')))


if __name__ == '__main__':
    factory = WebSocketClientFactory("ws://localhost:8080")
    factory.protocol = HelloClientProtocol

    loop = asyncio.get_event_loop()
    coro = loop.create_connection(factory, '127.0.0.1', 8080)
    loop.run_until_complete(coro)
    loop.run_forever()
    loop.close()

Π‘ΠΎΠ»Π΅Π΅ Π΄Π΅Ρ‚Π°Π»ΡŒΠ½ΠΎ ΠΏΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ вСсь исходный ΠΊΠΎΠ΄ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° ΠΌΠΎΠΆΠ½ΠΎ здСсь.

7. Π”Π°Π»ΡŒΠ½Π΅ΠΉΡˆΠ΅Π΅ Ρ€Π°Π·Π²ΠΈΡ‚ΠΈΠ΅

Π•ΡΡ‚ΡŒ достаточно ΠΌΠ½ΠΎΠ³ΠΎ ΠΈΠ΄Π΅ΠΉ ΠΊΠ°ΠΊ Ρ€Π°ΡΡˆΠΈΡ€ΠΈΡ‚ΡŒ Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π» Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ. НапримСр, ΠΌΠΎΠΆΠ½ΠΎ Ρ€Π°Π·Π²ΠΈΠ²Π°Ρ‚ΡŒ Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ Π² ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΡ… направлСниях:

  • ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° ΡƒΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠΉ
  • ΠŸΡ€ΠΎΡΠΌΠΎΡ‚Ρ€ Ρ‡Π΅Ρ€Π΅Π· Π±Ρ€Π°ΡƒΠ·Π΅Ρ€ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ ΠΊ API (Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ Π² Π²ΠΈΠ΄Π΅ ΠΏΠ»Π°Π³ΠΈΠ½Π° для Swagger)
  • ΠœΠΎΠ΄ΡƒΠ»ΠΈ для тСстирования API
  • ΠšΠ»ΠΈΠ΅Π½Ρ‚Ρ‹ для Python ΠΈ JavaScript
  • ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° Pony ΠΈ Peewee ORM’ΠΎΠ²

ΠžΠΏΡΡ‚ΡŒ ΠΆΠ΅ напомню, Ρ‡Ρ‚ΠΎ ΠΌΠ½ΠΎΠ³ΠΈΠ΅ Ρ„ΠΈΡ‡ΠΈ Π·Π°ΠΏΠ»Π°Π½ΠΈΡ€ΠΎΠ²Π°Π½Ρ‹ Π½Π° Ρ€Π°Π·Π½Ρ‹Π΅ Ρ€Π΅Π»ΠΈΠ·Ρ‹, Π° Π½Π΅ Π½Π° ΠΎΠ΄ΠΈΠ½. Π‘Π΄Π΅Π»Π°Π½ΠΎ это ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π½Π΅ ΠΊΠΈΠ΄Π°Ρ‚ΡŒΡΡ ΠΈΠ· крайности Π² ΠΊΡ€Π°ΠΉΠ½ΠΎΡΡ‚ΡŒ, дСлая Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½ΠΎ, вСдь ΠΏΠΎ ΠΈΡ‚ΠΎΠ³Ρƒ Π½ΠΈΡ‡Π΅Π³ΠΎ Π³ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈΠ· этого Π½Π΅ Π²Ρ‹ΠΉΠ΄Π΅Ρ‚. И ΠΌΠ½Π΅ ΠΏΡ€ΠΎΡ‰Π΅, ΠΈ Π²Π°ΠΌ.

8. И Π² Π·Π°ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΈ…

МнС каТСтся ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ»ΠΎΡΡŒ достаточно Π½Π΅ΠΏΠ»ΠΎΡ…ΠΎ для ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ Ρ€Π°Π·Π°, Π½Π΅ смотря Π½Π° отсутствиС ΠΊΠ°ΠΊΠΎΠ³ΠΎ-Π»ΠΈΠ±ΠΎ ΠΎΠΏΡ‹Ρ‚Π° Π² написании собствСнных Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊ. А внСсти свой Π²ΠΊΠ»Π°Π΄ (ΠΏΡƒΡΡ‚ΡŒ Π΄Π°ΠΆΠ΅ ΠΈ нСбольшой) Π² Ρ€Π°Π·Π²ΠΈΡ‚ΠΈΠ΅ языка Python – хочСтся достаточно сильно. НС ΡƒΠ΄ΠΈΠ²Π»ΡΠΉΡ‚Π΅ΡΡŒ Ρ‚ΠΎΠΌΡƒ, сколько Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ Π±Ρ‹Π»ΠΎ Π½Π° это Π±Ρ‹Π»ΠΎ Π·Π°Ρ‚Ρ€Π°Ρ‡Π΅Π½ΠΎ: всС дСлалось (ΠΈ ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ°Π΅Ρ‚ Π΄Π΅Π»Π°Ρ‚ΡŒΡΡ) Π² свободноС врСмя ΠΈ пСриодичСскими ΠΏΠ΅Ρ€Π΅Ρ€Ρ‹Π²Π°ΠΌΠΈ (ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ рСгулярная Ρ€Π°Π±ΠΎΡ‚Π° с ΠΎΠ΄Π½ΠΈΠΌ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΎΠΌ ΠΎΡ‡Π΅Π½ΡŒ утомляСт, Π° Ρ€Π°Π·Π²ΠΈΠ²Π°Ρ‚ΡŒΡΡ хочСтся Π² Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… направлСниях ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ).

Π’Π°ΠΊ ΠΈΠ»ΠΈ ΠΈΠ½Π°Ρ‡Π΅, Π±ΡƒΠ΄Ρƒ Ρ€Π°Π΄ ΡƒΡΠ»Ρ‹ΡˆΠ°Ρ‚ΡŒ всС ваши прСдлоТСния, ΠΈΠ΄Π΅ΠΈ ΠΈ ΡƒΠ»ΡƒΡ‡ΡˆΠ΅Π½ΠΈΡ ΠΏΠΎ Π΄Π°Π½Π½ΠΎΠΉ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ΅ Π² коммСнтариях (ΠΈΠ»ΠΈ Π² Π²ΠΈΠ΄Π΅ ΠΏΡƒΠ» рСквСстов Ρƒ мСня Π½Π° GitHub). НС ΡΡ‚Π΅ΡΠ½ΡΠΉΡ‚Π΅ΡΡŒ Π·Π°Π΄Π°Π²Π°Ρ‚ΡŒ ΠΊΠ°ΠΊΠΈΠ΅-Π»ΠΈΠ±ΠΎ вопросы ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ ΠΈ ΠΊΠ°ΠΊΠΈΡ…-Ρ‚ΠΎ особСнностСй Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ – Π±ΡƒΠ΄Ρƒ Ρ€Π°Π΄ Π»ΡŽΠ±ΠΎΠΌΡƒ Ρ„ΠΈΠ΄Π±Π΅ΠΊΡƒ.

Π’Π΅ΡΡŒ Π²Ρ‹ΡˆΠ΅ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½Ρ‹ΠΉ ΠΊΠΎΠ΄, Π° Ρ‚Π°ΠΊΠΆΠ΅ исходники Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ aiorest-ws, ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Π½Π° GitHub. ΠŸΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ располоТСны Π² ΠΊΠΎΡ€Π½Π΅ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°, Π² ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π΅ examples. Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡŽ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ здСсь.

Spring WebSocket. How it works? / Π₯Π°Π±Ρ€

Π”ΠΎΠ±Ρ€ΠΎΠ³ΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ суток ΡƒΠ²Π°ΠΆΠ°Π΅ΠΌΡ‹Π΅ Ρ…Π°Π±Ρ€Π°Π²Ρ‡Π°Π½Π΅. На ΠΌΠΎΠ΅ΠΌ Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΌ мСстС Ρ€Π°Π±ΠΎΡ‚Ρ‹ Π±Ρ‹Π»ΠΎ принято Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ пСрСвСсти взаимодСйствиС с web ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ Π½Π° WebSocket. БСрвСрная Ρ‡Π°ΡΡ‚ΡŒ написана Π½Π° Java с использованиСм Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΠ° Spring. Π’ Π΄Π°Π½Π½ΠΎΠΉ ΡΡ‚Π°Ρ‚ΡŒΠ΅ я Ρ…ΠΎΡ‚Π΅Π» ΠΏΠΎΠ΄Π΅Π»ΠΈΡ‚ΡŒΡΡ ΠΎΡΠΎΠ±Π΅Π½Π½ΠΎΡΡ‚ΡŒΡŽ устройства Spring WebSocket.

WebSocket обСспСчиваСт Π΄Π²ΡƒΡΡ‚ΠΎΡ€ΠΎΠ½Π½ΡŽΡŽ связь ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ ΠΈ сСрвСром, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ ΠΎΠ΄Π½ΠΎ TCP соСдинСниС.

ΠŸΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» состоит ΠΈΠ· Π΄Π²ΡƒΡ… Ρ„Π°Π·:


Для Handshake запроса ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ HTTP GET запрос, Π² Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ происходит ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ соСдинСния Π΄ΠΎ WebSocket.

Π’ Π΄Π°Π½Π½ΠΎΠΉ ΡΡ‚Π°Ρ‚ΡŒΠ΅ ΠΌΡ‹ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ Ρ€Π°Π·Π±Π΅Ρ€Π΅ΠΌ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ установлСния связи ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ ΠΈ сСрвСром, ΠΏΡ€ΠΎΠΊΠ°Ρ‡ΠΊΠΎΠΉ соСдинСния ΠΊ WebSocket ΠΈ пСрСсылкой сообщСния Π² Spring ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ.

Π’ Ρ€Π°Π·Π±ΠΎΡ€Π΅ Π±ΡƒΠ΄Π΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Spring-WebSocket ΠΈ Annotation based ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡŽ.

Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΎΠ³ΠΎ класса

Π˜Ρ‚Π°ΠΊ, для Π½Π°Ρ‡Π°Π»Π° Π½Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ ΠΎΠ±ΡŠΡΠ²ΠΈΡ‚ΡŒ Ρ‚ΠΎΡ‡ΠΊΡƒ доступа, ΠΊ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠ±Ρ€Π°Ρ‰Π°Ρ‚ΡŒΡΡ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ для создания соСдинСния ΠΈ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ Π΄Π°Π½Π½Ρ‹Ρ….

Для использования WebSocket Π² ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΎΠΌ классС Π½Π°ΠΌ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΡŽ @EnableWebSocket. Из описания Π΄Π°Π½Π½ΠΎΠΉ Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ слСдуСт Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎΡΡ‚ΡŒ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ интСрфСйс WebSocketConfigurer нашим ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹ΠΌ классом. Π˜Π½Ρ‚Π΅Ρ€Ρ„Π΅ΠΉΡ WebSocketConfigurer содСрТит СдинствСнный ΠΌΠ΅Ρ‚ΠΎΠ΄ registerWebSocketHandlers(WebSocketHandlerRegistry registry). Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ Π²Ρ…ΠΎΠ΄Π½ΠΎΠΉ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ WebSocketHandlerRegistry ΠΌΡ‹ осущСствляСм Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠ² (WebSocketHandler) входящих сообщСний Π½Π° ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹ΠΉ url.

Рассмотрим Ρ€Π°Π±ΠΎΡ‚Ρƒ Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ @EnableWebSocket Π±ΠΎΠ»Π΅Π΅ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ.

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(DelegatingWebSocketConfiguration.class)
public @interface EnableWebSocket {
}

Основная Π·Π°Π΄Π°Ρ‡Π° Π΄Π°Π½Π½ΠΎΠΉ Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ β€” ΠΈΠΌΠΏΠΎΡ€Ρ‚ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΎΠ³ΠΎ класса DelegatingWebSocketConfiguration, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ @Autowired ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ экзСмпляры интСрфСйса WebSocketConfigurer (наш ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹ΠΉ класс). Π”Π°Π½Π½Ρ‹Π΅ экзСмпляры WebSocketConfigurer ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ Π² Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΎΠΌ классС WebSocketConfigurationSupport для создания Π±ΠΈΠ½Π° HandlerMapping.

Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Π±ΠΈΠ½Π° HandlerMapping Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π² дальнСйшСм DispatcherServlet смог ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ для Π΄Π°Π½Π½ΠΎΠ³ΠΎ url.


Для прСобразования WebSocketHandler Π² экзСмпляр HandlerMapping Π½Π°ΠΌ ΠΏΠΎΡ‚Ρ€Π΅Π±ΡƒΡŽΡ‚ΡΡ Π°Π΄Π°ΠΏΡ‚Π΅Ρ€Ρ‹ WebSocketHttpRequestHandler ΠΈ WebSocketHandlerMapping.

ΠŸΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ WebSocketHttpRequestHandler ΠΌΡ‹ ΠΏΡ€ΠΎΠΈΠ·Π²Π΅Π΄Π΅ΠΌ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ WebSocketHandler ΠΊ HttpRequestHandler. А Π΄Π°Π»Π΅Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ связку url, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΡ‹ ΠΆΠ΄Π΅ΠΌ запроса ΠΏΠΎ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΈΡŽ WebSocket, ΠΈ HttpRequestHandler создадим экзСмпляр WebSocketHandlerMapping, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΈ Π±ΡƒΠ΄Π΅Ρ‚ зарСгистрирован Π² DispatcherServlet для ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ HTTP запроса.


Когда ΠΊΠ»ΠΈΠ΅Π½Ρ‚ посылаСт запрос Π½Π° ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ WebSocket соСдинСния, запрос Ρ‡Π΅Ρ€Π΅Π· DispatcherServlet ΠΏΡ€ΠΈΡ…ΠΎΠ΄ΠΈΡ‚ Π½Π° ΠΌΠ΅Ρ‚ΠΎΠ΄ handleRequest(HttpServletRequest servletRequest, HttpServletResponse servletResponse) нашСго Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€Π° WebSocketHttpRequestHandler.

Π’ Π΄Π°Π½Π½ΠΎΠΌ ΠΌΠ΅Ρ‚ΠΎΠ΄Π΅ происходит Π²Ρ‹Π·ΠΎΠ² Interceptors, ΠΎΠ±ΡŠΡΠ²Π»Π΅Π½Π½Ρ‹Ρ… Π² ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΎΠΌ классС ΠΏΡ€ΠΈ Π·Π°Π΄Π°Π½ΠΈΠΈ WebSocketHandlers, ΠΈ Π²Ρ‹Π·ΠΎΠ² ΠΌΠ΅Ρ‚ΠΎΠ΄Π° doHandshake, Π΄Π΅Ρ„ΠΎΠ»Ρ‚Π½ΠΎΠ³ΠΎ ΠΈΠ»ΠΈ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΎΠ³ΠΎ экзСмпляра HandshakeHandler.

ΠžΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Handshake запроса

На Ρ€Π°Π±ΠΎΡ‚Π΅ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° doHandshake остановимся Ρ‡ΡƒΡ‚ΡŒ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½Π΅Π΅. Π—Π΄Π΅ΡΡŒ ΠΈ происходит вся магия прСобразования соСдинСния ΠΊ WebSockets. Но для Π½Π°Ρ‡Π°Π»Π° Π΄Π°Π²Π°ΠΉΡ‚Π΅ разбСрСмся с ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°ΠΌΠΈ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΎΠ³ΠΎ запроса ΠΈ сСрвСрного ΠΎΡ‚Π²Π΅Ρ‚Π°.

Π’ΠΈΠΏΠΈΡ‡Π½Ρ‹ΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΎΠ³ΠΎ запроса выглядит ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ:

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: http://example.com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
 Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits

  • Origin β€” содСрТит url, с ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ производится запрос. Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для Π²Π΅Ρ€ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ допустимых адрСсов.
  • Sec-WebSocket-Protocol β€” опрСдСляСт Π½Π°Π±ΠΎΡ€ ΠΏΠΎΠ΄-ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»ΠΎΠ², ΠΊ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρƒ, STOMP, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±ΡƒΠ΄Π΅Ρ‚ рассмотрСн Π² ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΡ… ΡΡ‚Π°Ρ‚ΡŒΡΡ….
  • Sec-WebSocket-Key β€” случайный ΠΊΠ»ΡŽΡ‡, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ гСнСрируСтся Π±Ρ€Π°ΡƒΠ·Π΅Ρ€ΠΎΠΌ: 16 Π±Π°ΠΉΡ‚ Π² ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²ΠΊΠ΅ Base64.
  • Sec-WebSocket-Version β€” вСрсия ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π°.
  • Sec-WebSocket-Extensions β€” Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, permessage-deflate Π³ΠΎΠ²ΠΎΡ€ΠΈΡ‚ ΠΎ Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ сообщСния Π±ΡƒΠ΄ΡƒΡ‚ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ Π² сТатом Π²ΠΈΠ΄Π΅.

Π’ΠΈΠΏΠΈΡ‡Π½Ρ‹ΠΉ ΠΎΡ‚Π²Π΅Ρ‚ ΠΎΡ‚ сСрвСра:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

Код ΠΎΡ‚Π²Π΅Ρ‚Π° HTTP 101 Π³ΠΎΠ²ΠΎΡ€ΠΈΡ‚ ΠΎΠ± ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΈ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π°, Π² нашСм случаС Π½Π° WebSocket.
Sec-WebSocket-Accept β€” рассчитанноС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π½Π° основС ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½ΠΎΠ³ΠΎ Sec-WebSocket-Key ΠΈ константы Β«258EAFA5-E914-47DA-95CA-C5AB0DC85B11Β» β€” ΠΏΠΎ сути это ΠΏΠΎΠ΄Ρ‚Π²Π΅Ρ€ΠΆΠ΄Π΅Π½ΠΈΠ΅ ΠΎΡ‚ сСрвСра ΠΎ готовности ΠΈΠ½ΠΈΡ†ΠΈΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ WebSocket соСдинСниС.

Π Π°Π±ΠΎΡ‚Ρƒ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° doHandshake ΠΌΠΎΠΆΠ½ΠΎ схСматично ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ Π² Ρ‚Π°ΠΊΠΎΠΌ Π²ΠΈΠ΄Π΅:

БтратСгия обновлСния запроса Π΄ΠΎ WebSocket

На Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ доступны стратСгии обновлСния соСдинСния

  • TomcatRequestUpgradeStrategy
  • JettyRequestUpgradeStrategy
  • UndertowRequestUpgradeStrategy
  • GlassFishRequestUpgradeStrategy
  • WebLogicRequestUpgradeStrategy
  • WebSphereRequestUpgradeStrategy

ΠŸΡ€ΠΎΡ†Π΅ΡΡ обновлСния стратСгии состоит ΠΈΠ· ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΡ… шагов:
* ЭкзСмпляр EndPoint создаСтся ΠΏΡƒΡ‚Π΅ΠΌ оборачивания WebSocketHandler Π² StandardWebSocketHandlerAdapter, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΈ являСтся наслСдником EndPoint. Для создания сСссии ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ StandardWebSocketSession.

** Для обновлСния HttpServletRequest ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ стандартный ΠΌΠ΅Ρ‚ΠΎΠ΄ Π΄Π°Π½Π½ΠΎΠ³ΠΎ интСрфСйса update, Π² ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΠ΅Ρ€Π΅Π΄Π°Π΅ΠΌ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ HttpUpgradeHandler,

Π² случаС Ρ€Π°Π±ΠΎΡ‚Ρ‹ с Tomcat это WsHttpUpgradeHandler. ΠŸΡ€ΠΈ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ экзСмпляра HttpUpgradeHandler происходит созданиС ΠΈ рСгистрация EndPonit Π² WebSocketContainer.

ПослС Π΄Π°Π½Π½Ρ‹Ρ… настроСк наша рСализация WebSocketHandler Π³ΠΎΡ‚ΠΎΠ²Π° ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Ρ‚ΡŒ входящиС сообщСния, Π° ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ WebSocketSession ΠΌΡ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ»ΠΈ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΎΡ‚ΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ сообщСния ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ.

Бпасибо большоС Π·Π° Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅. Π’ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΡ… ΡΡ‚Π°Ρ‚ΡŒΡΡ… рассмотрим Ρ€Π°Π±ΠΎΡ‚Ρƒ fallback ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠ° ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ SockJS ΠΈ возмоТности ΠΏΠΎΠ΄-ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π° STOMP.

Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Π½Π½Ρ‹Π΅ источники:

β†’ The WebSocket Protocol

β†’ Spring WebSocket

Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ вСбсокСты Π² своСм iOS ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ / Π₯Π°Π±Ρ€

Π”ΠΎΠ±Ρ€Ρ‹ΠΉ дСнь, ΡƒΠ²Π°ΠΆΠ°Π΅ΠΌΡ‹Π΅ Ρ‡ΠΈΡ‚Π°Ρ‚Π΅Π»ΠΈ Π₯Π°Π±Ρ€Π°Ρ…Π°Π±Ρ€Π°!

БСгодня я Ρ…ΠΎΡ‡Ρƒ Ρ€Π°ΡΡΠΊΠ°Π·Π°Ρ‚ΡŒ Π²Π°ΠΌ ΠΎ Ρ‚ΠΎΠΌ, ΠΊΠ°ΠΊ просто ΠΈ быстро ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ вСбсокСты Π² своС iOS ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ Ρ‡Π°Ρ‚Π° извСстной Π±ΠΈΡ€ΠΆΠΈ ΠΊΡ€ΠΈΠΏΡ‚ΠΎΠ²Π°Π»ΡŽΡ‚. Π Π΅Π°Π»ΠΈΠ·ΡƒΠ΅ΠΌ ΠΌΡ‹ это ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ ΡƒΠ΄ΠΎΠ±Π½ΠΎΠ³ΠΎ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΎΠ³ΠΎ Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ SocketRocket.

Π­Ρ‚ΠΎΡ‚ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΡ€ΠΈΠ³ΠΎΠ΄ΠΈΡ‚ΡŒΡΡ для:

  • Π Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Ρ‡Π°Ρ‚Π° Π² мобильном ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π΅ ΠΏΠΎΠ΄ iOS
  • Использовании ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ Ρ‡Π°Ρ‚Π° для обучСния Π½Π΅ΠΉΡ€ΠΎΠ½Π½Ρ‹Ρ… сСтСй

Π—Π°ΠΈΠ½Ρ‚Π΅Ρ€Π΅ΡΠΎΠ²Π°Π²ΡˆΠΈΡ…ΡΡ ΠΏΡ€ΠΎΡˆΡƒ ΠΏΠΎΠ΄ ΠΊΠ°Ρ‚!

ДобавляСм SocketRocket Π² ΠΏΡ€ΠΎΠ΅ΠΊΡ‚

На Π³ΠΈΡ‚Ρ…Π°Π±Π΅ описано нСсколько Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ΠΎΠ² установки, я ΠΎΠΏΠΈΡˆΡƒ Ρ‚ΠΎΡ‚, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ ΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡΡŒ сам.

  1. ДобавляСм Π² наш ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ всС Ρ„Π°ΠΉΠ»Ρ‹ ΠΈΠ· Π³Ρ€ΡƒΠΏΠΏΡ‹ Β«SocketRocketΒ»
  2. ДобавляСм ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΠΈ Π² ΠΏΡ€ΠΎΠ΅ΠΊΡ‚:
    • libicucore.dylib
    • CFNetwork.framework
    • Security.framework
    • Foundation.framework
  3. ДобавляСм Π² ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ Ρ€Π°ΡΡˆΠΈΡ„Ρ€ΠΎΠ²Ρ‰ΠΈΠΊ HTML символов ΠΎΡ‚ Google (ΠΏΠΎΠ·ΠΆΠ΅ ΠΏΠΎΠΉΠΌΠ΅Ρ‚Π΅, Π·Π°Ρ‡Π΅ΠΌ)

НичСго слоТного! ВсС Π³ΠΎΡ‚ΠΎΠ²ΠΎ для использования всСй ΠΌΠΎΡ‰ΠΈ вСбсокСтов.

Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ сокСты

ΠœΠ΅Ρ‚ΠΎΠ΄Π°ΠΌΠΈ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΎΠ½Π½ΠΎΠ³ΠΎ поиска, Π΄Π΅Π΄ΡƒΠΊΡ†ΠΈΠΈ ΠΈ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΎΡ‚Π·Ρ‹Π²Ρ‡ΠΈΠ²Ρ‹Ρ… Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠ² Π±ΠΈΡ€ΠΆΡ‹, я наткнулся Π½Π° ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΉ источник, ΠΎΡ‚ΠΊΡƒΠ΄Π° Π²Ρ‹Ρ€Π²Π°Π» Π½ΡƒΠΆΠ½Ρ‹ΠΉ URL для сокСтов Ρ‡Π°Ρ‚Π°:

NSURL *url = [NSURL URLWithString:@"wss://ws.pusherapp.com/app/4e0ebd7a8b66fa3554a4?protocol=6&client=js&version=2.0.0&flash=false"];

Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ сам ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ сокСта с Π½ΡƒΠΆΠ½Ρ‹ΠΌ запросом, ΠΎΡ‚ΠΊΡ€Ρ‹Π²Π°Π΅ΠΌ Π΅Π³ΠΎ ΠΈ Π΄Π΅Π»Π°Π΅ΠΌ сСбя Π΄Π΅Π»Π΅Π³Π°Ρ‚ΠΎΠΌ:

NSURLRequest *request = [NSURLRequest requestWithURL:url];
SRWebSocket *rusSocket = [[SRWebSocket alloc] initWithURLRequest:request];
rusSocket.delegate = self;
[rusSocket open];

ΠŸΠΎΠ»Π½Ρ‹ΠΉ ΠΊΠΎΠ΄ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° setupSockets

- (void)setupSockets
{
    NSURL *url = [NSURL URLWithString:@"wss://ws.pusherapp.com/app/4e0ebd7a8b66fa3554a4?protocol=6&client=js&version=2.0.0&flash=false"];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    
    SRWebSocket *rusSocket = [[SRWebSocket alloc] initWithURLRequest:request];
    rusSocket.delegate = self;
    [rusSocket open];
}
ΠœΠ΅Ρ‚ΠΎΠ΄Ρ‹ SRWebSocketDelegate

Π’ ΠΊΠ°ΠΆΠ΄ΠΎΠΌ ΡƒΠ²Π°ΠΆΠ°ΡŽΡ‰Π΅ΠΌ сСбя Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΠ΅ ΠΏΠΎΠ΄ Objective-C ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ Π΄Π΅Π»Π΅Π³Π°Ρ‚Ρ‹ β€” Π° Π² вСбсокСтах ΠΈ ΠΏΠΎΠ΄Π°Π²Π½ΠΎ. ΠœΡ‹ Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠ΅ΠΌ Π΄Π²Π° ΠΌΠ΅Ρ‚ΠΎΠ΄Π° Π΄Π΅Π»Π΅Π³Π°Ρ‚Π° β€” ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ вызываСтся послС установки соСдинСния ΠΈ открытия сокСта, ΠΈ Π²Ρ‚ΠΎΡ€ΠΎΠΉ, Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌΡ‹ΠΉ ΠΏΠΎ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΡŽ сообщСния.

- (void)webSocketDidOpen:(SRWebSocket *)webSocket
{
    NSString *helloMsg = @"{\"event\":\"pusher:subscribe\",\"data\":{\"channel\":\"chat_ru\"}}";
    [webSocket send:helloMsg];
}

Π—Π΄Π΅ΡΡŒ всС ΠΏΡ€Π΅Π΄Π΅Π»ΡŒΠ½ΠΎ просто: ΠΊΠ°ΠΊ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ сокСты ΠΎΡ‚ΠΊΡ€Ρ‹Π²Π°ΡŽΡ‚ΡΡ, ΠΌΡ‹ подписываСмся Π½Π° оповСщСния ΠΈΠ· русского Ρ‡Π°Ρ‚Π°. По Π°Π½Π°Π»ΠΎΠ³ΠΈΠΈ, ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€ΠΎΠΏΠΈΡΠ°Ρ‚ΡŒ ΠΈ Β«chat_enΒ».

Π”Π°Π»ΡŒΡˆΠ΅ ΠΌΡ‹ описываСм ΠΌΠ΅Ρ‚ΠΎΠ΄ получСния сообщСния ΠΎΡ‚ вСбсокСта:

- (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(id)message
{
    message = [[message stringByReplacingOccurrencesOfString:@"///" withString:@""] stringByReplacingOccurrencesOfString:@"\\\\\\" withString:@""];
    message = [message gtm_stringByUnescapingFromHTML];
}

ΠžΠΏΡΡ‚ΡŒ ΠΆΠ΅, всС просто. Π’ ΠΏΠ΅Ρ€Π²ΠΎΠΉ строкС ΠΌΠ΅Ρ‚ΠΎΠ΄Π° ΠΌΡ‹ избавляСмся ΠΎΡ‚ мусора, Π²ΠΎ Π²Ρ‚ΠΎΡ€ΠΎΠΉ ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΡŽ ΠΎΡ‚ Google для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Ρ‚ΡŒ HTML символы Π² Ρ‡ΠΈΡ‚Π°Π΅ΠΌΡ‹Π΅ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΌ. Message ΠΈ Π΅ΡΡ‚ΡŒ нашС сообщСниС β€” дальшС Π΅Π³ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ°Ρ€ΡΠΈΡ‚ΡŒ Ρ‚Π°ΠΊ, ΠΊΠ°ΠΊ Π΄ΡƒΡˆΠ΅ ΡƒΠ³ΠΎΠ΄Π½ΠΎ.ΠŸΡ€ΠΈΠΌΠ΅Ρ€ сообщСния

{Β«eventΒ»:Β«msgΒ»,Β«dataΒ»:»\»{Β«uidΒ»:Β«467754Β»,Β«loginΒ»:Β«BTCalexxxΒ»,Β«msgΒ»:Β«anyone in for a short ltc pump to 15?Β»,Β«msg_idΒ»:12268748,Β«dateΒ»:Β«04.03.14 07:37:50Β»,Β«usr_clrΒ»:»#8da0b9″}\»»,Β«channelΒ»:Β«chat_enΒ»}

Π—Π°ΠΊΡ€Ρ‹Π²Π°Π΅ΠΌ соСдинСниС

ВсСгда Π·Π°ΠΊΡ€Ρ‹Π²Π°ΠΉΡ‚Π΅ соСдинСниС, ΠΊΠΎΠ³Π΄Π° ΠΎΠ½ΠΎ Π²Π°ΠΌ ΡƒΠΆΠ΅ Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ! Π‘Π΄Π΅Π»Π°Ρ‚ΡŒ это ΠΌΠΎΠΆΠ½ΠΎ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠΌ:

[rusSocket close];

Π—Π°ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅

ΠžΠ³Ρ€ΠΎΠΌΠ½ΠΎΠ΅ спасибо, Ρ‡Ρ‚ΠΎ Π΄ΠΎΡ‡ΠΈΡ‚Π°Π»ΠΈ Π΄ΠΎ ΠΊΠΎΠ½Ρ†Π°! Π’ΠΎΡ‚ Ρ‚Π°ΠΊΠΈΠΌ Π½Π΅Ρ…ΠΈΡ‚Ρ€Ρ‹ΠΌ ΠΌΠ΅Ρ‚Π΄ΠΎΠΌ Ρƒ нас Π½Π° Π»Π°Π΄ΠΎΠ½ΠΈ Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ Π΅ΡΡ‚ΡŒ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΈΠΌΠ΅Ρ‚ΡŒ Π°ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½ΡƒΡŽ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎ Ρ‡Π°Ρ‚Π΅ с ΠΎΠ΄Π½ΠΎΠΉ ΠΈΠ· Π±ΠΈΡ€ΠΆ ΠΊΡ€ΠΈΠΏΡ‚ΠΎΠ²Π°Π»ΡŽΡ‚.

Π’ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ ΡΡ‚Π°Ρ‚ΡŒΠ΅ ΠΌΠΎΠ³Ρƒ ΠΎΠΏΠΈΡΠ°Ρ‚ΡŒ, ΠΊΠ°ΠΊ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ свой WhatsApp ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹Ρ… инструмСнтов Π·Π° 4-5 часов Ρ€Π°Π±ΠΎΡ‚Ρ‹. ΠšΠΎΠ½Π΅Ρ‡Π½ΠΎ, Ссли Π²Π°ΠΌ, Π΄ΠΎΡ€ΠΎΠ³ΠΈΠ΅ Ρ‡ΠΈΡ‚Π°Ρ‚Π΅Π»ΠΈ, Π±ΡƒΠ΄Π΅Ρ‚ интСрСсно.

Nginx ΠΈ Websockets / Π₯Π°Π±Ρ€

Π’ Nginx Π½Π°ΠΊΠΎΠ½Π΅Ρ† Π΄ΠΎΠ±Π°Π²ΠΈΠ»ΠΈ Π΄ΠΎΠ»Π³ΠΎΠΆΠ΄Π°Π½Π½ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ ΠΏΠΎ ΠΏΡ€ΠΎΠΊΡΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡŽ Websockets.
Π’ связи с этим ΡΠΏΠ΅ΡˆΡƒ ΠΏΠΎΠ΄Π΅Π»ΠΈΡ‚ΡŒΡΡ ΠΊΠΎΠ½Ρ„ΠΈΠ³Π°ΠΌΠΈ ΠΈ нСбольшими подробностями.

Для Ρ‚Π΅Ρ… ΠΊΡ‚ΠΎ Π½Π΅ Π·Π½Π°Π», Ρ€Π°Π½Π΅Π΅ проксированиС Π±Ρ‹Π»ΠΎ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ Ρ‡Π΅Ρ€Π΅Π· сторонний ΠΌΠΎΠ΄ΡƒΠ»ΡŒ, с ограничСниями ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠ½ΠΎΠ³ΠΈΡ… Π½Π΅ устраивали. Ну, Π΄Π° ΠΌΡ‹ Π½Π΅ ΠΎΠ± этом.

Π’Π΅ΠΏΠ΅Ρ€ΡŒ Π½Π° ΠΎΠ΄Π½ΠΎΠΌ ΠΏΠΎΡ€Ρ‚Ρƒ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€ΠΎΠΊΡΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ http ΠΈ ws Ρ‚Ρ€Π°Ρ„Ρ„ΠΈΠΊ, Π±ΠΎΠ»Π΅Π΅ Ρ‚ΠΎΠ³ΠΎ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΏΠΎΠ΄ ΠΎΠ΄Π½ΠΈΠΌ SSL сСртификатом, ΠΈ всС это с Ρ€ΠΎΠ΄Π½Ρ‹ΠΌ Π·Π½Π°ΠΊΠΎΠΌΡ‹ΠΌ синтаксисом.

Ws доступны начиная с вСрсии 1.3.13, Π° Π±ΡƒΠΊΠ²Π°Π»ΡŒΠ½ΠΎ сСгодня Π΄ΠΎΠ±Π°Π²ΠΈΠ»ΠΈ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΡƒ Π΅Ρ‰Π΅ Π² ΠΌΠΎΠ΄ΡƒΠ»ΠΈ ngx_http_uwsgi_module ΠΈ ngx_http_scgi_module для 1.3.14

Π’ΠΎΡ‚, Ρ‡Ρ‚ΠΎ Π³ΠΎΠ²ΠΎΡ€ΠΈΡ‚ докумСнтация Π½Π° счСт ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΠΎΠ³ΠΎ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠ°.

Для прСвращСния соСдинСния ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ ΠΈ сСрвСром ΠΈΠ· HTTP/1.1 Π² WebSocket ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ доступный Π² HTTP/1.1 ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ смСны ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π°.

Но Π΅ΡΡ‚ΡŒ ΡΠ»ΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ: ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ β€œUpgrade” являСтся hop-by-hop Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΎΠΌ, Ρ‚ΠΎ ΠΎΠ½ Π½Π΅ пСрСдаётся ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° ΠΊ проксируСмому сСрвСру. ΠŸΡ€ΠΈ прямом проксировании ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρ‹ ΠΌΠΎΠ³ΡƒΡ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄ CONNECT, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ±ΠΎΠΉΡ‚ΠΈ эту ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡƒ. Однако ΠΏΡ€ΠΈ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠΌ проксировании Ρ‚Π°ΠΊΠΎΠΉ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ Π½Π΅ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π½ΠΈΡ‡Π΅Π³ΠΎ ΠΎ ΠΏΡ€ΠΎΠΊΡΠΈΡ€ΡƒΡŽΡ‰Π΅ΠΌ сСрвСрС Π½Π΅ Π·Π½Π°Π΅Ρ‚, ΠΈ трСбуСтся ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Π°Ρ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π½Π° ΠΏΡ€ΠΎΠΊΡΠΈΡ€ΡƒΡŽΡ‰Π΅ΠΌ сСрвСрС.

Начиная с вСрсии 1.3.13, Π² nginx прСдусмотрСн особый Ρ€Π΅ΠΆΠΈΠΌ Ρ€Π°Π±ΠΎΡ‚Ρ‹, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ позволяСт ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ Ρ‚ΡƒΠ½Π½Π΅Π»ΡŒ ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ ΠΈ проксируСмым сСрвСром, Ссли проксируСмый сСрвСр Π²Π΅Ρ€Π½ΡƒΠ» ΠΎΡ‚Π²Π΅Ρ‚ с ΠΊΠΎΠ΄ΠΎΠΌ 101 (Switching Protocols), ΠΈ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ попросил ΡΠΌΠ΅Π½ΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° β€œUpgrade” Π² запросС.

Как ΡƒΠΆΠ΅ ΠΎΡ‚ΠΌΠ΅Ρ‡Π°Π»ΠΎΡΡŒ Π²Ρ‹ΡˆΠ΅, hop-by-hop Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ, Π²ΠΊΠ»ΡŽΡ‡Π°Ρ β€œUpgrade” ΠΈ β€œConnection”, Π½Π΅ ΠΏΠ΅Ρ€Π΅Π΄Π°ΡŽΡ‚ΡΡ ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° ΠΊ проксируСмому сСрвСру, поэтому, для Ρ‚ΠΎΠ³ΠΎ Ρ‡Ρ‚ΠΎΠ±Ρ‹ проксируСмый сСрвСр ΡƒΠ·Π½Π°Π» ΠΎ Π½Π°ΠΌΠ΅Ρ€Π΅Π½ΠΈΠΈ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° ΡΠΌΠ΅Π½ΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» Π½Π° WebSocket, эти Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ слСдуСт ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ явно:

ΠšΠΎΠ½Ρ„ΠΈΠ³.

ΠŸΡ€ΠΎΡΡ‚ΠΎΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€:

location /ws/ {
    proxy_pass http://localhost:8080;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";

}

Π‘ΠΎΠ»Π΅Π΅ слоТный ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ поля β€œConnection” Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ΅ запроса ΠΊ проксируСмому сСрвСру зависит ΠΎΡ‚ наличия поля β€œUpgrade” Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ΅ запроса ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°:

http {
    map $http_upgrade $connection_upgrade {
        default upgrade;
        ''      close;
    }

    server {
        ...

        location /ws/ {
            proxy_pass http://localhost:8080;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection $connection_upgrade;
        }
    }

И Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ Π½Π΅ΠΎΡ‡Π΅Π²ΠΈΠ΄Π½Ρ‹ΠΉ, Π½ΠΎ Π²Π°ΠΆΠ½Ρ‹ΠΉ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ это proxy_read_timeout, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ стоит ΠΏΠΎ Π΄Π΅Ρ„ΠΎΠ»Ρ‚Ρƒ Π² Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΈ 60s, ΠΏΠΎ истСчСнии ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ΠΊΠΎΠ½Π½Π΅ΠΊΡ‚ обрываСтся, Ρ‡Π΅Π³ΠΎ Π² случаС ws ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ совсСм Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ.

ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ, ΠΌΡ‹ Π΄ΠΎΠ±Π°Π²ΠΈΠ»ΠΈ:

http {
      ...
      proxy_read_timeout 950s;
      ...
}

Π‘ΠΊΠΎΡ€Π΅Π΅ всСго Π²Π°ΡˆΠ΅ΠΌΡƒ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡŽ Π½ΡƒΠΆΠ½Ρ‹ Π±ΡƒΠ΄ΡƒΡ‚ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ Ρ†ΠΈΡ„Ρ€Ρ‹ Ρ‚Π°ΠΉΠΌΠ°ΡƒΡ‚Π°, поэтому Π½Π΅ копипаститС Π±Π΅Π·Π΄ΡƒΠΌΠ½ΠΎ;)

WebSockets | MDN

WebSocket Chrome
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

4
ΠšΡ€Π°ΠΉ
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

12
Firefox
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

11


Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

11

НСт ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ
7 — 11 Π‘ прСфиксом ЗамСчания
Π‘ прСфиксом Π’Ρ€Π΅Π±ΡƒΠ΅Ρ‚ Π²Π΅Π½Π΄ΠΎΡ€Π½Ρ‹ΠΉ прСфикс: Moz
ЗамСчания Π Π°Π·ΠΌΠ΅Ρ€ сообщСния ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ 16 ΠœΠ‘ (см. ΠžΡˆΠΈΠ±ΠΊΡƒ 711205).

НСт ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ
4 — 6
ЗамСчания Π Π°Π·ΠΌΠ΅Ρ€ сообщСния ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ 16 ΠœΠ‘ (см. ΠžΡˆΠΈΠ±ΠΊΡƒ 711205).
IE
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

10
ΠžΠΏΠ΅Ρ€Π°
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

12.1
Safari
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

5
WebView Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

≀37
Chrome Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

18
Firefox Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

14


Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

14
ЗамСчания Π‘ΠΌ. ΠžΡˆΠΈΠ±ΠΊΡƒ 695635.

НСт ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ
7 — 14 Π‘ прСфиксом ЗамСчания
Π‘ прСфиксом Π’Ρ€Π΅Π±ΡƒΠ΅Ρ‚ Π²Π΅Π½Π΄ΠΎΡ€Π½Ρ‹ΠΉ прСфикс: Moz
ЗамСчания Π Π°Π·ΠΌΠ΅Ρ€ сообщСния ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ 16 ΠœΠ‘ (см. ΠžΡˆΠΈΠ±ΠΊΡƒ 711205).

НСт ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ
4 — 6
ЗамСчания Π Π°Π·ΠΌΠ΅Ρ€ сообщСния ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ 16 ΠœΠ‘ (см. ΠžΡˆΠΈΠ±ΠΊΡƒ 711205).
ΠžΠΏΠ΅Ρ€Π° Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

12.1
Safari iOS
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

4.2
Samsung Π˜Π½Ρ‚Π΅Ρ€Π½Π΅Ρ‚ Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

1.0
WebSocket () конструктор Chrome
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
ΠšΡ€ΠΎΠΌΠΊΠ°
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

≀79
Firefox
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

7


Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

7

НСт ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ
4 — 7
ЗамСчания ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Ρ‹ Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‚ΡΡ.
IE
?
ΠžΠΏΠ΅Ρ€Π°
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Safari
?
WebView Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Chrome Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Firefox Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

7
ΠžΠΏΠ΅Ρ€Π° Android
?
Safari iOS
?
Samsung Π˜Π½Ρ‚Π΅Ρ€Π½Π΅Ρ‚ Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Π΄Π²ΠΎΠΈΡ‡Π½Ρ‹ΠΉ Π’ΠΈΠΏ Π₯Ρ€ΠΎΠΌ
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
ΠšΡ€ΠΎΠΌΠΊΠ°
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

12
Firefox
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
IE
?
ΠžΠΏΠ΅Ρ€Π°
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Safari
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
WebView Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Chrome Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Firefox Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Opera Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Safari iOS
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Samsung Internet Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
с Π±ΡƒΡ„Π΅Ρ€ΠΈΠ·Π°Ρ†ΠΈΠ΅ΠΉ ΠšΠΎΠ»ΠΈΡ‡Π΅ΡΡ‚Π²ΠΎ Π₯Ρ€ΠΎΠΌ
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
ΠšΡ€ΠΎΠΌΠΊΠ°
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

12
Firefox
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
IE
?
ΠžΠΏΠ΅Ρ€Π°
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Safari
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
WebView Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Chrome Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Firefox Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Opera Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Safari iOS
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Samsung Internet Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Π·Π°ΠΊΡ€Ρ‹Ρ‚ΡŒ Π₯Ρ€ΠΎΠΌ
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

4
ΠšΡ€Π°ΠΉ
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

12
Firefox
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

8


Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

8

НСт ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ
4 — 8
ЗамСчания ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‚ΡΡ, см. ΠžΡˆΠΈΠ±ΠΊΡƒ 674716.
IE
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

10
ΠžΠΏΠ΅Ρ€Π°
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

12.1
Safari
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

5
WebView Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

≀37
Chrome Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

18
Firefox Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

8


Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

8

НСт ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ
4 — 8
ЗамСчания ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‚ΡΡ, см. ΠžΡˆΠΈΠ±ΠΊΡƒ 674716.
ΠžΠΏΠ΅Ρ€Π° Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

12.1
Safari iOS
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

4.2
Samsung Π˜Π½Ρ‚Π΅Ρ€Π½Π΅Ρ‚ Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

1.0
Π·Π°ΠΊΡ€Ρ‹Ρ‚ΡŒ событиС Chrome
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
ΠšΡ€ΠΎΠΌΠΊΠ°
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

12
Firefox
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
IE
?
ΠžΠΏΠ΅Ρ€Π°
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Safari
?
WebView Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Chrome Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Firefox Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Opera Android
?
Safari iOS
?
Samsung Π˜Π½Ρ‚Π΅Ρ€Π½Π΅Ρ‚ Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
ошибка событиС Chrome
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
ΠšΡ€ΠΎΠΌΠΊΠ°
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

12
Firefox
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
IE
?
ΠžΠΏΠ΅Ρ€Π°
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Safari
?
WebView Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Chrome Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Firefox Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Opera Android
?
Safari iOS
?
Samsung Π˜Π½Ρ‚Π΅Ρ€Π½Π΅Ρ‚ Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
насадки Π₯Ρ€ΠΎΠΌ
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
ΠšΡ€ΠΎΠΌΠΊΠ°
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

12
Firefox
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

8
IE
?
ΠžΠΏΠ΅Ρ€Π°
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Safari
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
WebView Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Chrome Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Firefox Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

8
ΠžΠΏΠ΅Ρ€Π° Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Safari iOS
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Samsung Internet Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
сообщСниС событиС Chrome
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
ΠšΡ€ΠΎΠΌΠΊΠ°
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

12
Firefox
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
IE
?
ΠžΠΏΠ΅Ρ€Π°
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Safari
?
WebView Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Chrome Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Firefox Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Opera Android
?
Safari iOS
?
Samsung Π˜Π½Ρ‚Π΅Ρ€Π½Π΅Ρ‚ Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Π²ΠΊΠ». Π₯Ρ€ΠΎΠΌ
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
ΠšΡ€ΠΎΠΌΠΊΠ°
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

12
Firefox
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
IE
?
ΠžΠΏΠ΅Ρ€Π°
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Safari
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
WebView Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Chrome Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Firefox Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Opera Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Safari iOS
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Samsung Internet Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
ошибка Chrome
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
ΠšΡ€ΠΎΠΌΠΊΠ°
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

12
Firefox
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
IE
?
ΠžΠΏΠ΅Ρ€Π°
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Safari
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
WebView Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Chrome Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Firefox Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Opera Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Safari iOS
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Samsung Internet Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Π² сообщСнии Π₯Ρ€ΠΎΠΌ
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
ΠšΡ€ΠΎΠΌΠΊΠ°
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

12
Firefox
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
IE
?
ΠžΠΏΠ΅Ρ€Π°
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Safari
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
WebView Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Chrome Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Firefox Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Opera Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Safari iOS
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Samsung Internet Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
onopen Chrome
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
ΠšΡ€ΠΎΠΌΠΊΠ°
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

12
Firefox
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
IE
?
ΠžΠΏΠ΅Ρ€Π°
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Safari
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
WebView Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Chrome Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Firefox Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Opera Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Safari iOS
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Samsung Internet Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΎ событиС Chrome
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
ΠšΡ€ΠΎΠΌΠΊΠ°
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

12
Firefox
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
IE
?
ΠžΠΏΠ΅Ρ€Π°
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Safari
?
WebView Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Chrome Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Firefox Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Opera Android
?
Safari iOS
?
Samsung Π˜Π½Ρ‚Π΅Ρ€Π½Π΅Ρ‚ Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» Π₯Ρ€ΠΎΠΌ
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
ΠšΡ€ΠΎΠΌΠΊΠ°
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

12
Firefox
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
IE
?
ΠžΠΏΠ΅Ρ€Π°
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Safari
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
WebView Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Chrome Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Firefox Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Opera Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Safari iOS
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Samsung Internet Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» согласно RFC 6455 Chrome
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

16
ΠšΡ€Π°ΠΉ
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

12
Firefox
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

11
IE
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

10
ΠžΠΏΠ΅Ρ€Π°
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

15
Safari
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

6
WebView Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Chrome Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

18
Firefox Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

14
ΠžΠΏΠ΅Ρ€Π° Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

14
Safari iOS
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

6
Samsung Π˜Π½Ρ‚Π΅Ρ€Π½Π΅Ρ‚ Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

1.0
Π“ΠΎΡ‚ΠΎΠ²ΠΎ БостояниС Π₯Ρ€ΠΎΠΌ
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

43
ΠšΡ€Π°ΠΉ
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

12
Firefox
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

19
IE
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

10
ΠžΠΏΠ΅Ρ€Π°
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

30
Safari
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

10
WebView Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

43
Chrome Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

43
Firefox Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

19
ΠžΠΏΠ΅Ρ€Π° Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

30
Safari iOS
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

10
Samsung Π˜Π½Ρ‚Π΅Ρ€Π½Π΅Ρ‚ Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

4.0
ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ Π₯Ρ€ΠΎΠΌ
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

4
ΠšΡ€Π°ΠΉ
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

12
Firefox
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

18


Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

18
ЗамСчания Π‘ΠΌ. ΠžΡˆΠΈΠ±ΠΊΡƒ 775368.

НСт ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ
11 — 18
ЗамСчания ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‚ΡΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ Ρ‚ΠΈΠΏΠ° ArrayBuffer ΠΈ String .

НСт ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ
8 — 11
ЗамСчания ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ΡΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ Ρ‚ΠΈΠΏΠ° String .

НСт ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ
4 — 8
ЗамСчания ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ΡΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ Ρ‚ΠΈΠΏΠ° String . Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ логичСскоС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ .
IE
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

10
ΠžΠΏΠ΅Ρ€Π°
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

12.1
Safari
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

5
WebView Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

≀37
Chrome Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

18
Firefox Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

18


Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

18
ЗамСчания Π‘ΠΌ. ΠžΡˆΠΈΠ±ΠΊΡƒ 775368.

НСт ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ
14 — 18
ЗамСчания ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ΡΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ Ρ‚ΠΈΠΏΠ° ArrayBuffer ΠΈ String .

НСт ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ
8 — 14
ЗамСчания ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ΡΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ Ρ‚ΠΈΠΏΠ° String .

НСт ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ
4 — 8
ЗамСчания ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ΡΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ Ρ‚ΠΈΠΏΠ° String .Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ логичСскоС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ .
ΠžΠΏΠ΅Ρ€Π° Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

12.1
Safari iOS
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

4.2
Samsung Π˜Π½Ρ‚Π΅Ρ€Π½Π΅Ρ‚ Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

1.0
url Chrome
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
ΠšΡ€ΠΎΠΌΠΊΠ°
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

12
Firefox
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
IE
?
ΠžΠΏΠ΅Ρ€Π°
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Safari
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
WebView Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Chrome Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Firefox Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Opera Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Safari iOS
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Samsung Internet Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Π’ Π½Π°Π»ΠΈΡ‡ΠΈΠΈ Ρƒ Ρ€Π°Π±ΠΎΡ‡ΠΈΡ… Π₯Ρ€ΠΎΠΌ
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
ΠšΡ€ΠΎΠΌΠΊΠ°
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

≀18
Firefox
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

37
IE
?
Opera
?
Safari
?
WebView Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Chrome Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°
Firefox Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

37
ΠžΠΏΠ΅Ρ€Π° Android
?
Safari iOS
?
Samsung Π˜Π½Ρ‚Π΅Ρ€Π½Π΅Ρ‚ Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°

.

HTML5 | Π’Π΅Π±-сокСты

89

Π’Π΅Π±-ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ — HTML5 — Π’Π΅Π±-сокСты

Π‘Π΅Ρ€Π²Π΅Ρ€Π½Ρ‹Π΅ события, рассмотрСнныС Ρ€Π°Π½Π΅Π΅, ΡΠ²Π»ΡΡŽΡ‚ΡΡ ΠΈΠ΄Π΅Π°Π»ΡŒΠ½Ρ‹ΠΌ инструмСнтом, ΠΊΠΎΠ³Π΄Π° трСбуСтся ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ сообщСний с Π²Π΅Π±-сСрвСра. Но ΠΏΡ€ΠΈ этом связь получаСтся ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ одностороннСй. Π‘Ρ€Π°ΡƒΠ·Π΅Ρ€ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΡ‚Π²Π΅Ρ‡Π°Ρ‚ΡŒ Π½Π° сообщСния ΠΈΠ»ΠΈ Π²ΡΡ‚ΡƒΠΏΠ°Ρ‚ΡŒ Π² Π±ΠΎΠ»Π΅Π΅ слоТный Π΄ΠΈΠ°Π»ΠΎΠ³ с сСрвСром.

Если Π²Ρ‹ создаСтС Π²Π΅Π±-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ трСбуСтся ΡΠ΅Ρ€ΡŒΠ΅Π·Π½ΠΎΠ΅ двустороннСС взаимодСйствиС с Π²Π΅Π±-сСрвСром, Π»ΡƒΡ‡ΡˆΠΈΠΌ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΎΠΌ ΠΊ Π΅Π³ΠΎ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ (Π½Π΅ прибСгая ΠΊ ΠΏΠΎΠΌΠΎΡ‰ΠΈ Flash), Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, с использованиСм ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° XMLHttpRequest.Π’ зависимости ΠΎΡ‚ Ρ‚ΠΈΠΏΠ° создаваСмого прилоТСния этот ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ ΠΌΠΎΠΆΠ΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ Ρ‚Π°ΠΊ, ΠΊΠ°ΠΊ трСбуСтся. Но здСсь сущСствуСт ΠΈ достаточноС количСство ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ.

ΠŸΡ€Π΅ΠΆΠ΄Π΅ всСго, ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ XMLHttpRequest Π½Π΅ ΠΎΡ‡Π΅Π½ΡŒ Ρ…ΠΎΡ€ΠΎΡˆΠΎ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΈΡ‚ для быстрого ΠΎΠ±ΠΌΠ΅Π½Π° мноТСствСнными сообщСниями (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π² Ρ‡Π°Ρ‚Π΅). ΠŸΠΎΡ‚ΠΎΠΌ, Π² Π½Π΅ΠΌ Π½Π΅Ρ‚ возмоТности ΡΠ²ΡΠ·Π°Ρ‚ΡŒ ΠΎΠ΄ΠΈΠ½ Π²Ρ‹Π·ΠΎΠ² с Π΄Ρ€ΡƒΠ³ΠΈΠΌΠΈ, поэтому ΠΏΡ€ΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠΌ Π½ΠΎΠ²ΠΎΠΌ запросС ΠΎΡ‚ Π²Π΅Π±-страницы сСрвСр Π΄ΠΎΠ»ΠΆΠ΅Π½ Π²Ρ‹Ρ‡ΠΈΡΠ»ΡΡ‚ΡŒ с самого Π½Π°Ρ‡Π°Π»Π°, ΠΊΠΎΠΌΡƒ эта страница ΠΏΡ€ΠΈΠ½Π°Π΄Π»Π΅ΠΆΠΈΡ‚. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ слоТности ΠΊΠΎΠ΄Π° для ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ связанных запросов ΠΎΡ‚ Π²Π΅Π±-страницы ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΡ‡Π΅Π½ΡŒ быстро вырасти Π΄ΠΎ практичСски Π½Π΅Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠ΅ΠΌΠΎΠΉ.

Для всСх этих ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ Π΅ΡΡ‚ΡŒ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅, хотя ΠΎΠ½ΠΎ Π΅Ρ‰Π΅ Π½Π΅ Π²ΠΏΠΎΠ»Π½Π΅ Π³ΠΎΡ‚ΠΎΠ²ΠΎ. Π­Ρ‚ΠΈΠΌ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ΠΌ являСтся тСхнология Π²Π΅Π±-сокСтов (Π²Π΅Π±-сокСтов) , которая позволяСт Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Ρƒ ΡƒΠ΄Π΅Ρ€ΠΆΠΈΠ²Π°Ρ‚ΡŒ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΎΠ΅ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΊΠ΅Ρ€Ρƒ ΠΈ ΠΎΠ±ΠΌΠ΅Π½ΠΈΠ²Π°Ρ‚ΡŒΡΡ сообщСниями Π² Ρ‚Π΅Ρ‡Π΅Π½ΠΈΠ΅ любого Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ.

ВСхнология Π²Π΅Π±-сокСтов Π²Ρ‹Π·Π²Π°Π»Π° большоС Π²ΠΎΠ·Π±ΡƒΠΆΠ΄Π΅Π½ΠΈΠ΅ Π² срСдС Π²Π΅Π±-Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠ², Π½ΠΎ ΠΎΠ½Π° Π΅Ρ‰Π΅ находится Π² процСссС развития, хотя ΡƒΠΆΠ΅ ΠΈΠΌΠ΅Π΅Ρ‚ Π½Π΅ΠΏΠ»ΠΎΡ…ΡƒΡŽ Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π½ΡƒΡŽ ΡΠΎΠ²ΠΌΠ΅ΡΡ‚ΠΈΠΌΠΎΡΡ‚ΡŒ:

ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π°ΠΌΠΈ Π²Π΅Π±-сокСтов
Π‘Ρ€Π°ΡƒΠ·Π΅Ρ€ IE Firefox Π₯Ρ€ΠΎΠΌ Safari Opera Safari iOS Android
Минимальная вСрсия 10 6 14 6 12.1 6–

На Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π»ΡƒΡ‡ΡˆΠ΅ всСго Ρ‚Π΅ΡΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ страницы, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ Π²Π΅Π±-сокСты, Π² Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π΅ Chrome, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΡƒΡŽ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΡƒ для Π½ΠΈΡ….

ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ доступа ΠΊ Π²Π΅Π±-сокСтам

Π’Π΅Π±-сокСты ΡΠ²Π»ΡΡŽΡ‚ΡΡ спСциализированным инструмСнтом. Они Π°ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹ для Ρ‚Π°ΠΊΠΈΡ… ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ, ΠΊΠ°ΠΊ Ρ‡Π°Ρ‚, массивныС ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠ΅ ΠΈΠ³Ρ€Ρ‹ ΠΈΠ»ΠΈ инструмСнт для ΠΏΠΈΡ€ΠΈΠ½Π³ΠΎΠ²ΠΎΠ³ΠΎ взаимодСйствия. Π’Π΅Π±-сокСты ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ Π½ΠΎΠ²Ρ‹Π΅ Ρ‚ΠΈΠΏΡ‹ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ, Π½ΠΎ ΠΈΡ… ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π² Π±ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²Π΅ соврСмСнных Π²Π΅Π±-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ, Π΄Π²ΠΈΠΆΠΈΠΌΡ‹Ρ… JavaScript, скорСС всСго, Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ‚ смысла.

РСшСния Π½Π° основС Π²Π΅Π±-сокСтов ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ уТасны. Π Π°Π·Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ JavaScript-ΠΊΠΎΠ΄ для ΠΎΠ΄Π½ΠΎΠΉ страницы Π±ΡƒΠ΄Π΅Ρ‚ достаточно простой Π½Π°Π΄Π΅ΠΆΠ½Ρ‹ΠΌ. Но для создания сСрвСрного прилоТСния Π²Π°ΠΌ ΠΏΠΎΡ‚Ρ€Π΅Π±ΡƒΡŽΡ‚ΡΡ Π±Π΅ΡˆΠ΅Π½Ρ‹Π΅ знания ΠΈ Π½Π°Π²Ρ‹ΠΊΠΈ программирования, Π²ΠΊΠ»ΡŽΡ‡Π°Ρ ΠΏΠΎΠ½ΠΈΠΌΠ°Π½ΠΈΠ΅ ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ‚ΠΎΠ² многопоточности ΠΈ сСтСвого взаимодСйствия.

Для использования вашСго сайта Π΄ΠΎΠ»ΠΆΠ½Π° ΠΈΡΠΏΠΎΠ»Π½ΡΡ‚ΡŒΡΡ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Π°Ρ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°, которая Π±ΡƒΠ΄Π΅Ρ‚, ΠΊΠ°ΠΊ оТидаСтся, Π½Π°Π·Ρ‹Π²Π°Ρ‚ΡŒΡΡ сСрвСром Π²Π΅Π±-сокСтов. На эту ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ возлагаСтся ΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²Π΅Π½Π½ΠΎΡΡ‚ΡŒ Π·Π° ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ взаимодСйствия всСх участников, ΠΈ послС запуска ΠΎΠ½Π° Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ бСзостановочно.

МногиС хостинговыС ΠΊΠΎΠΌΠΏΠ°Π½ΠΈΠΈ Π½Π΅ Π΄ΠΎΠΏΡƒΡΠΊΠ°ΡŽΡ‚ Π΄ΠΎΠ»Π³ΠΎ Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‰ΠΈΡ… ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌ, Ссли Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π²Ρ‹ Π½Π΅ ΠΎΠΏΠ»Π°Ρ‚ΠΈΡ‚Π΅ Π²Ρ‹Π΄Π΅Π»Π΅Π½Π½Ρ‹ΠΉ Π²Π΅Π±-сСрвСр, Ρ‚.Π΅. сСрвСр, ΠΎΠ±ΡΠ»ΡƒΠΆΠΈΠ²Π°ΡŽΡ‰ΠΈΠΉ лишь ваш сайт. Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ ваш ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹ΠΉ ΠΎΠ±Ρ‰ΠΈΠΉ хостинг, Π²Ρ‹, скорСС, всСго, Π½Π΅ Ρ€Π°Π·ΠΌΠ΅Ρ‰Π°ΠΉΡ‚Π΅ Π½Π° Π½Π΅ΠΌ страницы, Π² ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Π²Π΅Π±-сокСты. Π”Π°ΠΆΠ΅ Ссли Π²Ρ‹ ΡƒΠΌΡƒΠ΄Ρ€ΠΈΡ‚Π΅ΡΡŒ Π·Π°ΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ сСрвСр Π²Π΅Π±-сокСтов ΠΈ ΡƒΠ΄Π΅Ρ€ΠΆΠΈΠ²Π°Ρ‚ΡŒ Π΅Π³ΠΎ Π² Ρ€Π°Π±ΠΎΡ‡Π΅ΠΌ состоянии, Π²Π»Π°Π΄Π΅Π»Π΅Ρ† вашСго хостинга, скорСС всСго, выявит ΠΈ Π²Ρ‹ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ Π΅Π³ΠΎ.

Π²Π°ΠΌ Π΄Π°Ρ‚ΡŒ прСдставлСниС ΠΎ прСдставлСнии сСрвСра Π²Π΅Π±-сокСтов, рассмотритС Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΈΠ· Π·Π°Π΄Π°Ρ‡

.

Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΉ

Π’Π°Ρˆ адрСс email Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠΏΡƒΠ±Π»ΠΈΠΊΠΎΠ²Π°Π½. ΠžΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ поля ΠΏΠΎΠΌΠ΅Ρ‡Π΅Π½Ρ‹ *