Π Π°Π·Π½ΠΎΠ΅

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

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

Π’Π²Π΅Π΄Π΅Π½ΠΈΠ΅ Π²Π²Π΅Π±-сокСты

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

Π˜Π½Ρ‚Π΅Ρ€Π½Π΅Ρ‚ Π±Ρ‹Π» построСн Π½Π° прСдставлСнии ΠΎ Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ Π·Π°Π±ΠΎΡ‚Π° браузСра– запрос Π΄Π°Π½Π½Ρ‹Ρ… с сСрвСра, Π° Π·Π°Π±ΠΎΡ‚Π° сСрвСра – обслуТиваниС этих запросов. Π­Ρ‚Π° ΠΏΠ°Ρ€Π°Π΄ΠΈΠ³ΠΌΠ° Π½Π΅ ΠΏΠΎΠ΄Π²Π΅Ρ€Π³Π°Π»Π°ΡΡŒ сомнСнию нСсколько Π»Π΅Ρ‚. Но с появлСниСм AJAX Π² 2005 Π³ΠΎΠ΄Ρƒ ΠΌΠ½ΠΎΠ³ΠΈΠ΅ Π½Π°Ρ‡Π°Π»ΠΈ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ Π½Π°Π΄ созданиСм Π΄Π²ΡƒΠ½Π°ΠΏΡ€Π°Π²Π»Π΅Π½Π½Ρ‹Ρ… соСдинСний.

Π’Π΅Π±-прилоТСния Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π»ΠΈΡΡŒ Π² Ρ€Π°Π·ΠΌΠ΅Ρ€Π΅. Π‘Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‰ΠΈΠΌ Ρ„Π°ΠΊΡ‚ΠΎΡ€ΠΎΠΌ для ΠΈΡ… роста Π±Ρ‹Π»Π° традиционная модСль HTTP. Π§Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€Π΅ΠΎΠ΄ΠΎΠ»Π΅Ρ‚ΡŒ это, Π±Ρ‹Π»ΠΈ созданы нСсколько стратСгий, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‰ΠΈΡ… сСрвСрам Β«ΠΏΡ€ΠΎΡ‚Π°Π»ΠΊΠΈΠ²Π°Ρ‚ΡŒΒ» (push) Π΄Π°Π½Π½Ρ‹Π΅ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ. Одной ΠΈΠ· Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ популярных стала стратСгия Β«Π΄Π»ΠΈΠ½Π½ΠΎΠ³ΠΎ опроса». Она ΠΏΠΎΠ΄Ρ€Π°Π·ΡƒΠΌΠ΅Π²Π°Π΅Ρ‚ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠ°Π½ΠΈΠ΅ HTTP- соСдинСния ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΌ Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€,ΠΏΠΎΠΊΠ° Ρƒ сСрвСра Π΅ΡΡ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ для ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ.

Но всС эти Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈ приводят ΠΊ ΠΏΠ΅Ρ€Π΅Π³Ρ€ΡƒΠ·ΠΊΠ΅ HTTP. ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ€Π°Π·, ΠΊΠΎΠ³Π΄Π° Π²Ρ‹ Π΄Π΅Π»Π°Π΅Ρ‚Π΅ запрос HTTP, Π½Π°Π±ΠΎΡ€ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΎΠ² ΠΈ cookie ΠΏΠ΅Ρ€Π΅Π΄Π°ΡŽΡ‚ΡΡ Π½Π° сСрвСр. Они Π½Π°ΠΊΠ°ΠΏΠ»ΠΈΠ²Π°ΡŽΡ‚ΡΡ Π² большиС массивы ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½ΡƒΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ. Π­Ρ‚ΠΎ ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅Ρ‚ врСмя оТидания, Ρ‡Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΊΡ€ΠΈΡ‚ΠΈΡ‡Π½ΠΎ для Ρ€Π°Π²Π½ΠΎΠΌΠ΅Ρ€Π½ΠΎΠΉ Ρ€Π°Π±ΠΎΡ‚Ρ‹ прилоТСния.

Π§Ρ‚ΠΎΠ±Ρ‹ Ρ€Π΅ΡˆΠΈΡ‚ΡŒ Π΄Π°Π½Π½ΡƒΡŽ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡƒ, Π½ΡƒΠΆΠ΅Π½ Π±Ρ‹Π» способ создания постоянного соСдинСния с ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΌΠΈ Π·Π°Π΄Π΅Ρ€ΠΆΠΊΠ°ΠΌΠΈ, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ΠΌΠΎΠ³Π»ΠΎ Π±Ρ‹ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Ρ‚ΡŒ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ, ΠΈΠ½ΠΈΡ†ΠΈΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Π΅ ΠΊΠ°ΠΊ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ, Ρ‚Π°ΠΊ ΠΈ сСрвСром. Π­Ρ‚ΠΎ ΠΊΠ°ΠΊ Ρ€Π°Π· Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΡŽΡ‚ Π²Π΅Π±-сокСты.

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

Π‘Ρ€Π°ΡƒΠ·Π΅Ρ€ устанавливаСт соСдинСниС ΠΏΠΎ Π²Π΅Π±-сокСту ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ «рукопоТатия». Π­Ρ‚ΠΎΡ‚ процСсс начинаСтся с ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎΠ³ΠΎ запроса HTTP Π½Π° сСрвСр. Π’ этот запрос Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ Upgrade, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ сообщаСт сСрвСру, Ρ‡Ρ‚ΠΎ Π±Ρ€Π°ΡƒΠ·Π΅Ρ€ Ρ…ΠΎΡ‡Π΅Ρ‚ ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ соСдинСниС ΠΏΠΎ Π²Π΅Π±-сокСту.

Π’ΠΎΡ‚ ΡƒΠΏΡ€ΠΎΡ‰Ρ‘Π½Π½Ρ‹ΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΏΠ΅Ρ€Π²ΠΎΠ½Π°Ρ‡Π°Π»ΡŒΠ½Ρ‹Ρ… Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΎΠ² запроса.

GET ws://websocket.example.com/ HTTP/1.1

Origin: http://example.com

Connection: Upgrade

Host: websocket.example.com

Upgrade: websocket

Π—Π°ΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅: URL-адрСса Π²Π΅Π±-сокСтов ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» ws. Π’Π°ΠΊΠΆΠ΅ сущСствуСт ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» wss для бСзопасных соСдинСний, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ являСтся эквивалСнтом HTTPS.

Если сСрвСр ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» WebSocket, ΠΎΠ½ сообщаСт ΠΎΠ± этом с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° Upgrade Π² ΠΎΡ‚Π²Π΅Ρ‚Π΅.

HTTP/1.1 101 WebSocket Protocol Handshake

Date: Wed, 16 Oct 2013 10:07:34 GMT

Connection: Upgrade

Upgrade: WebSocket

ПослС Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ Ρ€ΡƒΠΊΠΎΠΏΠΎΠΆΠ°Ρ‚ΠΈΠ΅ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ, ΠΏΠ΅Ρ€Π²ΠΎΠ½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎΠ΅ соСдинСниС HTTP замСняСтся соСдинСниСм ΠΏΠΎ Π²Π΅Π±-сокСту, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ Ρ‚ΠΎ ΠΆΠ΅ соСдинСниС TCP/IP. На этом этапС любая ΠΈΠ· сторон ΠΌΠΎΠΆΠ΅Ρ‚ Π½Π°Ρ‡Π°Ρ‚ΡŒ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΡƒ Π΄Π°Π½Π½Ρ‹Ρ….

Π‘ ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π²Π΅Π±-сокСтов ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ Π½Π΅ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½Π½Ρ‹ΠΉ объСм ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ Π±Π΅Π· добавлСния Π΄Π°Π½Π½Ρ‹Ρ…, связанных с запросами (ΠΊΠ°ΠΊ Π² HTTP). Π”Π°Π½Π½Ρ‹Π΅ ΠΏΠ΅Ρ€Π΅Π΄Π°ΡŽΡ‚ΡΡ Ρ‡Π΅Ρ€Π΅Π· Π²Π΅Π±-сокСт ΠΊΠ°ΠΊ сообщСния, ΠΊΠ°ΠΆΠ΄ΠΎΠ΅ ΠΈΠ· ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… состоит ΠΈΠ· ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈΠ»ΠΈ большСго количСства Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚ΠΎΠ².

Π§Ρ‚ΠΎΠ±Ρ‹ ΡƒΠ±Π΅Π΄ΠΈΡ‚ΡŒΡΡ, Ρ‡Ρ‚ΠΎ сообщСниС Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΎ Π½Π° сторонС ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°, ΠΊΠ°ΠΆΠ΄ΠΎΠΌΡƒ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚Ρƒ ΠΏΡ€Π΅Π΄ΡˆΠ΅ΡΡ‚Π²ΡƒΡŽΡ‚ ΠΎΡ‚ 4 Π΄ΠΎ 12 Π±Π°ΠΉΡ‚ Π΄Π°Π½Π½Ρ‹Ρ… ΠΎ ΠΏΠΎΠ»Π΅Π·Π½ΠΎΠΉ Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠ΅. ИспользованиС ΠΎΠ±ΠΌΠ΅Π½Π° сообщСниями Π½Π° основС Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚ΠΎΠ² позволяСт ΡΠ½ΠΈΠ·ΠΈΡ‚ΡŒ объСм Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ…, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΡ‚ ΠΊ ΡΠΎΠΊΡ€Π°Ρ‰Π΅Π½ΠΈΡŽ Π·Π°Π΄Π΅Ρ€ΠΆΠ΅ΠΊ.

Π—Π°ΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅: Π‘Ρ‚ΠΎΠΈΡ‚ ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π±ΡƒΠ΄Π΅Ρ‚ ΡƒΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ ΠΎ Π½ΠΎΠ²ΠΎΠΌ сообщСнии Ρ‚ΠΎΠ»ΡŒΠΊΠΎ, ΠΊΠΎΠ³Π΄Π° сСрвСр пСрСдаст всС Π΅Π³ΠΎ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚Ρ‹.

ΠœΡ‹ создадим простоС ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ соСдиняСтся с сСрвСром ΠΏΠΎ Π²Π΅Π±-сокСту. ΠŸΠ΅Ρ€Π΅Π΄ Ρ‚Π΅ΠΌ, ΠΊΠ°ΠΊ ΠΌΡ‹ углубимся Π² Π΄Π΅Ρ‚Π°Π»ΠΈ API, Π½ΡƒΠΆΠ½ΠΎ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ нСсколько Ρ„Π°ΠΉΠ»ΠΎΠ².

ΠŸΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ ΠΏΡ€ΠΈΠΌΠ΅Ρ€

Π—Π°Π³Ρ€ΡƒΠ·ΠΈΡ‚ΡŒ ΠΊΠΎΠ΄

ΠŸΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Π½Π° CodePen

Π‘ΠΎΠ·Π΄Π°ΠΉΡ‚Π΅ Ρ„Π°ΠΉΠ» index.html ΠΈ Π΄ΠΎΠ±Π°Π²ΡŒΡ‚Π΅ Π² Π½Π΅Π³ΠΎ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΡƒΡŽ Ρ€Π°Π·ΠΌΠ΅Ρ‚ΠΊΡƒ.

<!DOCTYPE html>
<html lang="en">
<head>
<metacharset="utf-8">
<title>WebSockets Demo</title>

<link rel="stylesheet" href="style.css">
</head>
<body>
<div>
<h2>WebSockets Demo</h2>

<div>Connecting...</div>

<ul></ul>

<form action="#" method="post">
<textarea placeholder="Write your message here..." required></textarea>
<button type="submit">Send Message</button>
<button type="button">Close Connection</button>
</form>
</div>

<script src="app.js"></script>
</body>
</html>

Π Π°Π·Π½ΠΈΡ†Π° ΠΌΠ΅ΠΆΠ΄Ρƒ Π²Π΅Π±-сокСтами ΠΈ Socket.IO / Π₯Π°Π±Ρ€

Π”ΠΎΠ±Ρ€ΠΎΠ³ΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ суток, Π΄Ρ€ΡƒΠ·ΡŒΡ!

Π’Π΅Π±-сокСты ΠΈ Socket.IO, вСроятно, ΡΠ²Π»ΡΡŽΡ‚ΡΡ двумя Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ распространСнными срСдствами ΠΊΠΎΠΌΠΌΡƒΠ½ΠΈΠΊΠ°Ρ†ΠΈΠΈ Π² Ρ€Π΅ΠΆΠΈΠΌΠ΅ Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ (Π΄Π°Π»Π΅Π΅ β€” ΠΆΠΈΠ²ΠΎΠ΅ ΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅). Но Ρ‡Π΅ΠΌ ΠΎΠ½ΠΈ ΠΎΡ‚Π»ΠΈΡ‡Π°ΡŽΡ‚ΡΡ?

ΠŸΡ€ΠΈ построСнии прилоТСния для ΠΆΠΈΠ²ΠΎΠ³ΠΎ общСния наступаСт ΠΌΠΎΠΌΠ΅Π½Ρ‚, ΠΊΠΎΠ³Π΄Π° Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π²Ρ‹Π±Ρ€Π°Ρ‚ΡŒ срСдство для ΠΎΠ±ΠΌΠ΅Π½Π° Π΄Π°Π½Π½Ρ‹ΠΌΠΈ ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ ΠΈ сСрвСром. Π’Π΅Π±-сокСты ΠΈ Socket.IO ΡΠ²Π»ΡΡŽΡ‚ΡΡ самыми популярными срСдствами ΠΆΠΈΠ²ΠΎΠ³ΠΎ общСния Π² соврСмСнном Π²Π΅Π±Π΅. КакоС ΠΈΠ· Π½ΠΈΡ… Π²Ρ‹Π±Ρ€Π°Ρ‚ΡŒ? Π’ Ρ‡Π΅ΠΌ Ρ€Π°Π·Π½ΠΈΡ†Π° ΠΌΠ΅ΠΆΠ΄Ρƒ этими тСхнологиями? Π”Π°Π²Π°ΠΉΡ‚Π΅ выясним.

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

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

НапримСр, ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²ΡŒΡ‚Π΅, Ρ‡Ρ‚ΠΎ Π²Ρ‹ создаСтС Ρ‡Π°Ρ‚: Π²Π°ΠΌ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΠΎΠ»ΡƒΡ‡Π°Ρ‚ΡŒ ΠΈ ΠΎΡ‚ΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ ΠΊΠ°ΠΊ ΠΌΠΎΠΆΠ½ΠΎ быстрСС, Π²Π΅Ρ€Π½ΠΎ? Π‘ этим прСкрасно ΡΠΏΡ€Π°Π²Π»ΡΡŽΡ‚ΡΡ Π²Π΅Π±-сокСты! Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΡŒ TCP-соСдинСниС ΠΈ Π΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ Π΅Π³ΠΎ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΌ сколько потрСбуСтся.

Π’Π΅Π±-сокСты появились Π² 2010 Π³ΠΎΠ΄Ρƒ Π² Google Chrome 4, ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ RFC (6455) ΠΎΠΏΡƒΠ±Π»ΠΈΠΊΠΎΠ²Π°Π½ Π² 2011.

Π’Π΅Π±-сокСты ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ Π² ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΡ… случаях:

  • Π§Π°Ρ‚Ρ‹
  • ΠœΠ½ΠΎΠ³ΠΎΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠ΅ ΠΈΠ³Ρ€Ρ‹
  • БовмСстноС Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅
  • Π‘ΠΎΡ†ΠΈΠ°Π»ΡŒΠ½Ρ‹Π΅ (новостныС) Π»Π΅Π½Ρ‚Ρ‹
  • ΠŸΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ, Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‰ΠΈΠ΅ Π½Π° основС мСстополоТСния

ΠΈ Ρ‚.Π΄.

Socket.IO

Socket.IO β€” Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° JavaScript, основанная (написанная ΠΏΠΎΠ²Π΅Ρ€Ρ…) Π½Π° Π²Π΅Π±-сокСтах… ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΡ… тСхнологиях. Она ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ Π²Π΅Π±-сокСты, ΠΊΠΎΠ³Π΄Π° ΠΎΠ½ΠΈ доступны, ΠΈΠ»ΠΈ Ρ‚Π°ΠΊΠΈΠ΅ Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈ, ΠΊΠ°ΠΊ Flash Socket, AJAX Long Polling, AJAX Multipart Stream, ΠΊΠΎΠ³Π΄Π° Π²Π΅Π±-сокСты нСдоступны. Π›Π΅Π³ΠΊΠΎΠΉ Π°Π½Π°Π»ΠΎΠ³ΠΈΠ΅ΠΉ ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠ»ΡƒΠΆΠΈΡ‚ΡŒ сравнСниС Fetch API ΠΈ Axios.

Π Π°Π·Π½ΠΈΡ†Π° ΠΌΠ΅ΠΆΠ΄Ρƒ Π²Π΅Π±-сокСтами ΠΈ Socket.IO

Π“Π»Π°Π²Π½Ρ‹ΠΌΠΈ прСимущСствами Socket.IO являСтся ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π΅:

  • Π’ ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ Π²Π΅Π±-сокСтов, Socket.IO позволяСт ΠΎΡ‚ΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ сообщСния всСм ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½Π½Ρ‹ΠΌ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°ΠΌ. НапримСр, Π²Ρ‹ ΠΏΠΈΡˆΠ΅Ρ‚Π΅ Ρ‡Π°Ρ‚ ΠΈ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ ΡƒΠ²Π΅Π΄ΠΎΠΌΠ»ΡΡ‚ΡŒ всСх ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ ΠΎ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΈ Π½ΠΎΠ²ΠΎΠ³ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ. Π’Ρ‹ Π»Π΅Π³ΠΊΠΎ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ это Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΎΠ΄Π½ΠΎΠΉ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ. ΠŸΡ€ΠΈ использовании Π²Π΅Π±-сокСтов, для Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎΠΉ Π·Π°Π΄Π°Ρ‡ΠΈ Π²Π°ΠΌ потрСбуСтся список ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½Π½Ρ‹Ρ… ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ² ΠΈ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠ° сообщСний ΠΏΠΎ ΠΎΠ΄Π½ΠΎΠΌΡƒ.
  • Π’ Π²Π΅Π±-сокСтах слоТно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ проксированиС ΠΈ балансировщики Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ. Socket.IO ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ эти Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈ ΠΈΠ· ΠΊΠΎΡ€ΠΎΠ±ΠΊΠΈ.
  • Как ΠΎΡ‚ΠΌΠ΅Ρ‡Π°Π»ΠΎΡΡŒ Ρ€Π°Π½Π΅Π΅, Socket.IO ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ ΠΏΠΎΡΡ‚Π΅ΠΏΠ΅Π½Π½ΡƒΡŽ (ΠΈΠ·ΡΡ‰Π½ΡƒΡŽ) Π΄Π΅Π³Ρ€Π°Π΄Π°Ρ†ΠΈΡŽ.
  • Socket.IO ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ автоматичСскоС ΠΏΠ΅Ρ€Π΅ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΏΡ€ΠΈ Ρ€Π°Π·Ρ€Ρ‹Π²Π΅ соСдинСния.
  • Π‘ Socket.IO Π»Π΅Π³Ρ‡Π΅ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ.

ΠœΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠΊΠ°Π·Π°Ρ‚ΡŒΡΡ, Ρ‡Ρ‚ΠΎ Socket.IO β€” Π»ΡƒΡ‡ΡˆΠ΅Π΅ срСдство для ΠΆΠΈΠ²ΠΎΠ³ΠΎ общСния. Однако сущСствуСт нСсколько ситуаций, ΠΊΠΎΠ³Π΄Π° Π»ΡƒΡ‡ΡˆΠ΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π²Π΅Π±-сокСты.

Π’ΠΎ-ΠΏΠ΅Ρ€Π²Ρ‹Ρ…, Π²Π΅Π±-сокСты ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‚ΡΡ всСми соврСмСнными Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π°ΠΌΠΈ. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ Π²Ρ‹ Ρ€Π΅Π΄ΠΊΠΎ Π½ΡƒΠΆΠ΄Π°Π΅Ρ‚Π΅ΡΡŒ Π² ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ΅ Π΄Ρ€ΡƒΠ³ΠΈΡ… Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠΉ, прСдоставляСмой Socket.IO.

Если Π³ΠΎΠ²ΠΎΡ€ΠΈΡ‚ΡŒ ΠΎ сСтСвом Ρ‚Ρ€Π°Ρ„ΠΈΠΊΠ΅, Ρ‚ΠΎ Π²Π΅Π±-сокСты ΠΎΡ‚ΠΏΡ€Π°Π²Π»ΡΡŽΡ‚ всСго Π΄Π²Π° запроса:

  • GET для получСния HTML страницы
  • UPGRADE для соСдинСния с Π²Π΅Π±-сокСтами

Π­Ρ‚ΠΎ позволяСт ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ соСдинСниС с сСрвСром. А Ρ‡Ρ‚ΠΎ насчСт Socket.IO?

  • GET для получСния HTML страницы
  • ΠšΠ»ΠΈΠ΅Π½Ρ‚ΡΠΊΠ°Ρ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° Socket.IO (207ΠΊΠ±)
  • Π’Ρ€ΠΈ long polling (Π΄Π»ΠΈΠ½Π½Ρ‹Π΅ опросы) Ajax-запроса
  • UPGRADE для соСдинСния с Π²Π΅Π±-сокСтами

Π’ ΠΌΠΈΡ€Π΅ JS 207ΠΊΠ± β€” это ΠΌΠ½ΠΎΠ³ΠΎ. КакоС Π½Π΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΠ΅ использованиС сСтСвого Ρ‚Ρ€Π°Ρ„ΠΈΠΊΠ°!

Π’ npm сущСствуСт ΠΏΠ°ΠΊΠ΅Ρ‚ Β«websocket-vs-socket.ioΒ», ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ позволяСт ΡΡ€Π°Π²Π½ΠΈΡ‚ΡŒ сСтСвой Ρ‚Ρ€Π°Ρ„ΠΈΠΊ этих Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠΉ:

Π‘Π΅Ρ‚Π΅Π²ΠΎΠΉ Ρ‚Ρ€Π°Ρ„ΠΈΠΊ Π²Π΅Π±-сокСтов:

Π‘Π΅Ρ‚Π΅Π²ΠΎΠΉ Ρ‚Ρ€Π°Ρ„ΠΈΠΊ Socket.IO:

Π Π°Π·Π½ΠΈΡ†Π° ΠΎΡ‡Π΅Π²ΠΈΠ΄Π½Π°!

ПишСм код

ΠŸΡ€ΠΎΡΡ‚ΠΎΠΉ сСрвСр Π½Π° Π²Π΅Π±-сокСтах


Π’ нашСй ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ Π½Π° Node.js ΠΌΡ‹ создадим сСрвСр, Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‰ΠΈΠΉ Π½Π° ΠΏΠΎΡ€Ρ‚Ρƒ 3001. ΠŸΡ€ΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠΌ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΈ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° ΠΌΡ‹ Π±ΡƒΠ΄Π΅ΠΌ ΠΏΡ€ΠΈΡΠ²Π°ΠΈΠ²Π°Ρ‚ΡŒ Π΅ΠΌΡƒ ΡƒΠ½ΠΈΠΊΠ°Π»ΡŒΠ½Ρ‹ΠΉ ID. ΠŸΡ€ΠΈ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠ΅ сообщСния ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ ΠΌΡ‹ Π±ΡƒΠ΄Π΅ΠΌ ΡƒΠ²Π΅Π΄ΠΎΠΌΠ»ΡΡ‚ΡŒ Π΅Π³ΠΎ ΠΎΠ± успСхС: []:

const WebSocket = require('ws')
const UUID = require('uuid')
const wss = new WebSocket.Server({ port: 3001 })

wss.on('connection', ws => {
  ws.id = UUID()

  ws.on('message', message => {
    ws.send(`[${ws.id}]: ${message}`)
  })
})

ΠžΡ‚Π»ΠΈΡ‡Π½ΠΎ! Но Ρ‡Ρ‚ΠΎ Ссли ΠΌΡ‹ Ρ…ΠΎΡ‚ΠΈΠΌ Ρ€Π°ΡΡΡ‹Π»Π°Ρ‚ΡŒ сообщСниС ΠΊΠ°ΠΆΠ΄ΠΎΠΌΡƒ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½Π½ΠΎΠΌΡƒ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ? Π’Π΅Π±-сокСты Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‚ рассылку ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ. Π­Ρ‚ΠΎ ΠΌΠΎΠΆΠ½ΠΎ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ:

const WebSocket = require("ws")
const UUID      = require("uuid")
const wss       = new WebSocket.Server({ port: 3001 })

function broadcast(clientId, message) {
  wss.clients.forEach(client => {
    if(client.readyState === WebSocket.OPEN) {
      client.send(`[${clientId}]: ${message}`)
    }
  })
}

wss.on('conection', ws => {
  ws.id = UUID()
  ws.on('message', message => broadcast(ws.id, message))
})

Π›Π΅Π³ΠΊΠΎ ΠΈ просто! Как Π²ΠΈΠ΄ΠΈΡ‚Π΅, WebSocket.Server Ρ…Ρ€Π°Π½ΠΈΡ‚ записи ΠΎ ΠΊΠ°ΠΆΠ΄ΠΎΠΌ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½Π½ΠΎΠΌ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π΅, поэтому ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ ΠΈΡ‚Π΅Ρ€Π°Ρ†ΠΈΡŽ ΠΈ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ сообщСниС ΠΊΠ°ΠΆΠ΄ΠΎΠΌΡƒ. Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΏΡ€ΠΎΡ‚Π΅ΡΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠΎΠ΄ Π½Π° ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€Π΅ (MacOS) ΠΈΠ»ΠΈ Π² Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π΅ (Chrome).

ΠŸΡ€ΠΎΡΡ‚ΠΎΠΉ сСрвСр Π½Π° Socket.IO

Π­Ρ‚ΠΎ Π±Ρ‹Π»ΠΎ Π½Π΅ слоТно. ΠœΠΎΠΆΠ΅Ρ‚ Π»ΠΈ Socket.IO ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ это Π΅Ρ‰Π΅ ΠΏΡ€ΠΎΡ‰Π΅? Как Π½Π°ΠΌ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ Ρ‚Π°ΠΊΠΎΠΉ ΠΆΠ΅ сСрвСр Π½Π° Socket.IO?

const io = require('socket.io')
const server = io.listen(3002)

server.on('connection', socket => {
  socket.on('message', message => {
    socket.emit(`[${socket.id}]: ${message}`)
    socket.broadcast.emit(`[${socket.id}]: ${message}`)
  })
})

Код получился ΠΏΠΎΡ‡Ρ‚ΠΈ Π½Π°ΠΏΠΎΠ»ΠΎΠ²ΠΈΠ½Ρƒ ΠΊΠΎΡ€ΠΎΡ‡Π΅! Как Π²ΠΈΠ΄ΠΈΡ‚Π΅, ΠΌΠ΅Ρ‚ΠΎΠ΄ Β«broadcastΒ» Π½Π΅ отправляСт ΡƒΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠ΅ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚Π΅Π»ΡŽ, поэтому ΠΌΡ‹ Π²Ρ‹Π½ΡƒΠΆΠ΄Π΅Π½Ρ‹ Π΄Π΅Π»Π°Ρ‚ΡŒ это Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ.

БущСствуСт ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°: ΠΊΠΎΠ΄ нСльзя ΠΏΡ€ΠΎΡ‚Π΅ΡΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π½Π° ΠΎΠ±Ρ‹Ρ‡Π½ΠΎΠΌ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π΅ Π²Π΅Π±-сокСтов. Π­Ρ‚ΠΎ связано с Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎ, ΠΊΠ°ΠΊ ΠΎΡ‚ΠΌΠ΅Ρ‡Π°Π»ΠΎΡΡŒ Ρ€Π°Π½Π΅Π΅, Socket.IO ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ Π½Π΅ чистыС Π²Π΅Π±-сокСты, Π° мноТСство Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠΉ для ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ всСх Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Ρ… ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ². Π’Π°ΠΊ ΠΊΠ°ΠΊ ΠΆΠ΅ Π½Π°ΠΌ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ Π΅Π³ΠΎ Ρ€Π°Π±ΠΎΡ‚ΠΎΡΠΏΠΎΡΠΎΠ±Π½ΠΎΡΡ‚ΡŒ?

// head
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/socket.io.slim.js"></script>

// body
<script>
  ioClient = io.connect('http://localhost:3002')
  ioClient.on('connect', socket => {
    ioClient.send('hello world')
    ioClient.on('message', msg => console.log(msg))
  })
</script>

НСобходимо ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹ΠΉ ΠΊΠ»ΠΈΠ΅Π½Ρ‚. Π’ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½ΠΎΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ ΠΌΡ‹ Π·Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ Π΅Π³ΠΎ ΠΈΠ· CDN. Π­Ρ‚ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ позволяСт Π½Π°ΠΌ провСсти быстрыС (грязныС) тСсты Π² Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π΅.

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

На Π·Π°ΠΌΠ΅Ρ‚ΠΊΡƒ

Π“ΠΎΡ€ΠΈΠ·ΠΎΠ½Ρ‚Π°Π»ΡŒΠ½ΠΎΠ΅ ΠΌΠ°ΡΡˆΡ‚Π°Π±ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅. Допустим, ваш Ρ‡Π°Ρ‚ ΠΎΠ±Ρ€Π΅Π» ΠΏΠΎΠΏΡƒΠ»ΡΡ€Π½ΠΎΡΡ‚ΡŒ ΠΈ Π²Π°ΠΌ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π΅Ρ‰Π΅ ΠΎΠ΄ΠΈΠ½ сСрвСр ΠΈ балансировщик Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ для ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ запросов. Ну, Ссли Π²Ρ‹ ΠΎΡ‚ΠΊΡ€Ρ‹Π²Π°Π΅Ρ‚Π΅ соСдинСниС Π½Π° Β«server 1Β», Π·Π°Ρ‚Π΅ΠΌ балансировщик ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ вас Π½Π° Β«server 2Β», Π²Ρ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚Π΅ ΠΎΡˆΠΈΠ±ΠΊΡƒ: Β«Error during WebSocket handshake: Unexpected response code: 400Β». Socket.IO Ρ€Π΅ΡˆΠ°Π΅Ρ‚ эту ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡƒ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ cookie (ΠΈΠ»ΠΈ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚ΠΈΠ·Π°Ρ†ΠΈΠΈ соСдинСний Π½Π° основС исходных адрСсов), Π° Ρƒ Π²Π΅Π±-сокСтов Π½Π΅ сущСствуСт ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎΠ³ΠΎ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠ°.
ΠŸΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ. Как ΠΎΡ‚ΠΌΠ΅Ρ‡Π°Π»ΠΎΡΡŒ Ρ€Π°Π½Π΅Π΅, Socket.IO прСдоставляСт нСсколько абстрактных ΡƒΡ€ΠΎΠ²Π½Π΅ΠΉ Π½Π°Π΄ транспортным ΡƒΡ€ΠΎΠ²Π½Π΅ΠΌ Π²Π΅Π±-сокСтов. Π’Π°ΠΊΠΆΠ΅ здСсь ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΡƒΠΏΠ°ΠΊΠΎΠ²Ρ‹Π²Π°Π½ΠΈΠ΅ Π΄Π°Π½Π½Ρ‹Ρ… Π² Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ JSON, Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΎΡ‚ΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ Π½Π° сСрвСр (ΠΈ Π½Π°ΠΎΠ±ΠΎΡ€ΠΎΡ‚) Π±ΠΈΠ½Π°Ρ€Π½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅ отсутствуСт. Если Π²Π°ΠΌ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌ Ρ‚Π°ΠΊΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π», придСтся Β«ΠΏΠΎΠΊΠΎΠ»Π΄ΠΎΠ²Π°Ρ‚ΡŒΒ» Π½Π°Π΄ ΠΊΠΎΠ΄ΠΎΠΌ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ с Ρ†Π΅Π»ΡŒΡŽ обСспСчСния Π½ΡƒΠΆΠ½ΠΎΠ³ΠΎ повСдСния. Π‘ Π²Π΅Π±-сокСтами Ρ‚Π°ΠΊΠΈΡ… ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ Π½Π΅ Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π΅Ρ‚.

Π’Π°ΠΊ Ρ‡Ρ‚ΠΎ ΠΆΠ΅ Π²Ρ‹Π±Ρ€Π°Ρ‚ΡŒ?

Π Π΅ΡˆΠ°Ρ‚ΡŒ Π²Π°ΠΌ.

Socket.IO ΠΎΠ±Π»Π΅Π³Ρ‡Π°Π΅Ρ‚ Тизнь, Π²Π°ΠΌ Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ Π·Π°Π±ΠΎΡ‚ΠΈΡ‚ΡŒΡΡ ΠΎ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°Ρ…, связанных с балансировкой Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ, Ρ€Π°Π·Ρ€Ρ‹Π²ΠΎΠΌ соСдинСний ΠΈΠ»ΠΈ рассылкой сообщСний… Π½ΠΎ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌ Π»ΠΈ Π²Π°ΠΌ Ρ‚Π°ΠΊΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»? ΠšΠ»ΠΈΠ΅Π½Ρ‚ΡΠΊΠ°Ρ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° Socket.IO вСсит большС, Ρ‡Π΅ΠΌ ΠΏΠ°ΠΊΠ΅Ρ‚Ρ‹ React, Redux ΠΈ React-Redux вмСстС взятыС. Π£Π²Π΅Ρ€Π΅Π½Ρ‹ Π»ΠΈ Π²Ρ‹, Ρ‡Ρ‚ΠΎ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡ΠΈΡ‚ΡŒΡΡ Π²Π΅Π±-сокСтами?

Π•Ρ‰Π΅ ΠΎΠ΄Π½ΠΎΠΉ Π²Π°ΠΆΠ½ΠΎΠΉ Π²Π΅Ρ‰ΡŒΡŽ, ΠΎ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ слСдуСт ΠΏΠΎΠΌΠ½ΠΈΡ‚ΡŒ, являСтся Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΈ использовании Socket.IO Π½Π° сторонС сСрвСра, большая Ρ‡Π°ΡΡ‚ΡŒ ΠΊΠΎΠ΄Π° Π±ΡƒΠ΄Π΅Ρ‚ написана Π½Π° абстракциях, прСдоставляСмых этой Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΎΠΉ. Если Ρƒ вас Π²ΠΎΠ·Π½ΠΈΠΊΠ½Π΅Ρ‚ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎΡΡ‚ΡŒ ΠΏΠ΅Ρ€Π΅ΠΏΠΈΡΠ°Ρ‚ΡŒ Node.js-микросСрвисы Π½Π° Go, Elixir, Java ΠΈΠ»ΠΈ Π΄Ρ€ΡƒΠ³ΠΎΠΉ язык программирования, Π²Π°ΠΌ придСтся ΠΏΠ΅Ρ€Π΅ΠΏΠΈΡΡ‹Π²Π°Ρ‚ΡŒ ΠΏΠΎΡ‡Ρ‚ΠΈ всю Π»ΠΎΠ³ΠΈΠΊΡƒ. НапримСр, для рассылки сообщСний Π² Socket.IO ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΌΠ΅Ρ‚ΠΎΠ΄ Β«broadcastΒ» (ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π² Π²Π΅Π±-сокСтах рСализуСтся Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ), поэтому ΠΏΡ€ΠΈ Ρ€Π΅Ρ„Π°ΠΊΡ‚ΠΎΡ€ΠΈΠ½Π³Π΅ придСтся ΠΏΠΎΠ½ΡΡ‚ΡŒ, ΠΊΠ°ΠΊ этот ΠΌΠ΅Ρ‚ΠΎΠ΄ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚. Π’ этом случаС слСдуСт ΠΏΡ€Π΅Π΄ΠΏΠΎΡ‡Π΅ΡΡ‚ΡŒ Π²Π΅Π±-сокСты, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΈΡ… Π»Π΅Π³Ρ‡Π΅ Π°Π΄Π°ΠΏΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ.

Π‘Π»Π°Π³ΠΎΠ΄Π°Ρ€ΡŽ Π·Π° Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅.

WebSocket — Π’Π΅Π±-Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈ для Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠ²

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

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

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

11


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

11

НСт ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ
7Β β€” 11Π‘ прСфиксом ЗамСчания
Π‘ прСфиксом Π’Ρ€Π΅Π±ΡƒΠ΅Ρ‚ Π²Π΅Π½Π΄ΠΎΡ€Π½Ρ‹ΠΉ прСфикс: Moz
ЗамСчания Message size limited to 16 MB (see bug 711205).

НСт ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ
4Β β€” 6
ЗамСчания Message size limited to 16 MB (see bug 711205).
IE
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

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

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

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

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

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

14


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

14
ЗамСчания See bug 695635.

НСт ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ
7Β β€” 14Π‘ прСфиксом ЗамСчания
Π‘ прСфиксом Π’Ρ€Π΅Π±ΡƒΠ΅Ρ‚ Π²Π΅Π½Π΄ΠΎΡ€Π½Ρ‹ΠΉ прСфикс: Moz
ЗамСчания Message size limited to 16 MB (see bug 711205).

НСт ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ
4Β β€” 6
ЗамСчания Message size limited to 16 MB (see bug 711205).
Opera Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

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

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

1.0
WebSocket() constructorChrome
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

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

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

7


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

7

НСт ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ
4Β β€” 7
ЗамСчания Parameter protocols not supported.
IE
?
Opera
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

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

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

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

7
Opera Android
?
Safari iOS
?
Samsung Internet Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

8


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

8

НСт ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ
4Β β€” 8
ЗамСчания Parameters not supported, see bug 674716.
IE
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

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

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

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

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

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

8


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

8

НСт ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ
4Β β€” 8
ЗамСчания Parameters not supported, see bug 674716.
Opera Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Π”Π°
Supports protocol as specified by RFC 6455Chrome
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

18


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

18
ЗамСчания See bug 775368.

НСт ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ
11Β β€” 18
ЗамСчания Only parameter of type ArrayBuffer and String supported.

НСт ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ
8Β β€” 11
ЗамСчания Only parameter of type String supported.

НСт ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ
4Β β€” 8
ЗамСчания Only parameter of type String supported. Returns boolean.
IE
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

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

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

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

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

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

18


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

18
ЗамСчания See bug 775368.

НСт ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ
14Β β€” 18
ЗамСчания Only parameter of type ArrayBuffer and String supported.

НСт ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ
8Β β€” 14
ЗамСчания Only parameter of type String supported.

НСт ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ
4Β β€” 8
ЗамСчания Only parameter of type String supported. Returns boolean.
Opera Android
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Π”Π°

Web-Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° β€’ PHP ΠΈ MySQL


ΠŸΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» WebSocket ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½ для Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ Ρ€Π°Π·Π½Ρ‹Ρ… Π·Π°Π΄Π°Ρ‡ ΠΈ снятия ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠΉ ΠΎΠ±ΠΌΠ΅Π½Π° Π΄Π°Π½Π½Ρ‹ΠΌΠΈ ΠΌΠ΅ΠΆΠ΄Ρƒ Π±Ρ€Π°ΡƒΠ·Π΅Ρ€ΠΎΠΌ ΠΈ сСрвСром. Он позволяСт ΠΏΠ΅Ρ€Π΅ΡΡ‹Π»Π°Ρ‚ΡŒ Π»ΡŽΠ±Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅, Π½Π° любой Π΄ΠΎΠΌΠ΅Π½, бСзопасно ΠΈ ΠΏΠΎΡ‡Ρ‚ΠΈ Π±Π΅Π· лишнСго сСтСвого Ρ‚Ρ€Π°Ρ„ΠΈΠΊΠ°. Для установлСния соСдинСния WebSocket ΠΊΠ»ΠΈΠ΅Π½Ρ‚ ΠΈ сСрвСр ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ», ΠΏΠΎΡ…ΠΎΠΆΠΈΠΉ Π½Π° HTTP. ΠšΠ»ΠΈΠ΅Π½Ρ‚ Ρ„ΠΎΡ€ΠΌΠΈΡ€ΡƒΠ΅Ρ‚ особый HTTP-запрос, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ сСрвСр ΠΎΡ‚Π²Π΅Ρ‡Π°Π΅Ρ‚ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹ΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ.

ΠŸΡ€ΠΎΡΡ‚ΠΎΠΉ сокСт-сСрвСр


Π’ ΠΏΠ΅Ρ€Π²ΡƒΡŽ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ Π½Π°Π΄ΠΎ Π² Ρ„Π°ΠΉΠ»Π΅ php.ini Ρ€Π°ΡΡΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ строку, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‰ΡƒΡŽ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с сокСтами ΠΈ ΠΏΠ΅Ρ€Π΅Π·Π°ΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ сСрвСр:

extension = php_sockets.dll


Π’ΠΎΡ‚ ΠΊΠ°ΠΊ выглядит ΠΏΡ€ΠΎΡΡ‚Π΅ΠΉΡˆΠΈΠΉ сокСт-сСрвСр:

<?php
function SocketServer($limit = 0) {
    $starttime = time();
    echo 'SERVER START' . PHP_EOL;

    echo 'Socket create...' . PHP_EOL;
    $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

    if (false === $socket) {
        die('Error: ' . socket_strerror(socket_last_error()) . PHP_EOL);
    }

    echo 'Socket bind...' . PHP_EOL;
    $bind = socket_bind($socket, '127.0.0.1', 7777); // привязываСм ΠΊ ip ΠΈ ΠΏΠΎΡ€Ρ‚Ρƒ
    if (false === $bind) {
        die('Error: ' . socket_strerror(socket_last_error()) . PHP_EOL);
    }

    echo 'Set options...' . PHP_EOL;
    // Ρ€Π°Π·Ρ€Π΅ΡˆΠ°Π΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠ΄ΠΈΠ½ ΠΏΠΎΡ€Ρ‚ для Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… соСдинСний
    $option = socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);
    if (false === $option) {
        die('Error: ' . socket_strerror(socket_last_error()) . PHP_EOL);
    }

    echo 'Listening socket...' . PHP_EOL;
    $listen = socket_listen($socket); // ΡΠ»ΡƒΡˆΠ°Π΅ΠΌ сокСт
    if (false === $listen) {
        die('Error: ' . socket_strerror(socket_last_error()) . PHP_EOL);
    }

    while (true) { // бСсконСчный Ρ†ΠΈΠΊΠ» оТидания ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ
        echo 'Waiting for connections...' . PHP_EOL;
        $connect = socket_accept($socket); // зависаСм, ΠΏΠΎΠΊΠ° Π½Π΅ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠΌ ΠΎΡ‚Π²Π΅Ρ‚Π°
        if ($connect !== false) {
            echo 'Client connected...' . PHP_EOL;
            echo 'Send message to client...' . PHP_EOL;
            socket_write($connect, 'Hello, Client!');
        } else {
            echo 'Error: ' . socket_strerror(socket_last_error()) . PHP_EOL;
            usleep(1000);
        }

        // останавливаСм сСрвСр послС $limit сСкунд
        if ($limit && (time() - $starttime > $limit)) {
            echo 'Closing connection...' . PHP_EOL;
            socket_close($socket);
            echo 'SERVER STOP' . PHP_EOL;
            return;
        }
    }
}

error_reporting(E_ALL); // Π²Ρ‹Π²ΠΎΠ΄ΠΈΠΌ всС ошибки ΠΈ прСдупрСТдСния
set_time_limit(0);      // бСсконСчноС врСмя Ρ€Π°Π±ΠΎΡ‚Ρ‹ скрипта
ob_implicit_flush();    // Π²ΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌ Π²Ρ‹Π²ΠΎΠ΄ Π±Π΅Π· Π±ΡƒΡ„Π΅Ρ€ΠΈΠ·Π°Ρ†ΠΈΠΈ

// ЗапускаСм сСрвСр Π² Ρ€Π°Π±ΠΎΡ‚Ρƒ, Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠ΅ Ρ€Π°Π±ΠΎΡ‚Ρ‹ Ρ‡Π΅Ρ€Π΅Π· 60 сСкунд
SocketServer(60);


Запустим Π΅Π³ΠΎ Π² Ρ€Π°Π±ΠΎΡ‚Ρƒ:

> php.exe -f simple.php
SERVER START
Socket create...
Socket bind...
Set option...
Listening socket...
Waiting for connections...



ΠŸΠΎΠΏΡ€ΠΎΠ±ΡƒΠ΅ΠΌ ΠΏΠΎΠΎΠ±Ρ‰Π°Ρ‚ΡŒΡΡ с сСрвСром с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ telnet:

> telnet


ΠŸΠΎΠ»ΡƒΡ‡ΠΈΠ² ΠΏΡ€ΠΈΠ³Π»Π°ΡˆΠ΅Π½ΠΈΠ΅ telnet, Π΄Π°Π΅ΠΌ ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ:

> open 127.0.0.1 7777



И Π²ΠΈΠ΄ΠΈΠΌ сообщСниС ΠΎΡ‚ сСрвСра:



Наш сСрвСр Π² Π΄Ρ€ΡƒΠ³ΠΎΠΌ ΠΎΠΊΠ½Π΅ Ρ‚ΠΎΠΆΠ΅ встрСпСнулся:


WebSocket сСрвСр


ΠŸΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» WebSocket Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Π½Π°Π΄ TCP. Π­Ρ‚ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΈ соСдинСнии Π±Ρ€Π°ΡƒΠ·Π΅Ρ€ отправляСт ΠΏΠΎ HTTP ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹Π΅ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ, ΡΠΏΡ€Π°ΡˆΠΈΠ²Π°Ρ: Β«ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ Π»ΠΈ сСрвСр WebSocket?Β». Если сСрвСр Π² ΠΎΡ‚Π²Π΅Ρ‚Π½Ρ‹Ρ… Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ°Ρ… ΠΎΡ‚Π²Π΅Ρ‡Π°Π΅Ρ‚ Β«Π”Π°, ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΒ», Ρ‚ΠΎ дальшС HTTP прСкращаСтся ΠΈ ΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅ ΠΈΠ΄Ρ‘Ρ‚ Π½Π° ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠΌ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π΅ WebSocket, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΡƒΠΆΠ΅ Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ‚ с HTTP Π½ΠΈΡ‡Π΅Π³ΠΎ ΠΎΠ±Ρ‰Π΅Π³ΠΎ.

GET /chat HTTP/1.1
Host: websocket.server.com
Upgrade: websocket
Connection: Upgrade
Origin: http://www.example.com
Sec-WebSocket-Key: Iv8io/9s+lYFgZWcXczP8Q==
Sec-WebSocket-Version: 13


Π—Π΄Π΅ΡΡŒ GET ΠΈ Host β€” стандартныС HTTP-Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ, Π° Upgrade ΠΈ Connection ΡƒΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‚, Ρ‡Ρ‚ΠΎ Π±Ρ€Π°ΡƒΠ·Π΅Ρ€ Ρ…ΠΎΡ‡Π΅Ρ‚ ΠΏΠ΅Ρ€Π΅ΠΉΡ‚ΠΈ Π½Π° WebSocket.


Π‘Π΅Ρ€Π²Π΅Ρ€ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΡ€ΠΎΠ°Π½Π°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ эти Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ ΠΈ Ρ€Π΅ΡˆΠΈΡ‚ΡŒ, Ρ€Π°Π·Ρ€Π΅ΡˆΠ°Π΅Ρ‚ Π»ΠΈ ΠΎΠ½ WebSocket с Π΄Π°Π½Π½ΠΎΠ³ΠΎ Π΄ΠΎΠΌΠ΅Π½Π° Origin. ΠžΡ‚Π²Π΅Ρ‚ сСрвСра, Ссли ΠΎΠ½ ΠΏΠΎΠ½ΠΈΠΌΠ°Π΅Ρ‚ ΠΈ Ρ€Π°Π·Ρ€Π΅ΡˆΠ°Π΅Ρ‚ WebSocket-ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: hsBlbuDTkk24srzEOTBUlZAlC2g=


Для тСстирования Ρ€Π°Π±ΠΎΡ‚Ρ‹ сСрвСра Π½Π°ΠΌ Π½ΡƒΠΆΠ΅Π½ ΠΊΠ»ΠΈΠ΅Π½Ρ‚:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8" />
    <title>ΠŸΡ€ΠΎΡΡ‚ΠΎΠΉ WebSocket ΠΊΠ»ΠΈΠ΅Π½Ρ‚</title>
    <link rel="stylesheet" href="style.css" type="text/css" />
    <script src="socket.js" type="text/javascript"></script>
</head>
<body>
    <div>
        <span>Π‘Π΅Ρ€Π²Π΅Ρ€</span>
        <input type="text" value="" />
    </div>
    <div>
        <input type="button" value="Π£ΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ соСдинСниС" />
        <input type="button" value="Π Π°Π·ΠΎΡ€Π²Π°Ρ‚ΡŒ соСдинСниС" />
    </div>
    <div>
        <span>Π‘ΠΎΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅</span>
        <input type="text" value="" />
        <input type="button" value="ΠžΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ сообщСниС" />
    </div>
    <div>
        <span>Π˜Π½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡ</span>
        <div></div>
    </div>
</body>
</html>
window.addEventListener('DOMContentLoaded', function () {

    var socket;

    // ΠΏΠΎΠΊΠ°Π·Π°Ρ‚ΡŒ сообщСниС Π² #socket-info
    function showMessage(message) {
        var div = document.createElement('div');
        div.appendChild(document.createTextNode(message));
        document.getElementById('socket-info').appendChild(div);
    }

    /*
     * Π£ΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ соСдинСниС с сСрвСром ΠΈ Π½Π°Π·Π½Π°Ρ‡ΠΈΡ‚ΡŒ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ событий
     */
    document.getElementById('connect').onclick = function () {
        // Π½ΠΎΠ²ΠΎΠ΅ соСдинСниС ΠΎΡ‚ΠΊΡ€Ρ‹Π²Π°Π΅ΠΌ, Ссли староС соСдинСниС Π·Π°ΠΊΡ€Ρ‹Ρ‚ΠΎ
        if (socket === undefined || socket.readyState !== 1) {
            socket = new WebSocket(document.getElementById('server').value);
        } else {
            showMessage('Надо Π·Π°ΠΊΡ€Ρ‹Ρ‚ΡŒ ΡƒΠΆΠ΅ ΠΈΠΌΠ΅ΡŽΡ‰Π΅Π΅ΡΡ соСдинСниС');
        }

        /*
         * Ρ‡Π΅Ρ‚Ρ‹Ρ€Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠ³ΠΎ Π²Ρ‹Π·ΠΎΠ²Π°: ΠΎΠ΄Π½Π° ΠΏΡ€ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠΈ Π΄Π°Π½Π½Ρ‹Ρ… ΠΈ Ρ‚Ρ€ΠΈ – ΠΏΡ€ΠΈ измСнСниях Π² состоянии соСдинСния
         */
        socket.onmessage = function (event) { // ΠΏΡ€ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠΈ Π΄Π°Π½Π½Ρ‹Ρ… ΠΎΡ‚ сСрвСра
            showMessage('ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΎ сообщСниС ΠΎΡ‚ сСрвСра: ' + event.data);
        }
        socket.onopen = function () { // ΠΏΡ€ΠΈ установкС соСдинСния с сСрвСром
            showMessage('Π‘ΠΎΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΠ΅ с сСрвСром установлСно');
        }
        socket.onerror = function(error) { // Ссли ΠΏΡ€ΠΎΠΈΠ·ΠΎΡˆΠ»Π° какая-Ρ‚ΠΎ ошибка
            showMessage('ΠŸΡ€ΠΎΠΈΠ·ΠΎΡˆΠ»Π° ошибка: ' + error.message);
        };
        socket.onclose = function(event) { // ΠΏΡ€ΠΈ Π·Π°ΠΊΡ€Ρ‹Ρ‚ΠΈΠΈ соСдинСния с сСрвСром
            showMessage('Π‘ΠΎΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΠ΅ с сСрвСром Π·Π°ΠΊΡ€Ρ‹Ρ‚ΠΎ');
            if (event.wasClean) {
                showMessage('Π‘ΠΎΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΠ΅ Π·Π°ΠΊΡ€Ρ‹Ρ‚ΠΎ чисто');
            } else {
                showMessage('ΠžΠ±Ρ€Ρ‹Π² соСдинСния'); // Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Β«ΡƒΠ±ΠΈΡ‚Β» процСсс сСрвСра
            }
            showMessage('Код: ' + event.code + ', ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π°: ' + event.reason);
        };
    };

    /*
     * ΠžΡ‚ΠΏΡ€Π°Π²ΠΊΠ° сообщСния сСрвСру
     */
    document.getElementById('send-msg').onclick = function () {
        if (socket !== undefined && socket.readyState === 1) {
            var message = document.getElementById('message').value;
            socket.send(message);
            showMessage('ΠžΡ‚ΠΏΡ€Π°Π²Π»Π΅Π½ΠΎ сообщСниС сСрвСру: ' + message);
        } else {
            showMessage('НСвозмоТно ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ сообщСниС, Π½Π΅Ρ‚ соСдинСния');
        }
    };

    /*
     * Π—Π°ΠΊΡ€Ρ‹Ρ‚ΡŒ соСдинСниС с сСрвСром
     */
    document.getElementById('disconnect').onclick = function () {
        if (socket !== undefined && socket.readyState === 1) {
            socket.close();
        } else {
            showMessage('Π‘ΠΎΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΠ΅ с сСрвСром ΡƒΠΆΠ΅ Π±Ρ‹Π»ΠΎ Π·Π°ΠΊΡ€Ρ‹Ρ‚ΠΎ');
        }
    };

});
body > div {
    margin-bottom: 15px;
    overflow: hidden;
}
span {
    display: block;
    margin-bottom: 2px;
}
input {
    padding: 5px;
    box-sizing: border-box;
}
input[type="text"] {
    width: 100%;
}
input[type="button"] {
    width: 25%;
    float: left;
    margin-top: 5px;
    margin-right: 5px;
}
div#socket-info {
    padding: 5px;
    border: 1px solid #ddd;
}


ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΈΠΌ Π΅Π³ΠΎ Π² Ρ€Π°Π±ΠΎΡ‚Π΅. ΠžΡ‚ΠΊΡ€Ρ‹Π²Π°Π΅ΠΌ HTML-страницу Π² Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π΅ ΠΈ заполняСм ΠΏΠ΅Ρ€Π²ΠΎΠ΅ ΠΏΠΎΠ»Π΅ Β«Π‘Π΅Ρ€Π²Π΅Ρ€Β»:

ws://echo.websocket.org


Π­Ρ‚ΠΎ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎ Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‰ΠΈΠΉ WebSocket echo-сСрвСр, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ отправляСт всС сообщСния ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ. Π–ΠΌΠ΅ΠΌ ΠΊΠ½ΠΎΠΏΠΊΡƒ Β«Π£ΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ соСдинСниС», Π½Π°Π±ΠΈΡ€Π°Π΅ΠΌ тСкст сообщСния Π² ΠΏΠΎΠ»Π΅ Β«Π‘ΠΎΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅Β», ΠΆΠΌΠ΅ΠΌ ΠΊΠ½ΠΎΠΏΠΊΡƒ Β«ΠžΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ сообщСниС»:



А Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ ΠΊΠΎΠ΄ WebSocket сСрвСра Π½Π° PHP:

<?php
/**
 * Класс WebSocket сСрвСра
 */
class WebSocketServer {

    /**
     * Ѐункция вызываСтся, ΠΊΠΎΠ³Π΄Π° ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΎ сообщСниС ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°
     */
    public $handler;

    /**
     * IP адрСс сСрвСра
     */
    private $ip;
    /**
     * ΠŸΠΎΡ€Ρ‚ сСрвСра
     */
    private $port;
    /**
     * Π‘ΠΎΠΊΠ΅Ρ‚ для принятия Π½ΠΎΠ²Ρ‹Ρ… соСдинСний, ΠΏΡ€ΠΎΡΠ»ΡƒΡˆΠΈΠ²Π°Π΅Ρ‚ ΡƒΠΊΠ°Π·Π°Π½Π½Ρ‹ΠΉ ΠΏΠΎΡ€Ρ‚
     */
    private $connection;
    /**
     * Для хранСния всСх ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ, принятых ΡΠ»ΡƒΡˆΠ°ΡŽΡ‰ΠΈΠΌ сокСтом
     */
    private $connects;

    /**
     * ΠžΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅ ΠΏΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ Ρ€Π°Π±ΠΎΡ‚Ρ‹ сСрвСра
     */
    private $timeLimit = 0;
    /**
     * ВрСмя Π½Π°Ρ‡Π°Π»Π° Ρ€Π°Π±ΠΎΡ‚Ρ‹ сСрвСра
     */
    private $startTime;
    /**
     * Π’Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ΡŒ сообщСния Π² консоль?
     */
    private $verbose = false;
    /**
     * Π—Π°ΠΏΠΈΡΡ‹Π²Π°Ρ‚ΡŒ сообщСния Π² log-Ρ„Π°ΠΉΠ»?
     */
    private $logging = false;
    /**
     * Имя log-Ρ„Π°ΠΉΠ»Π°
     */
    private $logFile = 'ws-log.txt';
    /**
     * РСсурс log-Ρ„Π°ΠΉΠ»Π°
     */
    private $resource;


    public function __construct($ip = '127.0.0.1', $port = 7777) {
        $this->ip = $ip;
        $this->port = $port;

        // эта функция вызываСтся, ΠΊΠΎΠ³Π΄Π° ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΎ сообщСниС ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°;
        // ΠΏΡ€ΠΈ создании экзСмпляра класса Π΄ΠΎΠ»ΠΆΠ½Π° Π±Ρ‹Ρ‚ΡŒ ΠΏΠ΅Ρ€Π΅ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π°
        $this->handler = function($connection, $data) {
            $message = '[' . date('r') . '] ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΎ сообщСниС ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°: ' . $data . PHP_EOL;
            if ($this->verbose) {
                echo $message;
            }
            if ($this->logging) {
                fwrite($this->resource, $message);
            }
        };
    }

    public function __destruct() {
        if (is_resource($this->connection)) {
            $this->stopServer();
        }
        if ($this->logging) {
            fclose($this->resource);
        }
    }

    /**
     * Π”ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ настройки для ΠΎΡ‚Π»Π°Π΄ΠΊΠΈ
     */
    public function settings($timeLimit = 0, $verbose = false, $logging = false, $logFile = 'ws-log.txt') {
        $this->timeLimit = $timeLimit;
        $this->verbose = $verbose;
        $this->logging = $logging;
        $this->logFile = $logFile;
        if ($this->logging) {
            $this->resource = fopen($this->logFile, 'a');
        }
    }

    /**
     * Π’Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ сообщСниС Π² консоль ΠΈ/ΠΈΠ»ΠΈ записываСт Π² Π»ΠΎΠ³-Ρ„Π°ΠΉΠ»
     */
    private function debug($message) {
        $message = '[' . date('r') . '] ' . $message . PHP_EOL;
        if ($this->verbose) {
            echo $message;
        }
        if ($this->logging) {
            fwrite($this->resource, $message);
        }
    }

    /**
     * ΠžΡ‚ΠΏΡ€Π°Π²Π»ΡΠ΅Ρ‚ сообщСниС ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ
     */
    public static function response($connect, $data) {
        socket_write($connect, self::encode($data));
    }

    /**
     * ЗапускаСт сСрвСр Π² Ρ€Π°Π±ΠΎΡ‚Ρƒ
     */
    public function startServer() {

        $this->debug('Try start server...');

        $this->connection = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

        if (false === $this->connection) {
            $this->debug('Error socket_create(): ' . socket_strerror(socket_last_error()));
            return;
        }

        $bind = socket_bind($this->connection, $this->ip, $this->port); // привязываСм ΠΊ ip ΠΈ ΠΏΠΎΡ€Ρ‚Ρƒ
        if (false === $bind) {
            $this->debug('Error socket_bind(): ' . socket_strerror(socket_last_error()));
            return;
        }

        // Ρ€Π°Π·Ρ€Π΅ΡˆΠ°Π΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠ΄ΠΈΠ½ ΠΏΠΎΡ€Ρ‚ для Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… соСдинСний
        $option = socket_set_option($this->connection, SOL_SOCKET, SO_REUSEADDR, 1);
        if (false === $option) {
            $this->debug('Error socket_set_option(): ' . socket_strerror(socket_last_error()));
            return;
        }

        $listen = socket_listen($this->connection); // ΡΠ»ΡƒΡˆΠ°Π΅ΠΌ сокСт
        if (false === $listen) {
            $this->debug('Error socket_listen(): ' . socket_strerror(socket_last_error()));
            return;
        }

        $this->debug('Server is running...');

        $this->connects = array($this->connection);
        $this->startTime = time();

        while (true) {

            $this->debug('Waiting for connections...');

            // создаСм копию массива, Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ массив $this->connects Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ socket_select()
            $read = $this->connects;
            $write = $except = null;

            /*
             * Π‘ΠΎΠΊΠ΅Ρ‚ $this->connection Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΡ€ΠΎΡΠ»ΡƒΡˆΠΈΠ²Π°Π΅Ρ‚ ΠΏΠΎΡ€Ρ‚ Π½Π° ΠΏΡ€Π΅Π΄ΠΌΠ΅Ρ‚ Π½ΠΎΠ²Ρ‹Ρ… соСдинСний. Как Ρ‚ΠΎΠ»ΡŒΠΊΠΎ поступило
             * Π½ΠΎΠ²ΠΎΠ΅ соСдинСниС, ΠΌΡ‹ создаСм Π½ΠΎΠ²Ρ‹ΠΉ рСсурс сокСта с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ socket_accept() ΠΈ ΠΏΠΎΠΌΠ΅Ρ‰Π°Π΅ΠΌ Π΅Π³ΠΎ Π² массив
             * $this->connects для дальнСйшСго чтСния ΠΈΠ· Π½Π΅Π³ΠΎ.
             */

            if ( ! socket_select($read, $write, $except, null)) { // ΠΎΠΆΠΈΠ΄Π°Π΅ΠΌ сокСты, доступныС для чтСния (Π±Π΅Π· Ρ‚Π°ΠΉΠΌΠ°ΡƒΡ‚Π°)
                break;
            }

            // Ссли ΡΠ»ΡƒΡˆΠ°ΡŽΡ‰ΠΈΠΉ сокСт Π΅ΡΡ‚ΡŒ Π² массивС чтСния, Π·Π½Π°Ρ‡ΠΈΡ‚ Π±Ρ‹Π»ΠΎ Π½ΠΎΠ²ΠΎΠ΅ соСдинСниС
            if (in_array($this->connection, $read)) {
                // ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅ΠΌ Π½ΠΎΠ²ΠΎΠ΅ соСдинСниС ΠΈ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΠΌ Ρ€ΡƒΠΊΠΎΠΏΠΎΠΆΠ°Ρ‚ΠΈΠ΅
                if (($connect = socket_accept($this->connection)) && $this->handshake($connect)) {
                    $this->debug('New connection accepted');
                    $this->connects[] = $connect; // добавляСм Π΅Π³ΠΎ Π² список Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Ρ… для ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ
                }
                // удаляСм ΡΠ»ΡƒΡˆΠ°ΡŽΡ‰ΠΈΠΉ сокСт ΠΈΠ· массива для чтСния
                unset($read[ array_search($this->connection, $read) ]);
            }

            foreach ($read as $connect) { // ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅ΠΌ всС соСдинСния, Π² ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π΅ΡΡ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ для чтСния
                $data = socket_read($connect, 100000);
                $decoded = self::decode($data);
                // Ссли ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π½Π΅ прислал Π΄Π°Π½Π½Ρ‹Ρ… ΠΈΠ»ΠΈ Ρ…ΠΎΡ‡Π΅Ρ‚ Ρ€Π°Π·ΠΎΡ€Π²Π°Ρ‚ΡŒ соСдинСниС
                if (false === $decoded || 'close' === $decoded['type']) {
                    $this->debug('Connection closing');
                    socket_write($connect, self::encode('  Closed on client demand', 'close'));
                    socket_shutdown($connect);
                    socket_close($connect);
                    unset($this->connects[ array_search($connect, $this->connects) ]);
                    $this->debug('Closed successfully');
                    continue;
                }
                // ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΎ сообщСниС ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°, Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΡƒΡŽ
                // Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅
                if (is_callable($this->handler)) {
                    call_user_func($this->handler, $connect, $decoded['payload']);
                }
            }

            // Ссли истСкло ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅ ΠΏΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ, останавливаСм сСрвСр
            if ($this->timeLimit && time() - $this->startTime > $this->timeLimit) {
                $this->debug('Time limit. Stopping server.');
                $this->stopServer();
                return;
            }

        }

    }

    /**
     * ΠžΡΡ‚Π°Π½Π°Π²Π»ΠΈΠ²Π°Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Ρƒ сСрвСра
     */
    public function stopServer() {
        // Π·Π°ΠΊΡ€Ρ‹Π²Π°Π΅ΠΌ ΡΠ»ΡƒΡˆΠ°ΡŽΡ‰ΠΈΠΉ сокСт
        socket_close($this->connection);
        if (!empty($this->connects)) { // отправляСм всС ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°ΠΌ сообщСниС ΠΎ Ρ€Π°Π·Ρ€Ρ‹Π²Π΅ соСдинСния
            foreach ($this->connects as $connect) {
                if (is_resource($connect)) {
                    socket_write($connect, self::encode('  Closed on server demand', 'close'));
                    socket_shutdown($connect);
                    socket_close($connect);
                }
            }
        }
    }

    /**
     * Для кодирования сообщСний ΠΏΠ΅Ρ€Π΅Π΄ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΎΠΉ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ
     */
    private static function encode($payload, $type = 'text', $masked = false) {
        $frameHead = array();
        $payloadLength = strlen($payload);

        switch ($type) {
            case 'text':
                // first byte indicates FIN, Text-Frame (10000001):
                $frameHead[0] = 129;
                break;
            case 'close':
                // first byte indicates FIN, Close Frame(10001000):
                $frameHead[0] = 136;
                break;
            case 'ping':
                // first byte indicates FIN, Ping frame (10001001):
                $frameHead[0] = 137;
                break;
            case 'pong':
                // first byte indicates FIN, Pong frame (10001010):
                $frameHead[0] = 138;
                break;
        }

        // set mask and payload length (using 1, 3 or 9 bytes)
        if ($payloadLength > 65535) {
            $payloadLengthBin = str_split(sprintf('%064b', $payloadLength), 8);
            $frameHead[1] = ($masked === true) ? 255 : 127;
            for ($i = 0; $i < 8; $i++) {
                $frameHead[$i + 2] = bindec($payloadLengthBin[$i]);
            }
            // most significant bit MUST be 0
            if ($frameHead[2] > 127) {
                return array('type' => '', 'payload' => '', 'error' => 'frame too large (1004)');
            }
        } elseif ($payloadLength > 125) {
            $payloadLengthBin = str_split(sprintf('%016b', $payloadLength), 8);
            $frameHead[1] = ($masked === true) ? 254 : 126;
            $frameHead[2] = bindec($payloadLengthBin[0]);
            $frameHead[3] = bindec($payloadLengthBin[1]);
        } else {
            $frameHead[1] = ($masked === true) ? $payloadLength + 128 : $payloadLength;
        }

        // convert frame-head to string:
        foreach (array_keys($frameHead) as $i) {
            $frameHead[$i] = chr($frameHead[$i]);
        }
        if ($masked === true) {
            // generate a random mask:
            $mask = array();
            for ($i = 0; $i < 4; $i++) {
                $mask[$i] = chr(rand(0, 255));
            }
            $frameHead = array_merge($frameHead, $mask);
        }
        $frame = implode('', $frameHead);

        // append payload to frame:
        for ($i = 0; $i < $payloadLength; $i++) {
            $frame .= ($masked === true) ? $payload[$i] ^ $mask[$i % 4] : $payload[$i];
        }

        return $frame;
    }

    /**
     * Для дСкодирования сообщСний, ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹Ρ… ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°
     */
    private static function decode($data) {
        if ( ! strlen($data)) {
            return false;
        }

        $unmaskedPayload = '';
        $decodedData = array();

        // estimate frame type:
        $firstByteBinary = sprintf('%08b', ord($data[0]));
        $secondByteBinary = sprintf('%08b', ord($data[1]));
        $opcode = bindec(substr($firstByteBinary, 4, 4));
        $isMasked = ($secondByteBinary[0] == '1') ? true : false;
        $payloadLength = ord($data[1]) & 127;

        // unmasked frame is received:
        if (!$isMasked) {
            return array('type' => '', 'payload' => '', 'error' => 'protocol error (1002)');
        }

        switch ($opcode) {
            // text frame:
            case 1:
                $decodedData['type'] = 'text';
                break;
            case 2:
                $decodedData['type'] = 'binary';
                break;
            // connection close frame:
            case 8:
                $decodedData['type'] = 'close';
                break;
            // ping frame:
            case 9:
                $decodedData['type'] = 'ping';
                break;
            // pong frame:
            case 10:
                $decodedData['type'] = 'pong';
                break;
            default:
                return array('type' => '', 'payload' => '', 'error' => 'unknown opcode (1003)');
        }

        if ($payloadLength === 126) {
            $mask = substr($data, 4, 4);
            $payloadOffset = 8;
            $dataLength = bindec(sprintf('%08b', ord($data[2])) . sprintf('%08b', ord($data[3]))) + $payloadOffset;
        } elseif ($payloadLength === 127) {
            $mask = substr($data, 10, 4);
            $payloadOffset = 14;
            $tmp = '';
            for ($i = 0; $i < 8; $i++) {
                $tmp .= sprintf('%08b', ord($data[$i + 2]));
            }
            $dataLength = bindec($tmp) + $payloadOffset;
            unset($tmp);
        } else {
            $mask = substr($data, 2, 4);
            $payloadOffset = 6;
            $dataLength = $payloadLength + $payloadOffset;
        }

        /**
         * We have to check for large frames here. socket_recv cuts at 1024 bytes
         * so if websocket-frame is > 1024 bytes we have to wait until whole
         * data is transferd.
         */
        if (strlen($data) < $dataLength) {
            return false;
        }

        if ($isMasked) {
            for ($i = $payloadOffset; $i < $dataLength; $i++) {
                $j = $i - $payloadOffset;
                if (isset($data[$i])) {
                    $unmaskedPayload .= $data[$i] ^ $mask[$j % 4];
                }
            }
            $decodedData['payload'] = $unmaskedPayload;
        } else {
            $payloadOffset = $payloadOffset - 4;
            $decodedData['payload'] = substr($data, $payloadOffset);
        }

        return $decodedData;
    }

    /**
     * Β«Π ΡƒΠΊΠΎΠΏΠΎΠΆΠ°Ρ‚ΠΈΠ΅Β», Ρ‚.Π΅. ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠ° Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΎΠ² согласно ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Ρƒ WebSocket
     */
    private function handshake($connect) {

        $info = array();

        $data = socket_read($connect, 1000);
        $lines = explode("\r\n", $data);
        foreach ($lines as $i => $line) {
            if ($i) {
                if (preg_match('/\A(\S+): (.*)\z/', $line, $matches)) {
                    $info[$matches[1]] = $matches[2];
                }
            } else {
                $header = explode(' ', $line);
                $info['method'] = $header[0];
                $info['uri'] = $header[1];
            }
            if (empty(trim($line))) break;
        }

        // ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ адрСс ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°
        $ip = $port = null;
        if ( ! socket_getpeername($connect, $ip, $port)) {
            return false;
        }
        $info['ip'] = $ip;
        $info['port'] = $port;

        if (empty($info['Sec-WebSocket-Key'])) {
            return false;
        }

        // отправляСм Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ согласно ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Ρƒ вСбсокСта
        $SecWebSocketAccept = 
            base64_encode(pack('H*', sha1($info['Sec-WebSocket-Key'] . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')));
        $upgrade = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" .
                   "Upgrade: websocket\r\n" .
                   "Connection: Upgrade\r\n" .
                   "Sec-WebSocket-Accept:".$SecWebSocketAccept."\r\n\r\n";
        socket_write($connect, $upgrade);

        return true;

    }

}


Для тСстирования напишСм нСбольшой PHP-скрипт, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ запускаСт Π² Ρ€Π°Π±ΠΎΡ‚Ρƒ сСрвСр ΠΈ всС сообщСния ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° отправляСт ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ (echo-сСрвСр):

<?php 
error_reporting(E_ALL);
set_time_limit(0);
ob_implicit_flush();

require 'WebSocketServer.class.php';

$server = new WebSocketServer('127.0.0.1', 7777);
// максимальноС врСмя Ρ€Π°Π±ΠΎΡ‚Ρ‹ 100 сСкунд, Π²Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ΡŒ сообщСния Π² консоль
$server->settings(100, true);

// эта функция вызываСтся, ΠΊΠΎΠ³Π΄Π° ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΎ сообщСниС ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°
$server->handler = function($connect, $data) {
    // ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹Π΅ ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° Π΄Π°Π½Π½Ρ‹Π΅ отправляСм ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ
    WebSocketServer::response($connect, $data);
};

$server->startServer();


ЗапускаСм скрипт Π² Ρ€Π°Π±ΠΎΡ‚Ρƒ:

> php.exe -f echo-server.php
[Fri, 12 Oct 2018 15:08:13 +0300] Try start server...
[Fri, 12 Oct 2018 15:08:13 +0300] Server is running...
[Fri, 12 Oct 2018 15:08:13 +0300] Waiting for connections...



Π•Ρ‰Π΅ ΠΎΠ΄ΠΈΠ½ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ использования сСрвСра β€” ΠΊΠ»ΠΈΠ΅Π½Ρ‚ отправляСт ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹, Π° сСрвСр ΠΈΡ… выполняСт:

<?php 
error_reporting(E_ALL);
set_time_limit(0);
ob_implicit_flush();

require 'WebSocketServer.class.php';

$server = new WebSocketServer('127.0.0.1', 7777);
// максимальноС врСмя Ρ€Π°Π±ΠΎΡ‚Ρ‹ 100 сСкунд, Π²Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ΡŒ сообщСния Π² консоль
$server->settings(100, true);

// эта функция вызываСтся, ΠΊΠΎΠ³Π΄Π° ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΎ сообщСниС ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°
$server->handler = function($connect, $data) {
    // Π°Π½Π°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ ΠΏΠΎΡΡ‚ΡƒΠΏΠΈΠ²ΡˆΡƒΡŽ ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ ΠΈ Π΄Π°Π΅ΠΌ ΠΎΡ‚Π²Π΅Ρ‚
    if ( ! in_array($data, array('date', 'time', 'country', 'city'))) {
        WebSocketServer::response($connect, 'НСизвСстная ΠΊΠΎΠΌΠ°Π½Π΄Π°');
        return;
    }
    switch ($data) {
        case 'date'   : $response = date('d.m.Y'); break;
        case 'time'   : $response = date('H:i:s'); break;
        case 'country': $response = 'Россия';      break;
        case 'city'   : $response = 'Москва';      break;
    }
    WebSocketServer::response($connect, $response);
};

$server->startServer();


ΠΠ»ΡŒΡ‚Π΅Ρ€Π½Π°Ρ‚ΠΈΠ²Π½Π°Ρ рСализация WebSocket сСрвСра с использованиСм Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌΠΈ:

<?php
/**
 * Класс WebSocket сСрвСра
 */
class WebSocketServer {

    /**
     * Ѐункция вызываСтся, ΠΊΠΎΠ³Π΄Π° ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΎ сообщСниС ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°
     */
    public $handler;

    /**
     * IP адрСс сСрвСра
     */
    private $ip;
    /**
     * ΠŸΠΎΡ€Ρ‚ сСрвСра
     */
    private $port;
    /**
     * Для хранСния ΡΠ»ΡƒΡˆΠ°ΡŽΡ‰Π΅Π³ΠΎ сокСта ΠΏΠΎΡ‚ΠΎΠΊΠ°
     */
    private $connection;
    /**
     * Для хранСния всСх ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ
     */
    private $connects;

    /**
     * ΠžΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅ ΠΏΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ Ρ€Π°Π±ΠΎΡ‚Ρ‹ сСрвСра
     */
    private $timeLimit = 0;
    /**
     * ВрСмя Π½Π°Ρ‡Π°Π»Π° Ρ€Π°Π±ΠΎΡ‚Ρ‹ сСрвСра
     */
    private $startTime;
    /**
     * Π’Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ΡŒ сообщСния Π² консоль?
     */
    private $verbose = false;
    /**
     * Π—Π°ΠΏΠΈΡΡ‹Π²Π°Ρ‚ΡŒ сообщСния Π² log-Ρ„Π°ΠΉΠ»?
     */
    private $logging = false;
    /**
     * Имя log-Ρ„Π°ΠΉΠ»Π°
     */
    private $logFile = 'ws-log.txt';
    /**
     * РСсурс log-Ρ„Π°ΠΉΠ»Π°
     */
    private $resource;


    public function __construct($ip = '127.0.0.1', $port = 7777) {
        $this->ip = $ip;
        $this->port = $port;

        // эта функция вызываСтся, ΠΊΠΎΠ³Π΄Π° ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΎ сообщСниС ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°;
        // ΠΏΡ€ΠΈ создании экзСмпляра класса Π΄ΠΎΠ»ΠΆΠ½Π° Π±Ρ‹Ρ‚ΡŒ ΠΏΠ΅Ρ€Π΅ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π°
        $this->handler = function($connection, $data) {
            $message = '[' . date('r') . '] ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΎ сообщСниС ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°: ' . $data . PHP_EOL;
            if ($this->verbose) {
                echo $message;
            }
            if ($this->logging) {
                fwrite($this->resource, $message);
            }
        };
    }

    public function __destruct() {
        if (is_resource($this->connection)) {
            $this->stopServer();
        }
        if ($this->logging) {
            fclose($this->resource);
        }
    }

    /**
     * Π”ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ настройки для ΠΎΡ‚Π»Π°Π΄ΠΊΠΈ
     */
    public function settings($timeLimit = 0, $verbose = false, $logging = false, $logFile = 'ws-log.txt') {
        $this->timeLimit = $timeLimit;
        $this->verbose = $verbose;
        $this->logging = $logging;
        $this->logFile = $logFile;
        if ($this->logging) {
            $this->resource = fopen($this->logFile, 'a');
        }
    }

    /**
     * Π’Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ сообщСниС Π² консоль ΠΈΠ»ΠΈ записываСт Π² Π»ΠΎΠ³-Ρ„Π°ΠΉΠ»
     */
    private function debug($message) {
        $message = '[' . date('r') . '] ' . $message . PHP_EOL;
        if ($this->verbose) {
            echo $message;
        }
        if ($this->logging) {
            fwrite($this->resource, $message);
        }
    }

    /**
     * ΠžΡ‚ΠΏΡ€Π°Π²Π»ΡΠ΅Ρ‚ сообщСниС ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ
     */
    public static function response($connect, $data) {
        fwrite($connect, self::encode($data));
    }

    /**
     * ЗапускаСт сСрвСр Π² Ρ€Π°Π±ΠΎΡ‚Ρƒ
     */
    public function startServer() {
        
        $this->debug('Try start server...');

        $this->connection = stream_socket_server('tcp://' . $this->ip . ':' . $this->port, $errno, $errstr);
        
        if ( ! $this->connection) {
            $this->debug('Cannot start server: ' .$errstr. '(' .$errno. ')');
            return false;
        }

        $this->debug('Server is running...');

        $this->connects = array();
        $this->startTime = time();

        while (true) {

            $this->debug('Waiting for connections...');

            // Ρ„ΠΎΡ€ΠΌΠΈΡ€ΡƒΠ΅ΠΌ массив ΠΏΡ€ΠΎΡΠ»ΡƒΡˆΠΈΠ²Π°Π΅ΠΌΡ‹Ρ… сокСтов
            $read = $this->connects;
            $read[] = $this->connection;
            $write = $except = null;

            if ( ! stream_select($read, $write, $except, null)) { // ΠΎΠΆΠΈΠ΄Π°Π΅ΠΌ сокСты доступныС для чтСния (Π±Π΅Π· Ρ‚Π°ΠΉΠΌΠ°ΡƒΡ‚Π°)
                break;
            }

            if (in_array($this->connection, $read)) { // Π΅ΡΡ‚ΡŒ Π½ΠΎΠ²ΠΎΠ΅ соСдинСниС
                // ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅ΠΌ Π½ΠΎΠ²ΠΎΠ΅ соСдинСниС ΠΈ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΠΌ Ρ€ΡƒΠΊΠΎΠΏΠΎΠΆΠ°Ρ‚ΠΈΠ΅
                if (($connect = stream_socket_accept($this->connection, -1)) && $this->handshake($connect)) {
                    $this->debug('New connection accepted');
                    $this->connects[] = $connect; // добавляСм Π΅Π³ΠΎ Π² список Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Ρ… для ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ
                }
                unset($read[ array_search($this->connection, $read) ]);
            }

            foreach ($read as $connect) { // ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅ΠΌ всС соСдинСния
                $data = fread($connect, 100000);
                $decoded = self::decode($data);
                // Ссли ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π½Π΅ прислал Π΄Π°Π½Π½Ρ‹Ρ… ΠΈΠ»ΠΈ Ρ…ΠΎΡ‡Π΅Ρ‚ Ρ€Π°Π·ΠΎΡ€Π²Π°Ρ‚ΡŒ соСдинСниС
                if (false === $decoded || 'close' === $decoded['type']) {
                    $this->debug('Connection closing');
                    fwrite($connect, self::encode('  Closed on client demand', 'close'));
                    fclose($connect);
                    unset($this->connects[ array_search($connect, $this->connects) ]);
                    $this->debug('Closed successfully');
                    continue;
                }
                // ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΎ сообщСниС ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°, Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΡƒΡŽ
                // Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅
                if (is_callable($this->handler)) {
                    call_user_func($this->handler, $connect, $decoded['payload']);
                }
            }

            // Ссли истСкло ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅ ΠΏΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ, останавливаСм сСрвСр
            if ($this->timeLimit && time() - $this->startTime > $this->timeLimit) {
                $this->debug('Time limit. Stopping server.');
                $this->stopServer();
                return;
            }
        }
    }

    /**
     * ΠžΡΡ‚Π°Π½Π°Π²Π»ΠΈΠ²Π°Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Ρƒ сСрвСра
     */
    public function stopServer() {
        fclose($this->connection); // Π·Π°ΠΊΡ€Ρ‹Π²Π°Π΅ΠΌ ΡΠ»ΡƒΡˆΠ°ΡŽΡ‰ΠΈΠΉ сокСт
        if (!empty($this->connects)) { // отправляСм всС ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°ΠΌ сообщСниС ΠΎ Ρ€Π°Π·Ρ€Ρ‹Π²Π΅ соСдинСния
            foreach ($this->connects as $connect) {
                if (is_resource($connect)) {
                    fwrite($connect, self::encode('  Closed on server demand', 'close'));
                    fclose($connect);
                }
            }
        }
    }

    /**
     * Для кодирования сообщСний ΠΏΠ΅Ρ€Π΅Π΄ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΎΠΉ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ
     */
    private static function encode($payload, $type = 'text', $masked = false) {
        $frameHead = array();
        $payloadLength = strlen($payload);

        switch ($type) {
            case 'text':
                // first byte indicates FIN, Text-Frame (10000001):
                $frameHead[0] = 129;
                break;
            case 'close':
                // first byte indicates FIN, Close Frame(10001000):
                $frameHead[0] = 136;
                break;
            case 'ping':
                // first byte indicates FIN, Ping frame (10001001):
                $frameHead[0] = 137;
                break;
            case 'pong':
                // first byte indicates FIN, Pong frame (10001010):
                $frameHead[0] = 138;
                break;
        }

        // set mask and payload length (using 1, 3 or 9 bytes)
        if ($payloadLength > 65535) {
            $payloadLengthBin = str_split(sprintf('%064b', $payloadLength), 8);
            $frameHead[1] = ($masked === true) ? 255 : 127;
            for ($i = 0; $i < 8; $i++) {
                $frameHead[$i + 2] = bindec($payloadLengthBin[$i]);
            }
            // most significant bit MUST be 0
            if ($frameHead[2] > 127) {
                return array('type' => '', 'payload' => '', 'error' => 'frame too large (1004)');
            }
        } elseif ($payloadLength > 125) {
            $payloadLengthBin = str_split(sprintf('%016b', $payloadLength), 8);
            $frameHead[1] = ($masked === true) ? 254 : 126;
            $frameHead[2] = bindec($payloadLengthBin[0]);
            $frameHead[3] = bindec($payloadLengthBin[1]);
        } else {
            $frameHead[1] = ($masked === true) ? $payloadLength + 128 : $payloadLength;
        }

        // convert frame-head to string:
        foreach (array_keys($frameHead) as $i) {
            $frameHead[$i] = chr($frameHead[$i]);
        }
        if ($masked === true) {
            // generate a random mask:
            $mask = array();
            for ($i = 0; $i < 4; $i++) {
                $mask[$i] = chr(rand(0, 255));
            }
            $frameHead = array_merge($frameHead, $mask);
        }
        $frame = implode('', $frameHead);

        // append payload to frame:
        for ($i = 0; $i < $payloadLength; $i++) {
            $frame .= ($masked === true) ? $payload[$i] ^ $mask[$i % 4] : $payload[$i];
        }

        return $frame;
    }

    /**
     * Для дСкодирования сообщСний, ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹Ρ… ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°
     */
    private static function decode($data) {
        if ( ! strlen($data)) {
            return false;
        }

        $unmaskedPayload = '';
        $decodedData = array();

        // estimate frame type:
        $firstByteBinary = sprintf('%08b', ord($data[0]));
        $secondByteBinary = sprintf('%08b', ord($data[1]));
        $opcode = bindec(substr($firstByteBinary, 4, 4));
        $isMasked = ($secondByteBinary[0] == '1') ? true : false;
        $payloadLength = ord($data[1]) & 127;

        // unmasked frame is received:
        if (!$isMasked) {
            return array('type' => '', 'payload' => '', 'error' => 'protocol error (1002)');
        }

        switch ($opcode) {
            // text frame:
            case 1:
                $decodedData['type'] = 'text';
                break;
            case 2:
                $decodedData['type'] = 'binary';
                break;
            // connection close frame:
            case 8:
                $decodedData['type'] = 'close';
                break;
            // ping frame:
            case 9:
                $decodedData['type'] = 'ping';
                break;
            // pong frame:
            case 10:
                $decodedData['type'] = 'pong';
                break;
            default:
                return array('type' => '', 'payload' => '', 'error' => 'unknown opcode (1003)');
        }

        if ($payloadLength === 126) {
            $mask = substr($data, 4, 4);
            $payloadOffset = 8;
            $dataLength = bindec(sprintf('%08b', ord($data[2])) . sprintf('%08b', ord($data[3]))) + $payloadOffset;
        } elseif ($payloadLength === 127) {
            $mask = substr($data, 10, 4);
            $payloadOffset = 14;
            $tmp = '';
            for ($i = 0; $i < 8; $i++) {
                $tmp .= sprintf('%08b', ord($data[$i + 2]));
            }
            $dataLength = bindec($tmp) + $payloadOffset;
            unset($tmp);
        } else {
            $mask = substr($data, 2, 4);
            $payloadOffset = 6;
            $dataLength = $payloadLength + $payloadOffset;
        }

        /**
         * We have to check for large frames here. socket_recv cuts at 1024 bytes
         * so if websocket-frame is > 1024 bytes we have to wait until whole
         * data is transferd.
         */
        if (strlen($data) < $dataLength) {
            return false;
        }

        if ($isMasked) {
            for ($i = $payloadOffset; $i < $dataLength; $i++) {
                $j = $i - $payloadOffset;
                if (isset($data[$i])) {
                    $unmaskedPayload .= $data[$i] ^ $mask[$j % 4];
                }
            }
            $decodedData['payload'] = $unmaskedPayload;
        } else {
            $payloadOffset = $payloadOffset - 4;
            $decodedData['payload'] = substr($data, $payloadOffset);
        }

        return $decodedData;
    }

    /**
     * Β«Π ΡƒΠΊΠΎΠΏΠΎΠΆΠ°Ρ‚ΠΈΠ΅Β», Ρ‚.Π΅. ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠ° Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΎΠ² согласно ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Ρƒ WebSocket
     */
    private function handshake($connect) {
        $info = array();

        $line = fgets($connect);
        $header = explode(' ', $line);
        $info['method'] = $header[0];
        $info['uri'] = $header[1];

        // считываСм Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ ΠΈΠ· соСдинСния
        while ($line = rtrim(fgets($connect))) {
            if (preg_match('/\A(\S+): (.*)\z/', $line, $matches)) {
                $info[$matches[1]] = $matches[2];
            } else {
                break;
            }
        }

        // ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ адрСс ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°
        $address = explode(':', stream_socket_get_name($connect, true));
        $info['ip'] = $address[0];
        $info['port'] = $address[1];

        if (empty($info['Sec-WebSocket-Key'])) {
            return false;
        }

        // отправляСм Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ согласно ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Ρƒ вСбсокСта
        $SecWebSocketAccept = 
            base64_encode(pack('H*', sha1($info['Sec-WebSocket-Key'] . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')));
        $upgrade = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" .
                   "Upgrade: websocket\r\n" .
                   "Connection: Upgrade\r\n" .
                   "Sec-WebSocket-Accept:".$SecWebSocketAccept."\r\n\r\n";
        fwrite($connect, $upgrade);

        return $info;
    }

}
Π”ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ

Поиск:
HandShakeΒ β€’ JavaScriptΒ β€’ PHPΒ β€’ ServerΒ β€’ SocketΒ β€’ Web-Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ°Β β€’ WebSocketΒ β€’ ΠšΠ»ΠΈΠ΅Π½Ρ‚Β β€’ ΠŸΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Β β€’ Π‘Π΅Ρ€Π²Π΅Ρ€Β β€’ Π‘ΠΎΠΊΠ΅Ρ‚

Π§Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅ Π²Π΅Π±-сокСт ΠΈ Ρ‡Π΅ΠΌ ΠΎΠ½ отличаСтся ΠΎΡ‚ HTTP?

HTTP ΠΈ WebSocket β€” это ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Ρ‹ связи, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Π΅ Π² ΠΊΠΎΠΌΠΌΡƒΠ½ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΊΠ»ΠΈΠ΅Π½Ρ‚-сСрвСр.

ΠŸΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» HTTP: HTTP являСтся ΠΎΠ΄Π½ΠΎΠ½Π°ΠΏΡ€Π°Π²Π»Π΅Π½Π½Ρ‹ΠΌ, ΠΊΠΎΠ³Π΄Π° ΠΊΠ»ΠΈΠ΅Π½Ρ‚ отправляСт запрос, Π° сСрвСр отправляСт ΠΎΡ‚Π²Π΅Ρ‚. Π”Π°Π²Π°ΠΉΡ‚Π΅ рассмотрим ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΊΠΎΠ³Π΄Π° ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ отправляСт запрос Π½Π° сСрвСр, этот запрос поступаСт Π² Π²ΠΈΠ΄Π΅ HTTP ΠΈΠ»ΠΈ HTTPS, послС ΠΏΡ€ΠΈΠ΅ΠΌΠ° сСрвСром запроса отправляСт ΠΎΡ‚Π²Π΅Ρ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ, ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ запрос связываСтся с ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΡ‚Π²Π΅Ρ‚ΠΎΠΌ, послС ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ ΠΎΡ‚Π²Π΅Ρ‚Π° соСдинСниС закрываСтся, ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ запрос HTTP ΠΈΠ»ΠΈ HTTPS ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ€Π°Π· устанавливаСт Π½ΠΎΠ²ΠΎΠ΅ соСдинСниС с сСрвСром, ΠΈ послС получСния ΠΎΡ‚Π²Π΅Ρ‚Π° соСдинСниС прСрываСтся само собой.
HTTP β€” это ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» Π±Π΅Π· сохранСния состояния, Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‰ΠΈΠΉ ΠΏΠΎΠ²Π΅Ρ€Ρ… TCP, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ являСтся ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»ΠΎΠΌ, ΠΎΡ€ΠΈΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΌ Π½Π° установлСниС соСдинСния, ΠΎΠ½ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚ доставку ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΠ² Π΄Π°Π½Π½Ρ‹Ρ… с использованиСм трСхсторонних ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² установлСния связи ΠΈ ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΡƒΡŽ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Ρƒ потСрянных ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΠ².

HTTP ΠΌΠΎΠΆΠ΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ ΠΏΠΎΠ²Π΅Ρ€Ρ… любого Π½Π°Π΄Π΅ΠΆΠ½ΠΎΠ³ΠΎ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π° с установлСниСм соСдинСния, Ρ‚Π°ΠΊΠΎΠ³ΠΎ ΠΊΠ°ΠΊ TCP, SCTP. Когда ΠΊΠ»ΠΈΠ΅Π½Ρ‚ отправляСт HTTP-запрос Π½Π° сСрвСр, ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ ΠΈ сСрвСром открываСтся TCP-соСдинСниС, ΠΈ послС получСния ΠΎΡ‚Π²Π΅Ρ‚Π° TCP-соСдинСниС прСрываСтся, ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ HTTP-запрос ΠΎΡ‚ΠΊΡ€Ρ‹Π²Π°Π΅Ρ‚ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠ΅ TCP-соСдинСниС с сСрвСром, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Ссли ΠΊΠ»ΠΈΠ΅Π½Ρ‚ отправляСт 10 запросов На сСрвСрС Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΎ 10 ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Ρ… HTTP-соСдинСний. ΠΈ Π·Π°ΠΊΡ€ΠΎΠΉΡ‚Π΅ послС получСния ΠΎΡ‚Π²Π΅Ρ‚Π° / отступлСния.

Π˜Π½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡ сообщСния HTTP, закодированная Π² ASCII, ΠΊΠ°ΠΆΠ΄ΠΎΠ΅ сообщСниС запроса HTTP состоит ΠΈΠ· вСрсии ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π° HTTP (HTTP / 1.1, HTTP / 2), ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² HTTP (GET / POST ΠΈ Ρ‚. Π”.), Π—Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΎΠ² HTTP (Ρ‚ΠΈΠΏ содСрТимого, Π΄Π»ΠΈΠ½Π° содСрТимого), ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΎ хостС ΠΈ Ρ‚. Π”. ΠΈ Ρ‚Π΅Π»ΠΎ, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ содСрТит фактичСскоС сообщСниС, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ пСрСдаСтся Π½Π° сСрвСр. Π—Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ HTTP Π²Π°Ρ€ΡŒΠΈΡ€ΡƒΡŽΡ‚ΡΡ ΠΎΡ‚ 200 Π±Π°ΠΉΡ‚ΠΎΠ² Π΄ΠΎ 2 ΠšΠ‘, ΠΎΠ±Ρ‰ΠΈΠΉ Ρ€Π°Π·ΠΌΠ΅Ρ€ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° HTTP составляСт 700-800 Π±Π°ΠΉΡ‚ΠΎΠ². Когда Π²Π΅Π±-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ большС Ρ„Π°ΠΉΠ»ΠΎΠ² cookie ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΡ… инструмСнтов Π½Π° сторонС ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Ρ€Π°ΡΡ…ΠΎΠ΄ΡƒΡŽΡ‚ срСдства хранСния Π°Π³Π΅Π½Ρ‚Π°, ΠΎΠ½ΠΎ ΡƒΠΌΠ΅Π½ΡŒΡˆΠ°Π΅Ρ‚ ΠΏΠΎΠ»Π΅Π·Π½ΡƒΡŽ Π½Π°Π³Ρ€ΡƒΠ·ΠΊΡƒ HTTP-Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ°.

WebSocket: WebSocket являСтся Π΄Π²ΡƒΠ½Π°ΠΏΡ€Π°Π²Π»Π΅Π½Π½Ρ‹ΠΌ, полнодуплСксным ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»ΠΎΠΌ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Π² Ρ‚ΠΎΠΌ ΠΆΠ΅ сцСнарии взаимодСйствия ΠΊΠ»ΠΈΠ΅Π½Ρ‚-сСрвСр, Π² ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ HTTP, ΠΎΠ½ начинаСтся с ws: // ΠΈΠ»ΠΈ wss: // . Π­Ρ‚ΠΎ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» с отслСТиваниСм состояния, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ соСдинСниС ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ ΠΈ сСрвСром Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Ρ‚ΡŒΡΡ Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° ΠΎΠ½ΠΎ Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΡ€Π΅Ρ€Π²Π°Π½ΠΎ ΠΊΠ°ΠΊΠΎΠΉ-Π»ΠΈΠ±ΠΎ стороной (ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ ΠΈΠ»ΠΈ сСрвСром). послС закрытия соСдинСния ΠΎΠ΄Π½ΠΈΠΌ ΠΈΠ· ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ² ΠΈ сСрвСра соСдинСниС прСкращаСтся с ΠΎΠ±ΠΎΠΈΡ… ΠΊΠΎΠ½Ρ†ΠΎΠ².

Π”Π°Π²Π°ΠΉΡ‚Π΅ возьмСм ΠΏΡ€ΠΈΠΌΠ΅Ρ€ взаимодСйствия ΠΊΠ»ΠΈΠ΅Π½Ρ‚-сСрвСр: Π΅ΡΡ‚ΡŒ ΠΊΠ»ΠΈΠ΅Π½Ρ‚, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ являСтся Π²Π΅Π±-Π±Ρ€Π°ΡƒΠ·Π΅Ρ€ΠΎΠΌ ΠΈ сСрвСром, всякий Ρ€Π°Π·, ΠΊΠΎΠ³Π΄Π° ΠΌΡ‹ ΠΈΠ½ΠΈΡ†ΠΈΠΈΡ€ΡƒΠ΅ΠΌ соСдинСниС ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ ΠΈ сСрвСром, ΠΊΠ»ΠΈΠ΅Π½Ρ‚-сСрвСр ΡΠΎΠ²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ Ρ€ΡƒΠΊΠΎΠΏΠΎΠΆΠ°Ρ‚ΠΈΠ΅ ΠΈ Ρ€Π΅ΡˆΠ°Π΅Ρ‚ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ Π½ΠΎΠ²ΠΎΠ΅ соСдинСниС, ΠΈ это соСдинСниС Π±ΡƒΠ΄Π΅Ρ‚ ΡΠΎΡ…Ρ€Π°Π½ΠΈΡ‚ΡŒ Π² ΠΆΠΈΠ²Ρ‹Ρ… Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΡ€Π΅ΠΊΡ€Π°Ρ‰Π΅Π½ Π½ΠΈ ΠΎΠ΄Π½ΠΈΠΌ ΠΈΠ· Π½ΠΈΡ…. Когда соСдинСниС установлСно ΠΈ Π°ΠΊΡ‚ΠΈΠ²Π½ΠΎ, соСдинСниС происходит ΠΏΠΎ ΠΎΠ΄Π½ΠΎΠΌΡƒ ΠΈ Ρ‚ΠΎΠΌΡƒ ΠΆΠ΅ ΠΊΠ°Π½Π°Π»Ρƒ соСдинСния, ΠΏΠΎΠΊΠ° ΠΎΠ½ΠΎ Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΡ€Π΅Ρ€Π²Π°Π½ΠΎ.

Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, послС установлСния связи ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ ΠΈ сСрвСром ΠΊΠ»ΠΈΠ΅Π½Ρ‚-сСрвСр ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ ΠΎ Π½ΠΎΠ²ΠΎΠΌ соСдинСнии, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Ρ‚ΡŒ Π΅Π³ΠΎ, это Π½ΠΎΠ²ΠΎΠ΅ соСдинСниС Π±ΡƒΠ΄Π΅Ρ‚ Π½Π°Π·Ρ‹Π²Π°Ρ‚ΡŒΡΡ WebSocket. Как Ρ‚ΠΎΠ»ΡŒΠΊΠΎ установлСниС Π»ΠΈΠ½ΠΈΠΈ связи ΠΈ соСдинСниС Π±ΡƒΠ΄ΡƒΡ‚ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹, ΠΎΠ±ΠΌΠ΅Π½ сообщСниями Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΡ€ΠΎΠΈΡΡ…ΠΎΠ΄ΠΈΡ‚ΡŒ Π² Π΄Π²ΡƒΠ½Π°ΠΏΡ€Π°Π²Π»Π΅Π½Π½ΠΎΠΌ Ρ€Π΅ΠΆΠΈΠΌΠ΅ Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΊΠ»ΠΈΠ΅Π½Ρ‚-сСрвСром Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ установлСно соСдинСниС. Если ΠΊΡ‚ΠΎ-Π»ΠΈΠ±ΠΎ ΠΈΠ· Π½ΠΈΡ… (ΠΊΠ»ΠΈΠ΅Π½Ρ‚-сСрвСр) ΡƒΠΌΠΈΡ€Π°Π΅Ρ‚ ΠΈΠ»ΠΈ Ρ€Π΅ΡˆΠ°Π΅Ρ‚ Π·Π°ΠΊΡ€Ρ‹Ρ‚ΡŒ, соСдинСниС закрываСтся ΠΎΠ±Π΅ΠΈΠΌΠΈ сторонами. Π’ΠΎ, ΠΊΠ°ΠΊ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ сокСт, Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ отличаСтся ΠΎΡ‚ Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ HTTP, ΠΊΠΎΠ΄ состояния 101 ΠΎΠ±ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ Π² WebSocket.

Когда ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π²Π΅Π±-сокСт:

  • Π’Π΅Π±-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π² Ρ€Π΅ΠΆΠΈΠΌΠ΅ Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ. Π’Π΅Π±-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π² Ρ€Π΅ΠΆΠΈΠΌΠ΅ Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ Π²Π΅Π±-сокСт для отобраТСния Π΄Π°Π½Π½Ρ‹Ρ… Π½Π° сторонС ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½Π΅ΠΏΡ€Π΅Ρ€Ρ‹Π²Π½ΠΎ ΠΎΡ‚ΠΏΡ€Π°Π²Π»ΡΡŽΡ‚ΡΡ Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½ΠΈΠΌ сСрвСром. Π’ WebSocket Π΄Π°Π½Π½Ρ‹Π΅ Π½Π΅ΠΏΡ€Π΅Ρ€Ρ‹Π²Π½ΠΎ ΠΏΡ€ΠΎΡ‚Π°Π»ΠΊΠΈΠ²Π°ΡŽΡ‚ΡΡ / ΠΏΠ΅Ρ€Π΅Π΄Π°ΡŽΡ‚ΡΡ Π² ΠΎΠ΄Π½ΠΎ ΠΈ Ρ‚ΠΎ ΠΆΠ΅ соСдинСниС, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ΡƒΠΆΠ΅ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΎ, поэтому Π²Π΅Π±-сокСт быстрСС ΠΈ ΠΏΠΎΠ²Ρ‹ΡˆΠ°Π΅Ρ‚ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ прилоТСния.

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

  • Π˜Π³Ρ€ΠΎΠ²ΠΎΠ΅ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅. Π’ ΠΈΠ³Ρ€ΠΎΠ²ΠΎΠΌ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΡΠΎΡΡ€Π΅Π΄ΠΎΡ‚ΠΎΡ‡ΠΈΡ‚ΡŒΡΡ Π½Π° Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ Π΄Π°Π½Π½Ρ‹Π΅ постоянно ΠΏΠΎΡΡ‚ΡƒΠΏΠ°ΡŽΡ‚ Π½Π° сСрвСр ΠΈ Π±Π΅Π· обновлСния ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΎΠ³ΠΎ интСрфСйса Π±ΡƒΠ΄ΡƒΡ‚ Π΄Π΅ΠΉΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ Π½Π° экранС; ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ интСрфСйс автоматичСски обновляСтся, Π΄Π°ΠΆΠ΅ Π½Π΅ устанавливая Π½ΠΎΠ²ΠΎΠ΅ соСдинСниС, поэтому ΠΎΠ½ΠΎ ΠΎΡ‡Π΅Π½ΡŒ ΠΏΠΎΠ»Π΅Π·Π½ΠΎ Π² ΠΈΠ³Ρ€ΠΎΠ²ΠΎΠΌ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ.
  • ΠŸΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Ρ‡Π°Ρ‚Π°. ΠŸΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Ρ‡Π°Ρ‚Π° ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ WebSocket для установлСния соСдинСния Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ Ρ€Π°Π· для ΠΎΠ±ΠΌΠ΅Π½Π°, ΠΏΡƒΠ±Π»ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΈ трансляции сообщСния срСди подписчика. ΠΎΠ½ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ ΠΎΠ΄Π½ΠΎ ΠΈ Ρ‚ΠΎ ΠΆΠ΅ соСдинСниС WebSocket для ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ ΠΈ получСния сообщСния ΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ сообщСния ΠΎΠ΄ΠΈΠ½ Π½Π° ΠΎΠ΄ΠΈΠ½.

Когда Π½Π΅ слСдуСт ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ WebSocket: WebSocket ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ, Ссли Π½Π°ΠΌ Π½ΡƒΠΆΠ½Ρ‹ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½Π½Ρ‹Π΅ Π² Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠΌ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ ΠΈΠ»ΠΈ Π½Π΅ΠΏΡ€Π΅Ρ€Ρ‹Π²Π½Ρ‹Π΅ ΠΏΠΎΡ‚ΠΎΠΊΠΈ Π΄Π°Π½Π½Ρ‹Ρ…, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΏΠ΅Ρ€Π΅Π΄Π°ΡŽΡ‚ΡΡ ΠΏΠΎ сСти. Если ΠΌΡ‹ Ρ…ΠΎΡ‚ΠΈΠΌ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ старыС Π΄Π°Π½Π½Ρ‹Π΅ ΠΈΠ»ΠΈ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ Ρ€Π°Π·, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ ΠΈΡ… с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ прилоТСния, ΠΌΡ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» HTTP , старыС Π΄Π°Π½Π½Ρ‹Π΅, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½Π΅ Ρ‚Ρ€Π΅Π±ΡƒΡŽΡ‚ΡΡ ΠΎΡ‡Π΅Π½ΡŒ часто ΠΈΠ»ΠΈ Π²Ρ‹Π±ΠΈΡ€Π°ΡŽΡ‚ΡΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ Ρ€Π°Π·, ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ Π·Π°ΠΏΡ€ΠΎΡˆΠ΅Π½Ρ‹ простым HTTP-запросом, поэтому Π² этом сцСнарии Π»ΡƒΡ‡ΡˆΠ΅ Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ WebSocket.

ΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅: Π²Π΅Π±-сСрвисов RESTful достаточно для получСния Π΄Π°Π½Π½Ρ‹Ρ… с сСрвСра, Ссли ΠΌΡ‹ Π·Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ Π΄Π°Π½Π½Ρ‹Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ Ρ€Π°Π·.

Различия ΠΌΠ΅ΠΆΠ΄Ρƒ HTTP ΠΈ WebSocket Connection:

WebSocket ConnectionHTTP Connection
WebSocket is a bidirectional communication protocol that can send the data from the client to the server or from the server to the client by reusing the established connection channel. The connection is kept alive until terminated by either the client or the server.The HTTP protocol is unidirectional protocol works on the top of TCP protocol which is a connection-oriented transport layer protocol, we can create the connection by using HTTP request methods after getting the response HTTP connection get closed.
Almost all the real-time application like (trading, monitoring, notification) services uses WebSocket to receiving the data on a single communication channel.Simple RESTful application uses HTTP protocol which is stateless.
All the frequently updated applications used WebSocket because it is faster than HTTP Connection.When we do not want to retain a connection for a particular amount of time or reusing the single connection for transmitting the data, HTTP connection is slower than the WebSocket..

ΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅: Π² зависимости ΠΎΡ‚ вашСго ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° Π²Ρ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π²Ρ‹Π±Ρ€Π°Ρ‚ΡŒ, Π³Π΄Π΅ это Π±ΡƒΠ΄Π΅Ρ‚ WebSocket ΠΈΠ»ΠΈ HTTP Connection.

Π Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡƒΠ΅ΠΌΡ‹Π΅ посты:

Π§Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅ Π²Π΅Π±-сокСт ΠΈ Ρ‡Π΅ΠΌ ΠΎΠ½ отличаСтся ΠΎΡ‚ HTTP?

0.00 (0%) 0 votes

Π˜ΡΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΠΈ ΠΏΡ€Π΅Π΄ΡƒΠΏΡ€Π΅Π΄ΠΈΠ»ΠΈ, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» WS-Discovery ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для DDoS-Π°Ρ‚Π°ΠΊ β€” Β«Π₯Π°ΠΊΠ΅Ρ€Β»

Π˜Π‘-спСциалисты обСспокоСны Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎ Π·Π»ΠΎΡƒΠΌΡ‹ΡˆΠ»Π΅Π½Π½ΠΈΠΊΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ WS-Discovery (Web Services Dynamic Discovery) для DDoS-Π°Ρ‚Π°ΠΊ, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» ΠΌΠΎΠΆΠ΅Ρ‚ Π΄Π°Π²Π°Ρ‚ΡŒ коэффициСнт Π°ΠΌΠΏΠ»ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ Ρ€Π°Π²Π½Ρ‹ΠΉ 300 ΠΈ Π΄Π°ΠΆΠ΅ 500.

ИзданиС ZDNet сообщаСт, Ρ‡Ρ‚ΠΎ ΠΏΠ΅Ρ€Π²Ρ‹Π΅ Π°Ρ‚Π°ΠΊΠΈ Ρ‚Π°ΠΊΠΎΠ³ΠΎ Ρ€ΠΎΠ΄Π° Π½Π°Ρ‡Π°Π»ΠΈΡΡŒ Π΅Ρ‰Π΅ Π² ΠΌΠ°Π΅ Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ Π³ΠΎΠ΄Π°, ΠΎΠ΄Π½Π°ΠΊΠΎ Ρ‚ΠΎΠ³Π΄Π° спСциалисты ΠΈ ΠΈΠ·Π΄Π°Π½ΠΈΠ΅ Ρ€Π΅ΡˆΠΈΠ»ΠΈ Π½Π΅ ΠΏΡ€ΠΈΠ²Π»Π΅ΠΊΠ°Ρ‚ΡŒ внимания ΠΊ происходящСму, ΠΈ Π½Π΅ ΠΏΠΎΠ΄Π°Π²Π°Ρ‚ΡŒ Π·Π»ΠΎΡƒΠΌΡ‹ΡˆΠ»Π΅Π½Π½ΠΈΠΊΠ°ΠΌ ΠΈΠ΄Π΅ΠΈ. Но Π² послСднСС врСмя ΡƒΠΆΠ΅ нСсколько Ρ…Π°ΠΊ-Π³Ρ€ΡƒΠΏΠΏ Π½Π°Ρ‡Π°Π»ΠΈ Π·Π»ΠΎΡƒΠΏΠΎΡ‚Ρ€Π΅Π±Π»ΡΡ‚ΡŒ WS-Discovery, ΠΈ Ρ‚Π°ΠΊΠΈΠ΅ DDoS-Π°Ρ‚Π°ΠΊΠΈ, ΠΊ соТалСнию, становятся постоянным явлСниСм.

WS-Discovery прСдставляСт собой многоадрСсный ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ», ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ для обнаруТСния Π΄Ρ€ΡƒΠ³ΠΈΡ… устройств, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΎΠ±ΠΌΠ΅Π½ΠΈΠ²Π°ΡŽΡ‚ΡΡ Π΄Π°Π½Π½Ρ‹ΠΌΠΈ Ρ‡Π΅Ρ€Π΅Π· ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹ΠΉ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» ΠΈΠ»ΠΈ интСрфСйс. Π’Π°ΠΊ, ΠΎΠ½ примСняСтся для обнаруТСния ΠΈ ΠΎΠ±ΠΌΠ΅Π½Π° Π΄Π°Π½Π½Ρ‹ΠΌΠΈ посрСдством SOAP с использованиСм ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΠ² UDP, поэтому ΠΈΠ½ΠΎΠ³Π΄Π° WS-Discovery Π½Π°Π·Ρ‹Π²Π°ΡŽΡ‚ SOAP-over-UDP.

И хотя WS-Discovery нСльзя Π½Π°Π·Π²Π°Ρ‚ΡŒ ΡˆΠΈΡ€ΠΎΠΊΠΎ распространСнным ΠΈΠ»ΠΈ общСизвСстным ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»ΠΎΠΌ, ΠΎΠ½ ΠΎΠ΄ΠΎΠ±Ρ€Π΅Π½ отраслСвой ΠΎΡ€Π³Π°Π½ΠΈΠ·Π°Ρ†ΠΈΠ΅ΠΉ ONVIF, Ρ‡Π»Π΅Π½Π°ΠΌΠΈ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΡΠ²Π»ΡΡŽΡ‚ΡΡ Ρ‚Π°ΠΊΠΈΠ΅ ΠΊΠΎΠΌΠΏΠ°Π½ΠΈΠΈ, ΠΊΠ°ΠΊ Axis, Sony, Bosch ΠΈ Ρ‚Π°ΠΊ Π΄Π°Π»Π΅Π΅. Π’ ΠΈΡ‚ΠΎΠ³Π΅ Π² настоящСС врСмя WS-Discovery ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‚ мноТСство устройств, ΠΎΡ‚ IP-ΠΊΠ°ΠΌΠ΅Ρ€ Π΄ΠΎ ΠΏΡ€ΠΈΠ½Ρ‚Π΅Ρ€ΠΎΠ², ΠΎΡ‚ Π±Ρ‹Ρ‚ΠΎΠ²Ρ‹Ρ… ΠΏΡ€ΠΈΠ±ΠΎΡ€ΠΎΠ² Π΄ΠΎ DVR. По статистикС поисковика BinaryEdge, Π² сСти ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠΈΡ‚ΡŒ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ 630Β 000 Ρ‚Π°ΠΊΠΈΡ… дСвайсов.

По мнСнию Π˜Π‘-спСциалистов, WS-Discovery идСально ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΈΡ‚ для провСдСния DDoS-Π°Ρ‚Π°ΠΊ ΠΏΠΎ ряду ΠΏΡ€ΠΈΡ‡ΠΈΠ½. Π’ΠΎ-ΠΏΠ΅Ρ€Π²Ρ‹Ρ…, ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» основан Π½Π° UDP, Π° Π·Π½Π°Ρ‡ΠΈΡ‚, Π²ΠΎΠ·ΠΌΠΎΠΆΠ΅Π½ спуфинг мСста назначСния ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΠ². ΠΡ‚Π°ΠΊΡƒΡŽΡ‰ΠΈΠ΅ ΠΌΠΎΠ³ΡƒΡ‚ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ UDP-ΠΏΠ°ΠΊΠ΅Ρ‚ WS-Discovery-слуТбС устройства, использовав ΠΏΡ€ΠΈ этом ΠΏΠΎΠ΄Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ ΠΎΠ±Ρ€Π°Ρ‚Π½Ρ‹ΠΉ IP-адрСс. Π’ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ устройство Π½Π°ΠΏΡ€Π°Π²ΠΈΡ‚ свой ΠΎΡ‚Π²Π΅Ρ‚ Π½Π° этот ΠΏΠΎΠ΄Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ адрСс, позволяя Π·Π»ΠΎΡƒΠΌΡ‹ΡˆΠ»Π΅Π½Π½ΠΈΠΊΠ°ΠΌ ΠΌΠ°Π½ΠΈΠΏΡƒΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ WS-Discovery-Ρ‚Ρ€Π°Ρ„ΠΈΠΊΠΎΠΌ ΠΈ направляя Π΅Π³ΠΎ Π½Π° ΠΆΠ΅Π»Π°Π΅ΠΌΡƒΡŽ Ρ†Π΅Π»ΡŒ. Π’ΠΎ-Π²Ρ‚ΠΎΡ€Ρ‹Ρ…, ΠΎΡ‚Π²Π΅Ρ‚ WS-Discovery Π²ΠΎ ΠΌΠ½ΠΎΠ³ΠΎ Ρ€Π°Π· большС ΠΈΠ·Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ запроса.Β Π­Ρ‚ΠΎ позволяСт Π°Ρ‚Π°ΠΊΡƒΡŽΡ‰ΠΈΠΌ Π±Π΅Π· Ρ‚Ρ€ΡƒΠ΄Π° ΡƒΡΠΈΠ»ΠΈΠ²Π°Ρ‚ΡŒ DDoS-Π°Ρ‚Π°ΠΊΠΈ.

По ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ZDNet, WS-Discovery использовался Π² Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… DDoS-Π°Ρ‚Π°ΠΊΠ°Ρ…, коэффициСнт Π°ΠΌΠΏΠ»ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π΄ΠΎΡ…ΠΎΠ΄ΠΈΠ» Π΄ΠΎ 300 ΠΈ Π΄Π°ΠΆΠ΅ Π΄ΠΎ 500. Π­Ρ‚ΠΎ ΠΎΡ‡Π΅Π½ΡŒ Ρ‚Ρ€Π΅Π²ΠΎΠΆΠ½Ρ‹Π΅ Ρ†ΠΈΡ„Ρ€Ρ‹, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ коэффициСнт усилСния для Π΄Ρ€ΡƒΠ³ΠΈΡ… UDP-ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»ΠΎΠ² Ρ€Π°Π²Π΅Π½ Π² срСднСм 10. К ΡΡ‡Π°ΡΡ‚ΡŒΡŽ, исслСдоватСли ΠΏΠΎΠ»Π°Π³Π°ΡŽΡ‚, Ρ‡Ρ‚ΠΎ Ρ‚Π°ΠΊΠΈΠ΅ высокиС коэффициСнты Π°ΠΌΠΏΠ»ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ – это скорСС ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΈΠ· ΠΏΡ€Π°Π²ΠΈΠ»Π°, Π° Π½Π΅ Π½ΠΎΡ€ΠΌΠ°. Π’Π°ΠΊ, ΠΏΠΎ Π΄Π°Π½Π½Ρ‹ΠΌ Π˜Π‘-ΠΊΠΎΠΌΠΏΠ°Π½ΠΈΠΈ ZeroBS GmbH, которая Π² этом мСсяцС отслСТивала Π²ΠΎΠ»Π½Ρƒ DDoS-Π°Ρ‚Π°ΠΊ с использованиСм WS-Discovery, Π±ΠΎΠ»Π΅Π΅ распространСнный коэффициСнт усилСния всС ΠΆΠ΅ составляСт ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ 10.

Π’Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅, Турналисты ΠΎΡ‚ΠΌΠ΅Ρ‡Π°ΡŽΡ‚, Ρ‡Ρ‚ΠΎ PoC-эксплоит для провСдСния DDoS-Π°Ρ‚Π°ΠΊ с использованиСм WS-Discovery, ΠΎΠΏΡƒΠ±Π»ΠΈΠΊΠΎΠ²Π°Π½Π½Ρ‹ΠΉ Π½Π° GitHub Π΅Ρ‰Π΅ Π² ΠΊΠΎΠ½Ρ†Π΅ 2018 Π³ΠΎΠ΄Π°, ΠΏΠΎΠΌΠΎΠ³Π°Π΅Ρ‚ Π΄ΠΎΡΡ‚ΠΈΡ‡ΡŒ коэффициСнта Π°ΠΌΠΏΠ»ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΎΡ‚ 70 Π΄ΠΎ 150 (ссылку ΠΈΠ·Π΄Π°Π½ΠΈΠ΅ ΠΏΠΎ понятным ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π°ΠΌ Π½Π΅ ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΡ‚).

О ΠΏΠ΅Ρ€Π²Ρ‹Ρ… ΠΌΠ°ΡΡˆΡ‚Π°Π±Π½Ρ‹Ρ… Π°Ρ‚Π°ΠΊΠ°Ρ… с использованиСм ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π° WS-Discovery Π² ΠΌΠ°Π΅ Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ Π³ΠΎΠ΄Π° сообщил Π˜Π‘-спСциалист Π’Π°ΠΊΠ΅Ρ€ ΠŸΡ€Π΅ΡΡ‚ΠΎΠ½ (Tucker Preston). Π’ΠΎΠ³Π΄Π° ΠΎΠ½ наблюдал Π±ΠΎΠ»Π΅Π΅ 130 DDoS-Π°Ρ‚Π°ΠΊ, Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΈΠ· ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… достигли мощности Π±ΠΎΠ»Π΅Π΅ 350 Π“Π±ΠΈΡ‚/с. ПозднСС ΠΎΠ± этих Π°Ρ‚Π°ΠΊΠ°Ρ… написали ΠΈ экспСрты ΠΊΠΎΠΌΠΏΠ°Π½ΠΈΠΈ Netscout Π² ΠΎΡ‚Ρ‡Π΅Ρ‚Π΅, ΠΎΠΏΡƒΠ±Π»ΠΈΠΊΠΎΠ²Π°Π½Π½ΠΎΠΌ Π² ΠΏΡ€ΠΎΡˆΠ»ΠΎΠΌ мСсяцС.

Атаки, зафиксированныС Π’Π°ΠΊΠ΅Ρ€ΠΎΠΌ ΠŸΡ€Π΅ΡΡ‚ΠΎΠ½ΠΎΠΌ

И хотя, ΠΏΠΎ Π΄Π°Π½Π½Ρ‹ΠΌ ZeroBS GmbH, ΠΏΠΎΡ‚ΠΎΠΌ Π°Ρ‚Π°ΠΊΠΈ ΠΏΠΎΡ‡Ρ‚ΠΈ ΠΏΡ€Π΅ΠΊΡ€Π°Ρ‚ΠΈΠ»ΠΈΡΡŒ, Π² августС 2019 Π³ΠΎΠ΄Π° ΠΎΠ½ΠΈ ΡƒΡΠΈΠ»ΠΈΠ»ΠΈΡΡŒ снова. Π’ ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ ΠΏΠ΅Ρ€Π²Ρ‹Ρ… Π²ΠΎΠ»Π½, эти Π°Ρ‚Π°ΠΊΠΈ Π±Ρ‹Π»ΠΈ Π³ΠΎΡ€Π°Π·Π΄ΠΎ «скромнСС», ΠΈ исслСдоватСли ΠΏΠΎΠ»Π°Π³Π°ΡŽΡ‚, Ρ‡Ρ‚ΠΎ ΠΈΡ… ΠΏΡ€ΠΎΠ²ΠΎΠ΄ΠΈΠ»ΠΈ Π³Ρ€ΡƒΠΏΠΏΠΈΡ€ΠΎΠ²ΠΊΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½Π΅ Π΄ΠΎ ΠΊΠΎΠ½Ρ†Π° освСдомлСны ΠΎ возмоТностях ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π° ΠΈΠ»ΠΈ Π½Π΅ ΠΈΠΌΠ΅ΡŽΡ‚ тСхничСских срСдств для Π΅Π³ΠΎ использования Π² ΠΏΠΎΠ»Π½ΡƒΡŽ силу. По ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ZeroBS GmbH, послСдниС Π°Ρ‚Π°ΠΊΠΈ достигали максимум 40 Π“Π±ΠΈΡ‚/с ΠΈ коэффициСнтом усилСния Π½Π΅ Π±ΠΎΠ»Π΅Π΅ 10. Для этих Π°Ρ‚Π°ΠΊ использовалось всСго порядка 5000 устройств (Π² основном IP-ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ ΠΈ ΠΏΡ€ΠΈΠ½Ρ‚Π΅Ρ€Ρ‹), входящих Π² Π±ΠΎΡ‚Π½Π΅Ρ‚Ρ‹.

Π”Π°Π½Π½Ρ‹Π΅ ZeroBS GmbH

ЭкспСрты ΠΏΡ€Π΅Π΄ΡƒΠΏΡ€Π΅ΠΆΠ΄Π°ΡŽΡ‚, Ρ‡Ρ‚ΠΎ Π² настоящСС врСмя DDoS-Π°Ρ‚Π°ΠΊΠΈ с ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ΠΌ WS-Discovery Π΅Ρ‰Π΅ Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ Π΅ΠΆΠ΅Π΄Π½Π΅Π²Π½ΠΎ ΠΈ Π² ΠΏΠΎΠ»Π½ΡƒΡŽ силу. Пока Π·Π»ΠΎΡƒΠΌΡ‹ΡˆΠ»Π΅Π½Π½ΠΈΠΊΠΈ ΡΠΊΡΠΏΠ»ΡƒΠ°Ρ‚ΠΈΡ€ΡƒΡŽΡ‚ возмоТности Ρ‚ΠΎΠ»ΡŒΠΊΠΎ нСбольшой части WS-Discovery-устройств, доступных Π² сСти, ΠΈ Π΄ΠΎΠ±ΠΈΠ²Π°ΡŽΡ‚ΡΡ вСсьма Π½Π΅Π±ΠΎΠ»ΡŒΡˆΠΈΡ… коэффициСнтов Π°ΠΌΠΏΠ»ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ. Однако ΡƒΠΆΠ΅ Π² блиТайшиС мСсяцы этот ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» ΠΌΠΎΠΆΠ΅Ρ‚ ΡΡ‚Π°Ρ‚ΡŒ Π»ΡŽΠ±ΠΈΠΌΡ‹ΠΌ инструмСнтом ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠ² Π±ΠΎΡ‚Π½Π΅Ρ‚ΠΎΠ², ΠΈ ситуация сущСствСнно ΡƒΡ…ΡƒΠ΄ΡˆΠΈΡ‚ΡΡ.

ΠžΠ±Π·ΠΎΡ€ способов ΠΈ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»ΠΎΠ² Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ Π² Π²Π΅Π±-прилоТСниях

Π― расскаТу ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠΈ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… способов Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ для Π²Π΅Π±-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ, Π²ΠΊΠ»ΡŽΡ‡Π°Ρ Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΡŽ ΠΏΠΎ ΠΏΠ°Ρ€ΠΎΠ»ΡŽ, ΠΏΠΎ сСртификатам, ΠΏΠΎ ΠΎΠ΄Π½ΠΎΡ€Π°Π·ΠΎΠ²Ρ‹ΠΌ паролям, ΠΏΠΎ ΠΊΠ»ΡŽΡ‡Π°ΠΌ доступа ΠΈ ΠΏΠΎ Ρ‚ΠΎΠΊΠ΅Π½Π°ΠΌ. ΠšΠΎΡΠ½ΡƒΡΡŒ Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈ Π΅Π΄ΠΈΠ½ΠΎΠ³ΠΎ Π²Ρ…ΠΎΠ΄Π° (Single Sign-On), Ρ€Π°ΡΡΠΌΠΎΡ‚Ρ€ΡŽ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ стандарты ΠΈ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Ρ‹ Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ.

ΠŸΠ΅Ρ€Π΅Π΄ Ρ‚Π΅ΠΌ, ΠΊΠ°ΠΊ ΠΏΠ΅Ρ€Π΅ΠΉΡ‚ΠΈ ΠΊ тСхничСским дСталям, Π΄Π°Π²Π°ΠΉΡ‚Π΅ Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ освСТим Ρ‚Π΅Ρ€ΠΌΠΈΠ½ΠΎΠ»ΠΎΠ³ΠΈΡŽ.

  • Π˜Π΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΡ β€” это заявлСниС ΠΎ Ρ‚ΠΎΠΌ, ΠΊΠ΅ΠΌ Π²Ρ‹ ΡΠ²Π»ΡΠ΅Ρ‚Π΅ΡΡŒ. Π’ зависимости ΠΎΡ‚ ситуации, это ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ имя, адрСс элСктронной ΠΏΠΎΡ‡Ρ‚Ρ‹, Π½ΠΎΠΌΠ΅Ρ€ ΡƒΡ‡Π΅Ρ‚Π½ΠΎΠΉ записи, ΠΈΡ‚Π΄.
  • АутСнтификация β€” прСдоставлСниС Π΄ΠΎΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒΡΡ‚Π², Ρ‡Ρ‚ΠΎ Π²Ρ‹ Π½Π° самом Π΄Π΅Π»Π΅ Π΅ΡΡ‚ΡŒ Ρ‚ΠΎΡ‚, ΠΊΠ΅ΠΌ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Π»ΠΈΡΡŒ (ΠΎΡ‚ слова β€œauthentic” β€” истинный, ΠΏΠΎΠ΄Π»ΠΈΠ½Π½Ρ‹ΠΉ).
  • Авторизация β€” ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ°, Ρ‡Ρ‚ΠΎ Π²Π°ΠΌ Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½ доступ ΠΊ Π·Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°Π΅ΠΌΠΎΠΌΡƒ рСсурсу.

НапримСр, ΠΏΡ€ΠΈ ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠ΅ ΠΏΠΎΠΏΠ°ΡΡ‚ΡŒ Π² Π·Π°ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΉ ΠΊΠ»ΡƒΠ± вас ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΡ†ΠΈΡ€ΡƒΡŽΡ‚ (спросят вашС имя ΠΈ Ρ„Π°ΠΌΠΈΠ»ΠΈΡŽ), Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΡ†ΠΈΡ€ΡƒΡŽΡ‚ (попросят ΠΏΠΎΠΊΠ°Π·Π°Ρ‚ΡŒ паспорт ΠΈ свСрят Ρ„ΠΎΡ‚ΠΎΠ³Ρ€Π°Ρ„ΠΈΡŽ) ΠΈ Π°Π²Ρ‚ΠΎΡ€ΠΈΠ·ΡƒΡŽΡ‚ (провСрят, Ρ‡Ρ‚ΠΎ фамилия находится Π² спискС гостСй), ΠΏΡ€Π΅ΠΆΠ΄Π΅ Ρ‡Π΅ΠΌ пустят Π²Π½ΡƒΡ‚Ρ€ΡŒ.

Аналогично эти Ρ‚Π΅Ρ€ΠΌΠΈΠ½Ρ‹ ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡŽΡ‚ΡΡ Π² ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€Π½Ρ‹Ρ… систСмах, Π³Π΄Π΅ Ρ‚Ρ€Π°Π΄ΠΈΡ†ΠΈΠΎΠ½Π½ΠΎ ΠΏΠΎΠ΄ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠ΅ΠΉ ΠΏΠΎΠ½ΠΈΠΌΠ°ΡŽΡ‚ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ вашСй ΡƒΡ‡Π΅Ρ‚Π½ΠΎΠΉ записи (identity) ΠΏΠΎ username ΠΈΠ»ΠΈ email; ΠΏΠΎΠ΄ Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠ΅ΠΉ β€” ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΡƒ, Ρ‡Ρ‚ΠΎ Π²Ρ‹ Π·Π½Π°Π΅Ρ‚Π΅ ΠΏΠ°Ρ€ΠΎΠ»ΡŒ ΠΎΡ‚ этой ΡƒΡ‡Π΅Ρ‚Π½ΠΎΠΉ записи, Π° ΠΏΠΎΠ΄ Π°Π²Ρ‚ΠΎΡ€ΠΈΠ·Π°Ρ†ΠΈΠ΅ΠΉ β€” ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΡƒ вашСй Ρ€ΠΎΠ»ΠΈ Π² систСмС ΠΈ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ ΠΎ прСдоставлСнии доступа ΠΊ Π·Π°ΠΏΡ€ΠΎΡˆΠ΅Π½Π½ΠΎΠΉ страницС ΠΈΠ»ΠΈ рСсурсу.

Однако Π² соврСмСнных систСмах ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‚ ΠΈ Π±ΠΎΠ»Π΅Π΅ слоТныС схСмы Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΈ Π°Π²Ρ‚ΠΎΡ€ΠΈΠ·Π°Ρ†ΠΈΠΈ, ΠΎ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… я расскаТу Π΄Π°Π»Π΅Π΅. Но Π½Π°Ρ‡Π½Π΅ΠΌ с простого ΠΈ понятного.

АутСнтификация ΠΏΠΎ ΠΏΠ°Ρ€ΠΎΠ»ΡŽ

Π­Ρ‚ΠΎΡ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄ основываСтся Π½Π° Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ username ΠΈ password для ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠΉ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΈ Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ Π² систСмС. ΠŸΠ°Ρ€Π° username/password задаСтся ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΌ ΠΏΡ€ΠΈ Π΅Π³ΠΎ рСгистрации Π² систСмС, ΠΏΡ€ΠΈ этом Π² качСствС username ΠΌΠΎΠΆΠ΅Ρ‚ Π²Ρ‹ΡΡ‚ΡƒΠΏΠ°Ρ‚ΡŒ адрСс элСктронной ΠΏΠΎΡ‡Ρ‚Ρ‹ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ.

ΠŸΡ€ΠΈΠΌΠ΅Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΊ Π²Π΅Π±-прилоТСниям, сущСствуСт нСсколько стандартных ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»ΠΎΠ² для Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΏΠΎ ΠΏΠ°Ρ€ΠΎΠ»ΡŽ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΡ‹ рассмотрим Π½ΠΈΠΆΠ΅.

HTTP authentication

Π­Ρ‚ΠΎΡ‚ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ», описанный Π² стандартах HTTP 1.0/1.1, сущСствуСт ΠΎΡ‡Π΅Π½ΡŒ Π΄Π°Π²Π½ΠΎ ΠΈ Π΄ΠΎ сих ΠΏΠΎΡ€ Π°ΠΊΡ‚ΠΈΠ²Π½ΠΎ примСняСтся Π² ΠΊΠΎΡ€ΠΏΠΎΡ€Π°Ρ‚ΠΈΠ²Π½ΠΎΠΉ срСдС. ΠŸΡ€ΠΈΠΌΠ΅Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΊ Π²Π΅Π±-сайтам Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ:

  1. Π‘Π΅Ρ€Π²Π΅Ρ€, ΠΏΡ€ΠΈ ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠΈ Π½Π΅Π°Π²Ρ‚ΠΎΡ€ΠΈΠ·ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° ΠΊ Π·Π°Ρ‰ΠΈΡ‰Π΅Π½Π½ΠΎΠΌΡƒ рСсурсу, отсылаСт HTTP статус β€œ401 Unauthorized” ΠΈ добавляСт Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ β€œWWW-Authenticate” с ΡƒΠΊΠ°Π·Π°Π½ΠΈΠ΅ΠΌ схСмы ΠΈ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ.
  2. Π‘Ρ€Π°ΡƒΠ·Π΅Ρ€, ΠΏΡ€ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠΈ Ρ‚Π°ΠΊΠΎΠ³ΠΎ ΠΎΡ‚Π²Π΅Ρ‚Π°, автоматичСски ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ Π΄ΠΈΠ°Π»ΠΎΠ³ Π²Π²ΠΎΠ΄Π° username ΠΈ password. ΠŸΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ Π²Π²ΠΎΠ΄ΠΈΡ‚ Π΄Π΅Ρ‚Π°Π»ΠΈ своСй ΡƒΡ‡Π΅Ρ‚Π½ΠΎΠΉ записи.
  3. Π’ΠΎ всСх ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΡ… запросах ΠΊ этому Π²Π΅Π±-сайту Π±Ρ€Π°ΡƒΠ·Π΅Ρ€ автоматичСски добавляСт HTTP Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ β€œAuthorization”, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ ΠΏΠ΅Ρ€Π΅Π΄Π°ΡŽΡ‚ΡΡ Π΄Π°Π½Π½Ρ‹Π΅ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ для Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ сСрвСром.
  4. Π‘Π΅Ρ€Π²Π΅Ρ€ Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΡ†ΠΈΡ€ΡƒΠ΅Ρ‚ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ ΠΏΠΎ Π΄Π°Π½Π½Ρ‹ΠΌ ΠΈΠ· этого Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ°. РСшСниС ΠΎ прСдоставлСнии доступа (авторизация) производится ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎ Π½Π° основании Ρ€ΠΎΠ»ΠΈ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ, ACL ΠΈΠ»ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΡ… Π΄Π°Π½Π½Ρ‹Ρ… ΡƒΡ‡Π΅Ρ‚Π½ΠΎΠΉ записи.

Π’Π΅ΡΡŒ процСсс стандартизирован ΠΈ Ρ…ΠΎΡ€ΠΎΡˆΠΎ поддСрТиваСтся всСми Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π°ΠΌΠΈ ΠΈ Π²Π΅Π±-сСрвСрами. БущСствуСт нСсколько схСм Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ, ΠΎΡ‚Π»ΠΈΡ‡Π°ΡŽΡ‰ΠΈΡ…ΡΡ ΠΏΠΎ ΡƒΡ€ΠΎΠ²Π½ΡŽ бСзопасности:

  1. Basic β€” Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ простая схСма, ΠΏΡ€ΠΈ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ username ΠΈ password ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ ΠΏΠ΅Ρ€Π΅Π΄Π°ΡŽΡ‚ΡΡ Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ΅ Authorization Π² Π½Π΅Π·Π°ΡˆΠΈΡ„Ρ€ΠΎΠ²Π°Π½Π½ΠΎΠΌ Π²ΠΈΠ΄Π΅ (base64-encoded). Однако ΠΏΡ€ΠΈ использовании HTTPS (HTTP over SSL) ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π°, являСтся ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ бСзопасной.

    ΠŸΡ€ΠΈΠΌΠ΅Ρ€ HTTP Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ с использованиСм Basic схСмы.

  2. Digest β€” challenge-response-схСма, ΠΏΡ€ΠΈ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ сСрвСр посылаСт ΡƒΠ½ΠΈΠΊΠ°Π»ΡŒΠ½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ nonce, Π° Π±Ρ€Π°ΡƒΠ·Π΅Ρ€ ΠΏΠ΅Ρ€Π΅Π΄Π°Π΅Ρ‚ MD5 Ρ…ΡΡˆ пароля ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ, вычислСнный с использованиСм ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠ³ΠΎ nonce. Π‘ΠΎΠ»Π΅Π΅ бСзопасная Π°Π»ΡŒΡ‚Π΅Ρ€Π½Π°Ρ‚ΠΈΠ²Π² Basic схСмы ΠΏΡ€ΠΈ Π½Π΅Π·Π°Ρ‰ΠΈΡ‰Π΅Π½Π½Ρ‹Ρ… соСдинСниях, Π½ΠΎ ΠΏΠΎΠ΄Π²Π΅Ρ€ΠΆΠ΅Π½Π° man-in-the-middle attacks (с Π·Π°ΠΌΠ΅Π½ΠΎΠΉ схСмы Π½Π° basic). ΠšΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, использованиС этой схСмы Π½Π΅ позволяСт ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΡ‚ΡŒ соврСмСнныС Ρ…ΡΡˆ-Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ для хранСния ΠΏΠ°Ρ€ΠΎΠ»Π΅ΠΉ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ Π½Π° сСрвСрС.
  3. NTLM (извСстная ΠΊΠ°ΠΊ Windows authentication) β€” Ρ‚Π°ΠΊΠΆΠ΅ основана Π½Π° challenge-response ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Π΅, ΠΏΡ€ΠΈ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ ΠΏΠ°Ρ€ΠΎΠ»ΡŒ Π½Π΅ пСрСдаСтся Π² чистом Π²ΠΈΠ΄Π΅. Π­Ρ‚Π° схСма Π½Π΅ являСтся стандартом HTTP, Π½ΠΎ поддСрТиваСтся Π±ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²ΠΎΠΌ Π±Ρ€Π°ΡƒΠ·Π΅Ρ€ΠΎΠ² ΠΈ Π²Π΅Π±-сСрвСров. ΠŸΡ€Π΅ΠΈΠΌΡƒΡ‰Π΅ΡΡ‚Π²Π΅Π½Π½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ Windows Active Directory Π² Π²Π΅Π±-прилоТСниях. Уязвима ΠΊ pass-the-hash-Π°Ρ‚Π°ΠΊΠ°ΠΌ.
  4. Negotiate β€” Π΅Ρ‰Π΅ ΠΎΠ΄Π½Π° схСма ΠΈΠ· сСмСйства Windows authentication, которая позволяСт ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ Π²Ρ‹Π±Ρ€Π°Ρ‚ΡŒ ΠΌΠ΅ΠΆΠ΄Ρƒ NTLM ΠΈ Kerberos Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠ΅ΠΉ. Kerberos β€” Π±ΠΎΠ»Π΅Π΅ бСзопасный ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ», основанный Π½Π° ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΠ΅ Single Sign-On. Однако ΠΎΠ½ ΠΌΠΎΠΆΠ΅Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ, Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ссли ΠΈ ΠΊΠ»ΠΈΠ΅Π½Ρ‚, ΠΈ сСрвСр находятся Π² Π·ΠΎΠ½Π΅ intranet ΠΈ ΡΠ²Π»ΡΡŽΡ‚ΡΡ Ρ‡Π°ΡΡ‚ΡŒΡŽ Π΄ΠΎΠΌΠ΅Π½Π° Windows.

Π‘Ρ‚ΠΎΠΈΡ‚ ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΈ использовании HTTP-Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ Ρƒ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ Π½Π΅Ρ‚ стандартной возмоТности Π²Ρ‹ΠΉΡ‚ΠΈ ΠΈΠ· Π²Π΅Π±-прилоТСния, ΠΊΡ€ΠΎΠΌΠ΅ ΠΊΠ°ΠΊ Π·Π°ΠΊΡ€Ρ‹Ρ‚ΡŒ всС ΠΎΠΊΠ½Π° Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π°.

Forms authentication

Для этого ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π° Π½Π΅Ρ‚ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ³ΠΎ стандарта, поэтому всС Π΅Π³ΠΎ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ спСцифичны для ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½Ρ‹Ρ… систСм, Π° Ρ‚ΠΎΡ‡Π½Π΅Π΅, для ΠΌΠΎΠ΄ΡƒΠ»Π΅ΠΉ Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΠΎΠ² Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ.

Π Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ это ΠΏΠΎ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌΡƒ ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΡƒ: Π² Π²Π΅Π±-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ HTML-Ρ„ΠΎΡ€ΠΌΠ°, Π² ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ Π΄ΠΎΠ»ΠΆΠ΅Π½ ввСсти свои username/password ΠΈ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ ΠΈΡ… Π½Π° сСрвСр Ρ‡Π΅Ρ€Π΅Π· HTTP POST для Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ. Π’ случаС успСха Π²Π΅Π±-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ создаСт session token, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ помСщаСтся Π² browser cookies. ΠŸΡ€ΠΈ ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΡ… Π²Π΅Π±-запросах session token автоматичСски пСрСдаСтся Π½Π° сСрвСр ΠΈ позволяСт ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡŽ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎ Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΌ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ для Π°Π²Ρ‚ΠΎΡ€ΠΈΠ·Π°Ρ†ΠΈΠΈ запроса.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ forms authentication.

ΠŸΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ session token двумя способами:

  1. Как ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠΉ сСссии ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ, которая хранится Π² памяти сСрвСра ΠΈΠ»ΠΈ Π² Π±Π°Π·Π΅ Π΄Π°Π½Π½Ρ‹Ρ…. БСссия Π΄ΠΎΠ»ΠΆΠ½Π° ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ всю Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡƒΡŽ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ для возмоТности Π°Π²Ρ‚ΠΎΡ€ΠΈΠ·Π°Ρ†ΠΈΠΈ Π΅Π³ΠΎ запросов.
  2. Как Π·Π°ΡˆΠΈΡ„Ρ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ ΠΈ/ΠΈΠ»ΠΈ подписанный ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, содСрТащий Π΄Π°Π½Π½Ρ‹Π΅ ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅, Π° Ρ‚Π°ΠΊΠΆΠ΅ ΠΏΠ΅Ρ€ΠΈΠΎΠ΄ дСйствия. Π­Ρ‚ΠΎΡ‚ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ позволяСт Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ stateless-Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Ρƒ сСрвСра, ΠΎΠ΄Π½Π°ΠΊΠΎ Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠ° обновлСния сСссионного Ρ‚ΠΎΠΊΠ΅Π½Π° ΠΏΠΎ истСчСнии срока дСйствия. НСсколько стандартных Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ΠΎΠ² Ρ‚Π°ΠΊΠΈΡ… Ρ‚ΠΎΠΊΠ΅Π½ΠΎΠ² Ρ€Π°ΡΡΠΌΠ°Ρ‚Ρ€ΠΈΠ²Π°ΡŽΡ‚ΡΡ Π² сСкции «АутСнтификация ΠΏΠΎ Ρ‚ΠΎΠΊΠ΅Π½Π°ΠΌΒ».

НСобходимо ΠΏΠΎΠ½ΠΈΠΌΠ°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΏΠ΅Ρ€Π΅Ρ…Π²Π°Ρ‚ session token Π·Π°Ρ‡Π°ΡΡ‚ΡƒΡŽ Π΄Π°Π΅Ρ‚ Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½Ρ‹ΠΉ ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ доступа, Ρ‡Ρ‚ΠΎ ΠΈ Π·Π½Π°Π½ΠΈΠ΅ username/password. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ всС ΠΊΠΎΠΌΠΌΡƒΠ½ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ ΠΈ сСрвСром Π² случаС forms authentication Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚ΡŒΡΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΠΎ Π·Π°Ρ‰ΠΈΡ‰Π΅Π½Π½ΠΎΠΌΡƒ соСдинСнию HTTPS.

Π”Ρ€ΡƒΠ³ΠΈΠ΅ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Ρ‹ Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΏΠΎ ΠΏΠ°Ρ€ΠΎΠ»ΡŽ

Π”Π²Π° ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π°, описанных Π²Ρ‹ΡˆΠ΅, ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ для Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ Π½Π° Π²Π΅Π±-сайтах. Но ΠΏΡ€ΠΈ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅ ΠΊΠ»ΠΈΠ΅Π½Ρ‚-сСрвСрных ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ с использованиСм Π²Π΅Π±-сСрвисов (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, iOS ΠΈΠ»ΠΈ Android), наряду с HTTP Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠ΅ΠΉ, часто ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡŽΡ‚ΡΡ нСстандартныС ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Ρ‹, Π² ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Π΅ для Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°ΡŽΡ‚ΡΡ Π² Π΄Ρ€ΡƒΠ³ΠΈΡ… частях запроса.

БущСствуСт всСго нСсколько мСст, Π³Π΄Π΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ username ΠΈ password Π² HTTP запросах:

  1. URL query β€” считаСтся нСбСзопасным Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ΠΎΠΌ, Ρ‚. ΠΊ. строки URL ΠΌΠΎΠ³ΡƒΡ‚ Π·Π°ΠΏΠΎΠΌΠΈΠ½Π°Ρ‚ΡŒΡΡ Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π°ΠΌΠΈ, прокси ΠΈ Π²Π΅Π±-сСрвСрами.
  2. Request body β€” бСзопасный Π²Π°Ρ€ΠΈΠ°Π½Ρ‚, Π½ΠΎ ΠΎΠ½ ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΠΌ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для запросов, содСрТащих Ρ‚Π΅Π»ΠΎ сообщСния (Ρ‚Π°ΠΊΠΈΠ΅ ΠΊΠ°ΠΊ POST, PUT, PATCH).
  3. HTTP header β€”ΠΎΠΏΡ‚ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚, ΠΏΡ€ΠΈ этом ΠΌΠΎΠ³ΡƒΡ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ ΠΈ стандартный Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ Authorization (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, с Basic-схСмой), ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½Ρ‹Π΅ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ.
РаспространСнныС уязвимости ΠΈ ошибки Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ

АутСнтификации ΠΏΠΎ ΠΏΠ°Ρ€ΠΎΠ»ΡŽ считаСтся Π½Π΅ ΠΎΡ‡Π΅Π½ΡŒ Π½Π°Π΄Π΅ΠΆΠ½Ρ‹ΠΌ способом, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ ΠΏΠ°Ρ€ΠΎΠ»ΡŒ часто ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ΄ΠΎΠ±Ρ€Π°Ρ‚ΡŒ, Π° ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΠΈ склонны ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ простыС ΠΈ ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²Ρ‹Π΅ ΠΏΠ°Ρ€ΠΎΠ»ΠΈ Π² Ρ€Π°Π·Π½Ρ‹Ρ… систСмах, Π»ΠΈΠ±ΠΎ Π·Π°ΠΏΠΈΡΡ‹Π²Π°Ρ‚ΡŒ ΠΈΡ… Π½Π° ΠΊΠ»ΠΎΡ‡ΠΊΠ°Ρ… Π±ΡƒΠΌΠ°Π³ΠΈ. Если Π·Π»ΠΎΡƒΠΌΡ‹ΡˆΠ»Π΅Π½Π½ΠΈΠΊ смог Π²Ρ‹ΡΡΠ½ΠΈΡ‚ΡŒ ΠΏΠ°Ρ€ΠΎΠ»ΡŒ, Ρ‚ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ Π·Π°Ρ‡Π°ΡΡ‚ΡƒΡŽ ΠΎΠ± этом Π½Π΅ ΡƒΠ·Π½Π°Π΅Ρ‚. ΠšΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ ΠΌΠΎΠ³ΡƒΡ‚ Π΄ΠΎΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ ряд ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹Ρ… ошибок, ΡƒΠΏΡ€ΠΎΡ‰Π°ΡŽΡ‰ΠΈΡ… Π²Π·Π»ΠΎΠΌ ΡƒΡ‡Π΅Ρ‚Π½Ρ‹Ρ… записСй.

НиТС прСдставлСн список Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ часто Π²ΡΡ‚Ρ€Π΅Ρ‡Π°ΡŽΡ‰ΠΈΡ…ΡΡ уязвимостСй Π² случаС использования Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΏΠΎ ΠΏΠ°Ρ€ΠΎΠ»ΡŽ:

  • Π’Π΅Π±-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ позволяСт ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡΠΌ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ простыС ΠΏΠ°Ρ€ΠΎΠ»ΠΈ.
  • Π’Π΅Π±-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π½Π΅ Π·Π°Ρ‰ΠΈΡ‰Π΅Π½ΠΎ ΠΎΡ‚ возмоТности ΠΏΠ΅Ρ€Π΅Π±ΠΎΡ€Π° ΠΏΠ°Ρ€ΠΎΠ»Π΅ΠΉ (brute-force attacks).
  • Π’Π΅Π±-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ само Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ ΠΈ распространяСт ΠΏΠ°Ρ€ΠΎΠ»ΠΈ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡΠΌ, ΠΎΠ΄Π½Π°ΠΊΠΎ Π½Π΅ Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ смСны пароля послС ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ Π²Ρ…ΠΎΠ΄Π° (Ρ‚.Π΅. Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ ΠΏΠ°Ρ€ΠΎΠ»ΡŒ Π³Π΄Π΅-Ρ‚ΠΎ записан).
  • Π’Π΅Π±-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ допускаСт ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Ρƒ ΠΏΠ°Ρ€ΠΎΠ»Π΅ΠΉ ΠΏΠΎ Π½Π΅Π·Π°Ρ‰ΠΈΡ‰Π΅Π½Π½ΠΎΠΌΡƒ HTTP-соСдинСнию, Π»ΠΈΠ±ΠΎ Π² строкС URL.
  • Π’Π΅Π±-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ бСзопасныС Ρ…ΡΡˆ-Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ для хранСния ΠΏΠ°Ρ€ΠΎΠ»Π΅ΠΉ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ.
  • Π’Π΅Π±-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π½Π΅ прСдоставляСт ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡΠΌ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ измСнСния пароля Π»ΠΈΠ±ΠΎ Π½Π΅ Π½ΠΎΡ‚ΠΈΡ„ΠΈΡ†ΠΈΡ€ΡƒΠ΅Ρ‚ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ ΠΎΠ± ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΈ ΠΈΡ… ΠΏΠ°Ρ€ΠΎΠ»Π΅ΠΉ.
  • Π’Π΅Π±-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ ΡƒΡΠ·Π²ΠΈΠΌΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ восстановлСния пароля, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ для получСния нСсанкционированного доступа ΠΊ Π΄Ρ€ΡƒΠ³ΠΈΠΌ ΡƒΡ‡Π΅Ρ‚Π½Ρ‹ΠΌ записям.
  • Π’Π΅Π±-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π½Π΅ Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎΠΉ Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ для Π²Π°ΠΆΠ½Ρ‹Ρ… дСйствий: смСна пароля, измСнСния адрСса доставки Ρ‚ΠΎΠ²Π°Ρ€ΠΎΠ² ΠΈ Ρ‚. ΠΏ.
  • Π’Π΅Π±-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ создаСт session tokens Ρ‚Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΎΠ½ΠΈ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ ΠΏΠΎΠ΄ΠΎΠ±Ρ€Π°Π½Ρ‹ ΠΈΠ»ΠΈ прСдсказаны для Π΄Ρ€ΡƒΠ³ΠΈΡ… ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ.
  • Π’Π΅Π±-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ допускаСт ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Ρƒ session tokens ΠΏΠΎ Π½Π΅Π·Π°Ρ‰ΠΈΡ‰Π΅Π½Π½ΠΎΠΌΡƒ HTTP-соСдинСнию, Π»ΠΈΠ±ΠΎ Π² строкС URL.
  • Π’Π΅Π±-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ уязвимо для session fixation-Π°Ρ‚Π°ΠΊ (Ρ‚. Π΅. Π½Π΅ замСняСт session token ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄Π΅ Π°Π½ΠΎΠ½ΠΈΠΌΠ½ΠΎΠΉ сСссии ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ Π² Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Π½Π½ΡƒΡŽ).
  • Π’Π΅Π±-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π½Π΅ устанавливаСт Ρ„Π»Π°Π³ΠΈ HttpOnly ΠΈ Secure для browser cookies, содСрТащих session tokens.
  • Π’Π΅Π±-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π½Π΅ ΡƒΠ½ΠΈΡ‡Ρ‚ΠΎΠΆΠ°Π΅Ρ‚ сСссии ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ послС ΠΊΠΎΡ€ΠΎΡ‚ΠΊΠΎΠ³ΠΎ ΠΏΠ΅Ρ€ΠΈΠΎΠ΄Π° нСактивности Π»ΠΈΠ±ΠΎ Π½Π΅ прСдоставляСт Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ Π²Ρ‹Ρ…ΠΎΠ΄Π° ΠΈΠ· Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠΉ сСссии.
АутСнтификация ΠΏΠΎ сСртификатам

Π‘Π΅Ρ€Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ прСдставляСт собой Π½Π°Π±ΠΎΡ€ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ΠΎΠ², ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΡ†ΠΈΡ€ΡƒΡŽΡ‰ΠΈΡ… Π²Π»Π°Π΄Π΅Π»ΡŒΡ†Π°, подписанный certificate authority (CA). CA выступаСт Π² Ρ€ΠΎΠ»ΠΈ посрСдника, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚ ΠΏΠΎΠ΄Π»ΠΈΠ½Π½ΠΎΡΡ‚ΡŒ сСртификатов (ΠΏΠΎ Π°Π½Π°Π»ΠΎΠ³ΠΈΠΈ с ЀМБ, Π²Ρ‹ΠΏΡƒΡΠΊΠ°ΡŽΡ‰Π΅ΠΉ паспорта). Π’Π°ΠΊΠΆΠ΅ сСртификат криптографичСски связан с Π·Π°ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΌ ΠΊΠ»ΡŽΡ‡ΠΎΠΌ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ хранится Ρƒ Π²Π»Π°Π΄Π΅Π»ΡŒΡ†Π° сСртификата ΠΈ позволяСт ΠΎΠ΄Π½ΠΎΠ·Π½Π°Ρ‡Π½ΠΎ ΠΏΠΎΠ΄Ρ‚Π²Π΅Ρ€Π΄ΠΈΡ‚ΡŒ Ρ„Π°ΠΊΡ‚ владСния сСртификатом.

На сторонС ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° сСртификат вмСстС с Π·Π°ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΌ ΠΊΠ»ΡŽΡ‡ΠΎΠΌ ΠΌΠΎΠ³ΡƒΡ‚ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒΡΡ Π² ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΎΠΉ систСмС, Π² Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π΅, Π² Ρ„Π°ΠΉΠ»Π΅, Π½Π° ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠΌ физичСском устройствС (smart card, USB token). ΠžΠ±Ρ‹Ρ‡Π½ΠΎ Π·Π°ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΉ ΠΊΠ»ΡŽΡ‡ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π·Π°Ρ‰ΠΈΡ‰Π΅Π½ ΠΏΠ°Ρ€ΠΎΠ»Π΅ΠΌ ΠΈΠ»ΠΈ PIN-ΠΊΠΎΠ΄ΠΎΠΌ.

Π’ Π²Π΅Π±-прилоТСниях Ρ‚Ρ€Π°Π΄ΠΈΡ†ΠΈΠΎΠ½Π½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ сСртификаты стандарта X.509. АутСнтификация с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ X.509-сСртификата происходит Π² ΠΌΠΎΠΌΠ΅Π½Ρ‚ соСдинСния с сСрвСром ΠΈ являСтся Ρ‡Π°ΡΡ‚ΡŒΡŽ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π° SSL/TLS. Π­Ρ‚ΠΎΡ‚ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ Ρ‚Π°ΠΊΠΆΠ΅ Ρ…ΠΎΡ€ΠΎΡˆΠΎ поддСрТиваСтся Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π°ΠΌΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŽ Π²Ρ‹Π±Ρ€Π°Ρ‚ΡŒ ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΡ‚ΡŒ сСртификат, Ссли Π²Π΅Π±-сайт допускаСт Ρ‚Π°ΠΊΠΎΠΉ способ Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ.

ИспользованиС сСртификата для Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ.

Π’ΠΎ врСмя Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ сСрвСр выполняСт ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΡƒ сСртификата Π½Π° основании ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΡ… ΠΏΡ€Π°Π²ΠΈΠ»:

  1. Π‘Π΅Ρ€Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ подписан Π΄ΠΎΠ²Π΅Ρ€Π΅Π½Π½Ρ‹ΠΌ certification authority (ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠΈ сСртификатов).
  2. Π‘Π΅Ρ€Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ Π½Π° Ρ‚Π΅ΠΊΡƒΡ‰ΡƒΡŽ Π΄Π°Ρ‚Ρƒ (ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° срока дСйствия).
  3. Π‘Π΅Ρ€Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ Π½Π΅ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ ΠΎΡ‚ΠΎΠ·Π²Π°Π½ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΌ CA (ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° списков ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ).

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ X.509 сСртификата.

ПослС ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠΉ Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ Π²Π΅Π±-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ Π°Π²Ρ‚ΠΎΡ€ΠΈΠ·Π°Ρ†ΠΈΡŽ запроса Π½Π° основании Ρ‚Π°ΠΊΠΈΡ… Π΄Π°Π½Π½Ρ‹Ρ… сСртификата, ΠΊΠ°ΠΊ subject (имя Π²Π»Π°Π΄Π΅Π»ΡŒΡ†Π°), issuer (эмитСнт), serial number (сСрийный Π½ΠΎΠΌΠ΅Ρ€ сСртификата) ΠΈΠ»ΠΈ thumbprint (ΠΎΡ‚ΠΏΠ΅Ρ‡Π°Ρ‚ΠΎΠΊ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΎΠ³ΠΎ ΠΊΠ»ΡŽΡ‡Π° сСртификата).

ИспользованиС сСртификатов для Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ β€” ΠΊΡƒΠ΄Π° Π±ΠΎΠ»Π΅Π΅ Π½Π°Π΄Π΅ΠΆΠ½Ρ‹ΠΉ способ, Ρ‡Π΅ΠΌ аутСнтификация посрСдством ΠΏΠ°Ρ€ΠΎΠ»Π΅ΠΉ. Π­Ρ‚ΠΎ достигаСтся созданиСм Π² процСссС Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ Ρ†ΠΈΡ„Ρ€ΠΎΠ²ΠΎΠΉ подписи, Π½Π°Π»ΠΈΡ‡ΠΈΠ΅ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ Π΄ΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ Ρ„Π°ΠΊΡ‚ примСнСния Π·Π°ΠΊΡ€Ρ‹Ρ‚ΠΎΠ³ΠΎ ΠΊΠ»ΡŽΡ‡Π° Π² ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠΉ ситуации (non-repudiation). Однако трудности с распространСниСм ΠΈ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΎΠΉ сСртификатов Π΄Π΅Π»Π°Π΅Ρ‚ Ρ‚Π°ΠΊΠΎΠΉ способ Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ малодоступным Π² ΡˆΠΈΡ€ΠΎΠΊΠΈΡ… ΠΊΡ€ΡƒΠ³Π°Ρ….

АутСнтификация ΠΏΠΎ ΠΎΠ΄Π½ΠΎΡ€Π°Π·ΠΎΠ²Ρ‹ΠΌ паролям

АутСнтификация ΠΏΠΎ ΠΎΠ΄Π½ΠΎΡ€Π°Π·ΠΎΠ²Ρ‹ΠΌ паролям ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ примСняСтся Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΊ Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΏΠΎ паролям для Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ two-factor authentication (2FA). Π’ этой ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ†ΠΈΠΈ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŽ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ Π΄Π²ΡƒΡ… Ρ‚ΠΈΠΏΠΎΠ² для Π²Ρ…ΠΎΠ΄Π° Π² систСму: Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ ΠΎΠ½ Π·Π½Π°Π΅Ρ‚ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΏΠ°Ρ€ΠΎΠ»ΡŒ), ΠΈ Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ, Ρ‡Π΅ΠΌ ΠΎΠ½ Π²Π»Π°Π΄Π΅Π΅Ρ‚ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, устройство для Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ ΠΎΠ΄Π½ΠΎΡ€Π°Π·ΠΎΠ²Ρ‹Ρ… ΠΏΠ°Ρ€ΠΎΠ»Π΅ΠΉ). НаличиС Π΄Π²ΡƒΡ… Ρ„Π°ΠΊΡ‚ΠΎΡ€ΠΎΠ² позволяСт Π² Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΉ стСпСни ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΡ‚ΡŒ ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ бСзопасности, Ρ‡Ρ‚ΠΎ ΠΌ. Π±. вострСбовано для ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹Ρ… Π²ΠΈΠ΄ΠΎΠ² Π²Π΅Π±-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ.

Π”Ρ€ΡƒΠ³ΠΎΠΉ популярный сцСнарий использования ΠΎΠ΄Π½ΠΎΡ€Π°Π·ΠΎΠ²Ρ‹Ρ… ΠΏΠ°Ρ€ΠΎΠ»Π΅ΠΉ β€” Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Π°Ρ аутСнтификация ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ Π²ΠΎ врСмя выполнСния Π²Π°ΠΆΠ½Ρ‹Ρ… дСйствий: ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄ Π΄Π΅Π½Π΅Π³, ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ настроСк ΠΈ Ρ‚. ΠΏ.

Π‘ΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‚ Ρ€Π°Π·Π½Ρ‹Π΅ источники для создания ΠΎΠ΄Π½ΠΎΡ€Π°Π·ΠΎΠ²Ρ‹Ρ… ΠΏΠ°Ρ€ΠΎΠ»Π΅ΠΉ. НаиболСС популярныС:

  1. АппаратныС ΠΈΠ»ΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½Ρ‹Π΅ Ρ‚ΠΎΠΊΠ΅Π½Ρ‹, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠ³ΡƒΡ‚ Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠ΄Π½ΠΎΡ€Π°Π·ΠΎΠ²Ρ‹Π΅ ΠΏΠ°Ρ€ΠΎΠ»ΠΈ Π½Π° основании сСкрСтного ΠΊΠ»ΡŽΡ‡Π°, Π²Π²Π΅Π΄Π΅Π½Π½ΠΎΠ³ΠΎ Π² Π½ΠΈΡ…, ΠΈ Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ. Π‘Π΅ΠΊΡ€Π΅Ρ‚Π½Ρ‹Π΅ ΠΊΠ»ΡŽΡ‡ΠΈ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ, ΡΠ²Π»ΡΡŽΡ‰ΠΈΠ΅ΡΡ Ρ„Π°ΠΊΡ‚ΠΎΡ€ΠΎΠΌ владСния, Ρ‚Π°ΠΊΠΆΠ΅ хранятся Π½Π° сСрвСрС, Ρ‡Ρ‚ΠΎ позволяСт Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΡƒ Π²Π²Π΅Π΄Π΅Π½Π½Ρ‹Ρ… ΠΎΠ΄Π½ΠΎΡ€Π°Π·ΠΎΠ²Ρ‹Ρ… ΠΏΠ°Ρ€ΠΎΠ»Π΅ΠΉ. ΠŸΡ€ΠΈΠΌΠ΅Ρ€ Π°ΠΏΠΏΠ°Ρ€Π°Ρ‚Π½ΠΎΠΉ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΉ Ρ‚ΠΎΠΊΠ΅Π½ΠΎΠ² β€” RSA SecurID; ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠΉ β€” ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Google Authenticator.
  2. Π‘Π»ΡƒΡ‡Π°ΠΉΠ½ΠΎ Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅ΠΌΡ‹Π΅ ΠΊΠΎΠ΄Ρ‹, ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Π΅ΠΌΡ‹Π΅ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŽ Ρ‡Π΅Ρ€Π΅Π· SMS ΠΈΠ»ΠΈ Π΄Ρ€ΡƒΠ³ΠΎΠΉ ΠΊΠ°Π½Π°Π» связи. Π’ этой ситуации Ρ„Π°ΠΊΡ‚ΠΎΡ€ владСния β€” Ρ‚Π΅Π»Π΅Ρ„ΠΎΠ½ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ (Ρ‚ΠΎΡ‡Π½Π΅Π΅ β€” SIM-ΠΊΠ°Ρ€Ρ‚Π°, привязанная ΠΊ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠΌΡƒ Π½ΠΎΠΌΠ΅Ρ€Ρƒ).
  3. РаспСчатка ΠΈΠ»ΠΈ scratch card со списком Π·Π°Ρ€Π°Π½Π΅Π΅ сформированных ΠΎΠ΄Π½ΠΎΡ€Π°Π·ΠΎΠ²Ρ‹Ρ… ΠΏΠ°Ρ€ΠΎΠ»Π΅ΠΉ. Для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Π½ΠΎΠ²ΠΎΠ³ΠΎ Π²Ρ…ΠΎΠ΄Π° Π² систСму трСбуСтся ввСсти Π½ΠΎΠ²Ρ‹ΠΉ ΠΎΠ΄Π½ΠΎΡ€Π°Π·ΠΎΠ²Ρ‹ΠΉ ΠΏΠ°Ρ€ΠΎΠ»ΡŒ с ΡƒΠΊΠ°Π·Π°Π½Π½Ρ‹ΠΌ Π½ΠΎΠΌΠ΅Ρ€ΠΎΠΌ.

Аппаратный Ρ‚ΠΎΠΊΠ΅Π½ RSA SecurID Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ Π½ΠΎΠ²Ρ‹ΠΉ ΠΊΠΎΠ΄ ΠΊΠ°ΠΆΠ΄Ρ‹Π΅ 30 сСкунд.

Π’ Π²Π΅Π±-прилоТСниях Ρ‚Π°ΠΊΠΎΠΉ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ часто рСализуСтся посрСдством Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ forms authentication: послС ΠΏΠ΅Ρ€Π²ΠΈΡ‡Π½ΠΎΠΉ Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΏΠΎ ΠΏΠ°Ρ€ΠΎΠ»ΡŽ, создаСтся сСссия ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ, ΠΎΠ΄Π½Π°ΠΊΠΎ Π² контСкстС этой сСссии ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ‚ доступа ΠΊ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡŽ Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° ΠΎΠ½ Π½Π΅ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΡƒΡŽ Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΡŽ ΠΏΠΎ ΠΎΠ΄Π½ΠΎΡ€Π°Π·ΠΎΠ²ΠΎΠΌΡƒ ΠΏΠ°Ρ€ΠΎΠ»ΡŽ.

АутСнтификация ΠΏΠΎ ΠΊΠ»ΡŽΡ‡Π°ΠΌ доступа

Π­Ρ‚ΠΎΡ‚ способ Ρ‡Π°Ρ‰Π΅ всСго ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ устройств, сСрвисов ΠΈΠ»ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΡ… ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ ΠΏΡ€ΠΈ ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠΈ ΠΊ Π²Π΅Π±-сСрвисам. Π—Π΄Π΅ΡΡŒ Π² качСствС сСкрСта ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡŽΡ‚ΡΡ ΠΊΠ»ΡŽΡ‡ΠΈ доступа (access key, API key) β€” Π΄Π»ΠΈΠ½Π½Ρ‹Π΅ ΡƒΠ½ΠΈΠΊΠ°Π»ΡŒΠ½Ρ‹Π΅ строки, содСрТащиС ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½Ρ‹ΠΉ Π½Π°Π±ΠΎΡ€ символов, ΠΏΠΎ сути Π·Π°ΠΌΠ΅Π½ΡΡŽΡ‰ΠΈΠ΅ собой ΠΊΠΎΠΌΠ±ΠΈΠ½Π°Ρ†ΠΈΡŽ username/password.

Π’ Π±ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²Π΅ случаСв, сСрвСр Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ ΠΊΠ»ΡŽΡ‡ΠΈ доступа ΠΏΠΎ запросу ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π΄Π°Π»Π΅Π΅ ΡΠΎΡ…Ρ€Π°Π½ΡΡŽΡ‚ эти ΠΊΠ»ΡŽΡ‡ΠΈ Π² клиСнтских прилоТСниях. ΠŸΡ€ΠΈ создании ΠΊΠ»ΡŽΡ‡Π° Ρ‚Π°ΠΊΠΆΠ΅ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡ΠΈΡ‚ΡŒ срок дСйствия ΠΈ ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ доступа, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ клиСнтскоС ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΏΡ€ΠΈ Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ этого ΠΊΠ»ΡŽΡ‡Π°.

Π₯ΠΎΡ€ΠΎΡˆΠΈΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ примСнСния Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΏΠΎ ΠΊΠ»ΡŽΡ‡Ρƒ β€” ΠΎΠ±Π»Π°ΠΊΠΎ Amazon Web Services. ΠŸΡ€Π΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΠΌ, Ρƒ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ Π΅ΡΡ‚ΡŒ Π²Π΅Π±-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‰Π΅Π΅ Π·Π°Π³Ρ€ΡƒΠΆΠ°Ρ‚ΡŒ ΠΈ ΠΏΡ€ΠΎΡΠΌΠ°Ρ‚Ρ€ΠΈΠ²Π°Ρ‚ΡŒ Ρ„ΠΎΡ‚ΠΎΠ³Ρ€Π°Ρ„ΠΈΠΈ, ΠΈ ΠΎΠ½ Ρ…ΠΎΡ‡Π΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ сСрвис Amazon S3 для хранСния Ρ„Π°ΠΉΠ»ΠΎΠ². Π’ Ρ‚Π°ΠΊΠΎΠΌ случаС, ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ Ρ‡Π΅Ρ€Π΅Π· консоль AWS ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ ΠΊΠ»ΡŽΡ‡, ΠΈΠΌΠ΅ΡŽΡ‰ΠΈΠΉ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½Π½Ρ‹ΠΉ доступ ΠΊ ΠΎΠ±Π»Π°ΠΊΡƒ: Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‡Ρ‚Π΅Π½ΠΈΠ΅/запись Π΅Π³ΠΎ Ρ„Π°ΠΉΠ»ΠΎΠ² Π² Amazon S3. Π­Ρ‚ΠΎΡ‚ ΠΊΠ»ΡŽΡ‡ Π² Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΡ‚ΡŒ для Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ Π²Π΅Π±-прилоТСния Π² ΠΎΠ±Π»Π°ΠΊΠ΅ AWS.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ примСнСния Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΏΠΎ ΠΊΠ»ΡŽΡ‡Ρƒ.

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

Π‘ тСхничСской Ρ‚ΠΎΡ‡ΠΊΠΈ зрСния, здСсь Π½Π΅ сущСствуСт Π΅Π΄ΠΈΠ½ΠΎΠ³ΠΎ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π°: ΠΊΠ»ΡŽΡ‡ΠΈ ΠΌΠΎΠ³ΡƒΡ‚ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒΡΡ Π² Ρ€Π°Π·Π½Ρ‹Ρ… частях HTTP-запроса: URL query, request body ΠΈΠ»ΠΈ HTTP header. Как ΠΈ Π² случаС Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΏΠΎ ΠΏΠ°Ρ€ΠΎΠ»ΡŽ, Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ ΠΎΠΏΡ‚ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ β€” использованиС HTTP header. Π’ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… случаях ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ HTTP-схСму Bearer для ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ Ρ‚ΠΎΠΊΠ΅Π½Π° Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ΅ (Authorization: Bearer [token]). Π§Ρ‚ΠΎΠ±Ρ‹ ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ ΠΏΠ΅Ρ€Π΅Ρ…Π²Π°Ρ‚Π° ΠΊΠ»ΡŽΡ‡Π΅ΠΉ, соСдинСниС с сСрвСром Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±Ρ‹Ρ‚ΡŒ ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ Π·Π°Ρ‰ΠΈΡ‰Π΅Π½ΠΎ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»ΠΎΠΌ SSL/TLS.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΏΠΎ ΠΊΠ»ΡŽΡ‡Ρƒ доступа, ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½ΠΎΠ³ΠΎ Π² HTTP Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ΅.

ΠšΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‚ Π±ΠΎΠ»Π΅Π΅ слоТныС схСмы Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΏΠΎ ΠΊΠ»ΡŽΡ‡Π°ΠΌ для Π½Π΅Π·Π°Ρ‰ΠΈΡ‰Π΅Π½Π½Ρ‹Ρ… соСдинСний. Π’ этом случаС, ΠΊΠ»ΡŽΡ‡ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ состоит ΠΈΡ… Π΄Π²ΡƒΡ… частСй: ΠΏΡƒΠ±Π»ΠΈΡ‡Π½ΠΎΠΉ ΠΈ сСкрСтной. ΠŸΡƒΠ±Π»ΠΈΡ‡Π½Π°Ρ Ρ‡Π°ΡΡ‚ΡŒ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°, Π° сСкрСтная Ρ‡Π°ΡΡ‚ΡŒ позволяСт ΡΠ³Π΅Π½Π΅Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ подпись. НапримСр, ΠΏΠΎ Π°Π½Π°Π»ΠΎΠ³ΠΈΠΈ с digest authentication схСмой, сСрвСр ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΡΠ»Π°Ρ‚ΡŒ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ ΡƒΠ½ΠΈΠΊΠ°Π»ΡŒΠ½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ nonce ΠΈΠ»ΠΈ timestamp, Π° ΠΊΠ»ΠΈΠ΅Π½Ρ‚ β€” Π²ΠΎΠ·Π²Ρ€Π°Ρ‚ΠΈΡ‚ΡŒ Ρ…ΡΡˆ ΠΈΠ»ΠΈ HMAC этого значСния, вычислСнный с использованиСм сСкрСтной части ΠΊΠ»ΡŽΡ‡Π°. Π­Ρ‚ΠΎ позволяСт ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ всСго ΠΊΠ»ΡŽΡ‡Π° Π² ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π»ΡŒΠ½ΠΎΠΌ Π²ΠΈΠ΄Π΅ ΠΈ Π·Π°Ρ‰ΠΈΡ‰Π°Π΅Ρ‚ ΠΎΡ‚ replay attacks.

АутСнтификация ΠΏΠΎ Ρ‚ΠΎΠΊΠ΅Π½Π°ΠΌ

Π’Π°ΠΊΠΎΠΉ способ Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ Ρ‡Π°Ρ‰Π΅ всСго примСняСтся ΠΏΡ€ΠΈ построСнии распрСдСлСнных систСм Single Sign-On (SSO), Π³Π΄Π΅ ΠΎΠ΄Π½ΠΎ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ (service provider ΠΈΠ»ΠΈ relying party) Π΄Π΅Π»Π΅Π³ΠΈΡ€ΡƒΠ΅Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ Π΄Ρ€ΡƒΠ³ΠΎΠΌΡƒ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡŽ (identity provider ΠΈΠ»ΠΈ authentication service). Π’ΠΈΠΏΠΈΡ‡Π½Ρ‹ΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ этого способа β€” Π²Ρ…ΠΎΠ΄ Π² ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Ρ‡Π΅Ρ€Π΅Π· ΡƒΡ‡Π΅Ρ‚Π½ΡƒΡŽ запись Π² ΡΠΎΡ†ΠΈΠ°Π»ΡŒΠ½Ρ‹Ρ… сСтях. Π—Π΄Π΅ΡΡŒ ΡΠΎΡ†ΠΈΠ°Π»ΡŒΠ½Ρ‹Π΅ сСти ΡΠ²Π»ΡΡŽΡ‚ΡΡ сСрвисами Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ, Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ довСряСт Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ ΡΠΎΡ†ΠΈΠ°Π»ΡŒΠ½Ρ‹ΠΌ сСтям.

РСализация этого способа Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ identity provider (IP) прСдоставляСт достовСрныС свСдСния ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ Π² Π²ΠΈΠ΄Π΅ Ρ‚ΠΎΠΊΠ΅Π½Π°, Π° service provider (SP) ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ этот Ρ‚ΠΎΠΊΠ΅Π½ для ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ, Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΈ Π°Π²Ρ‚ΠΎΡ€ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ.

На ΠΎΠ±Ρ‰Π΅ΠΌ ΡƒΡ€ΠΎΠ²Π½Π΅, вСсь процСсс выглядит ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ:

  1. ΠšΠ»ΠΈΠ΅Π½Ρ‚ аутСнтифицируСтся Π² identity provider ΠΎΠ΄Π½ΠΈΠΌ ΠΈΠ· способов, спСцифичным для Π½Π΅Π³ΠΎ (ΠΏΠ°Ρ€ΠΎΠ»ΡŒ, ΠΊΠ»ΡŽΡ‡ доступа, сСртификат, Kerberos, ΠΈΡ‚Π΄.).
  2. ΠšΠ»ΠΈΠ΅Π½Ρ‚ просит identity provider ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ Π΅ΠΌΡƒ Ρ‚ΠΎΠΊΠ΅Π½ для ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠ³ΠΎ SP-прилоТСния. Identity provider Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ Ρ‚ΠΎΠΊΠ΅Π½ ΠΈ отправляСт Π΅Π³ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ.
  3. ΠšΠ»ΠΈΠ΅Π½Ρ‚ аутСнтифицируСтся Π² SP-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ этого Ρ‚ΠΎΠΊΠ΅Π½Π°.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ Β«Π°ΠΊΡ‚ΠΈΠ²Π½ΠΎΠ³ΠΎΒ» ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ Ρ‚ΠΎΠΊΠ΅Π½Π°, ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½ΠΎΠ³ΠΎ посрСдством Bearer схСмы.

ΠŸΡ€ΠΎΡ†Π΅ΡΡ, описанный Π²Ρ‹ΡˆΠ΅, ΠΎΡ‚Ρ€Π°ΠΆΠ°Π΅Ρ‚ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ Π°ΠΊΡ‚ΠΈΠ²Π½ΠΎΠ³ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°, Ρ‚. Π΅. Ρ‚Π°ΠΊΠΎΠ³ΠΎ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΠΎΠΆΠ΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ Π·Π°ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½Π½ΡƒΡŽ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ дСйствий (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, iOS/Android прилоТСния). Π‘Ρ€Π°ΡƒΠ·Π΅Ρ€ ΠΆΠ΅ β€” пассивный ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π² Ρ‚ΠΎΠΌ смыслС, Ρ‡Ρ‚ΠΎ ΠΎΠ½ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Ρ‚ΡŒ страницы, Π·Π°ΠΏΡ€ΠΎΡˆΠ΅Π½Π½Ρ‹Π΅ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΌ. Π’ этом случаС аутСнтификация достигаСтся посрСдством автоматичСского пСрСнаправлСния Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π° ΠΌΠ΅ΠΆΠ΄Ρƒ Π²Π΅Π±-прилоТСниями identity provider ΠΈ service provider.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ «пассивного» ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° посрСдством пСрСнаправлСния запросов.

БущСствуСт нСсколько стандартов, Π² точности ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡŽΡ‰ΠΈΡ… ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» взаимодСйствия ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°ΠΌΠΈ (Π°ΠΊΡ‚ΠΈΠ²Π½Ρ‹ΠΌΠΈ ΠΈ пассивными) ΠΈ IP/SP-прилоТСниями ΠΈ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅ΠΌΡ‹Ρ… Ρ‚ΠΎΠΊΠ΅Π½ΠΎΠ². Π‘Ρ€Π΅Π΄ΠΈ Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ популярных стандартов β€” OAuth, OpenID Connect, SAML, ΠΈ WS-Federation. НСкоторая информация ΠΎΠ± этих ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π°Ρ… β€” Π½ΠΈΠΆΠ΅ Π² ΡΡ‚Π°Ρ‚ΡŒΠ΅.

Π‘Π°ΠΌ Ρ‚ΠΎΠΊΠ΅Π½ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ прСдставляСт собой структуру Π΄Π°Π½Π½Ρ‹Ρ…, которая содСрТит ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ, ΠΊΡ‚ΠΎ сгСнСрировал Ρ‚ΠΎΠΊΠ΅Π½, ΠΊΡ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΏΠΎΠ»ΡƒΡ‡Π°Ρ‚Π΅Π»Π΅ΠΌ Ρ‚ΠΎΠΊΠ΅Π½Π°, срок дСйствия, Π½Π°Π±ΠΎΡ€ свСдСний ΠΎ самом ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ (claims). ΠšΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, Ρ‚ΠΎΠΊΠ΅Π½ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ подписываСтся для прСдотвращСния нСсанкционированных ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ ΠΈ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΠΉ подлинности.

ΠŸΡ€ΠΈ Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ‚ΠΎΠΊΠ΅Π½Π° SP-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ:

  1. Π’ΠΎΠΊΠ΅Π½ Π±Ρ‹Π» Π²Ρ‹Π΄Π°Π½ Π΄ΠΎΠ²Π΅Ρ€Π΅Π½Π½Ρ‹ΠΌ identity provider ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΠΌ (ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° поля issuer).
  2. Π’ΠΎΠΊΠ΅Π½ прСдназначаСтся Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΌΡƒ SP-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡŽ (ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° поля audience).
  3. Π‘Ρ€ΠΎΠΊ дСйствия Ρ‚ΠΎΠΊΠ΅Π½Π° Π΅Ρ‰Π΅ Π½Π΅ истСк (ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° поля expiration date).
  4. Π’ΠΎΠΊΠ΅Π½ ΠΏΠΎΠ΄Π»ΠΈΠ½Π½Ρ‹ΠΉ ΠΈ Π½Π΅ Π±Ρ‹Π» ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ (ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° подписи).

Π’ случаС ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠΉ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ SP-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ выполняСт Π°Π²Ρ‚ΠΎΡ€ΠΈΠ·Π°Ρ†ΠΈΡŽ запроса Π½Π° основании Π΄Π°Π½Π½Ρ‹Ρ… ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅, содСрТащихся Π² Ρ‚ΠΎΠΊΠ΅Π½Π΅.

Π€ΠΎΡ€ΠΌΠ°Ρ‚Ρ‹ Ρ‚ΠΎΠΊΠ΅Π½ΠΎΠ²

БущСствуСт нСсколько распространСнных Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ΠΎΠ² Ρ‚ΠΎΠΊΠ΅Π½ΠΎΠ² для Π²Π΅Π±-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ:

  1. Simple Web Token (SWT) β€” Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ простой Ρ„ΠΎΡ€ΠΌΠ°Ρ‚, ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²Π»ΡΡŽΡ‰ΠΈΠΉ собой Π½Π°Π±ΠΎΡ€ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½Ρ‹Ρ… ΠΏΠ°Ρ€ имя/Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π² Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅ кодирования HTML form. Π‘Ρ‚Π°Π½Π΄Π°Ρ€Ρ‚ опрСдСляСт нСсколько Π·Π°Ρ€Π΅Π·Π΅Ρ€Π²ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Ρ… ΠΈΠΌΠ΅Π½: Issuer, Audience, ExpiresOn ΠΈ HMACSHA256. Π’ΠΎΠΊΠ΅Π½ подписываСтся с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ симмСтричного ΠΊΠ»ΡŽΡ‡Π°, Ρ‚Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ ΠΎΠ±Π° IP- ΠΈ SP-прилоТСния Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΈΠΌΠ΅Ρ‚ΡŒ этот ΠΊΠ»ΡŽΡ‡ для возмоТности создания/ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ Ρ‚ΠΎΠΊΠ΅Π½Π°.

    ΠŸΡ€ΠΈΠΌΠ΅Ρ€ SWT Ρ‚ΠΎΠΊΠ΅Π½Π° (послС дСкодирования).

    Issuer=http://auth.myservice.com&

    Audience=http://myservice.com&

    ExpiresOn=1435937883&

    UserName=John Smith&

    UserRole=Admin&

    HMACSHA256=KOUQRPSpy64rvT2KnYyQKtFFXUIggnesSpE7ADA4o9w

  2. JSON Web Token (JWT) β€” содСрТит Ρ‚Ρ€ΠΈ Π±Π»ΠΎΠΊΠ°, Ρ€Π°Π·Π΄Π΅Π»Π΅Π½Π½Ρ‹Ρ… Ρ‚ΠΎΡ‡ΠΊΠ°ΠΌΠΈ: Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ, Π½Π°Π±ΠΎΡ€ ΠΏΠΎΠ»Π΅ΠΉ (claims) ΠΈ подпись. ΠŸΠ΅Ρ€Π²Ρ‹Π΅ Π΄Π²Π° Π±Π»ΠΎΠΊΠ° прСдставлСны Π² JSON-Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅ ΠΈ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π·Π°ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²Π°Π½Ρ‹ Π² Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ base64. Набор ΠΏΠΎΠ»Π΅ΠΉ содСрТит ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½Ρ‹Π΅ ΠΏΠ°Ρ€Ρ‹ имя/значСния, ΠΏΡ€ΠΈΡ‚ΠΎΠΌ стандарт JWT опрСдСляСт нСсколько Π·Π°Ρ€Π΅Π·Π΅Ρ€Π²ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Ρ… ΠΈΠΌΠ΅Π½ (iss, aud, exp ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠ΅). Подпись ΠΌΠΎΠΆΠ΅Ρ‚ Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒΡΡ ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ ΠΈ симмСтричных Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠΎΠ² ΡˆΠΈΡ„Ρ€ΠΎΠ²Π°Π½ΠΈΡ, ΠΈ асиммСтричных. ΠšΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, сущСствуСт ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ стандарт, ΠΎΡ‚ΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‰ΠΈΠΉ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ Π·Π°ΡˆΠΈΡ„Ρ€ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ JWT-Ρ‚ΠΎΠΊΠ΅Π½Π°.

    ΠŸΡ€ΠΈΠΌΠ΅Ρ€ подписанного JWT Ρ‚ΠΎΠΊΠ΅Π½Π° (послС дСкодирования 1 ΠΈ 2 Π±Π»ΠΎΠΊΠΎΠ²).

    { Β«algΒ»: Β«HS256Β», Β«typΒ»: Β«JWTΒ» }.

    { Β«issΒ»: Β«auth.myservice.comΒ», Β«audΒ»: Β«myservice.comΒ», Β«expΒ»: Β«1435937883Β», Β«userNameΒ»: Β«John SmithΒ», Β«userRoleΒ»: Β«AdminΒ» }.

    S9Zs/8/uEGGTVVtLggFTizCsMtwOJnRhjaQ2BMUQhcY

  3. Security Assertion Markup Language (SAML) β€” опрСдСляСт Ρ‚ΠΎΠΊΠ΅Π½Ρ‹ (SAML assertions) Π² XML-Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅, Π²ΠΊΠ»ΡŽΡ‡Π°ΡŽΡ‰Π΅ΠΌ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎΠ± эмитСнтС, ΠΎ ΡΡƒΠ±ΡŠΠ΅ΠΊΡ‚Π΅, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ условия для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ Ρ‚ΠΎΠΊΠ΅Π½Π°, Π½Π°Π±ΠΎΡ€ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… ΡƒΡ‚Π²Π΅Ρ€ΠΆΠ΄Π΅Π½ΠΈΠΉ (statements) ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅. Подпись SAML-Ρ‚ΠΎΠΊΠ΅Π½ΠΎΠ² осущСствляСтся ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ ассимСтричной ΠΊΡ€ΠΈΠΏΡ‚ΠΎΠ³Ρ€Π°Ρ„ΠΈΠΈ. ΠšΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, Π² ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΠΈΡ… Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ΠΎΠ², SAML-Ρ‚ΠΎΠΊΠ΅Π½Ρ‹ содСрТат ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ для подтвСрТдСния владСния Ρ‚ΠΎΠΊΠ΅Π½ΠΎΠΌ, Ρ‡Ρ‚ΠΎ позволяСт ΠΏΡ€Π΅Π΄ΠΎΡ‚Π²Ρ€Π°Ρ‚ΠΈΡ‚ΡŒ ΠΏΠ΅Ρ€Π΅Ρ…Π²Π°Ρ‚ Ρ‚ΠΎΠΊΠ΅Π½ΠΎΠ² Ρ‡Π΅Ρ€Π΅Π· man-in-the-middle-Π°Ρ‚Π°ΠΊΠΈ ΠΏΡ€ΠΈ использовании Π½Π΅Π·Π°Ρ‰ΠΈΡ‰Π΅Π½Π½Ρ‹Ρ… соСдинСний.
Π‘Ρ‚Π°Π½Π΄Π°Ρ€Ρ‚ SAML

Π‘Ρ‚Π°Π½Π΄Π°Ρ€Ρ‚ Security Assertion Markup Language (SAML) описываСт способы взаимодСйствия ΠΈ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Ρ‹ ΠΌΠ΅ΠΆΠ΄Ρƒ identity provider ΠΈ service provider для ΠΎΠ±ΠΌΠ΅Π½Π° Π΄Π°Π½Π½Ρ‹ΠΌΠΈ Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΈ Π°Π²Ρ‚ΠΎΡ€ΠΈΠ·Π°Ρ†ΠΈΠΈ посрСдством Ρ‚ΠΎΠΊΠ΅Π½ΠΎΠ². Π˜Π·Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎ вСрсии 1.0 ΠΈ 1.1 Π±Ρ‹Π»ΠΈ Π²Ρ‹ΠΏΡƒΡ‰Π΅Π½Ρ‹ Π² 2002 – 2003 Π³Π³., Π² Ρ‚ΠΎ врСмя ΠΊΠ°ΠΊ вСрсия 2.0, Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Ρ€Π°ΡΡˆΠΈΡ€ΡΡŽΡ‰Π°Ρ стандарт ΠΈ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ нСсовмСстимая, ΠΎΠΏΡƒΠ±Π»ΠΈΠΊΠΎΠ²Π°Π½Π° Π² 2005 Π³.

Π­Ρ‚ΠΎΡ‚ ΠΎΡΠ½ΠΎΠ²ΠΎΠΏΠΎΠ»Π°Π³Π°ΡŽΡ‰ΠΈΠΉ стандарт β€” достаточно слоТный ΠΈ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ ΠΌΠ½ΠΎΠ³ΠΎ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… сцСнариСв ΠΈΠ½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΈ систСм. ΠžΡΠ½ΠΎΠ²Π½Ρ‹Π΅ Β«ΡΡ‚Ρ€ΠΎΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ Π±Π»ΠΎΠΊΠΈΒ» стандарта:

  1. Assertions β€” собствСнный Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ SAML Ρ‚ΠΎΠΊΠ΅Π½ΠΎΠ² Π² XML Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅.
  2. Protocols β€” Π½Π°Π±ΠΎΡ€ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅ΠΌΡ‹Ρ… сообщСний ΠΌΠ΅ΠΆΠ΄Ρƒ участниками, срСди ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… β€” запрос Π½Π° созданиС Π½ΠΎΠ²ΠΎΠ³ΠΎ Ρ‚ΠΎΠΊΠ΅Π½Π°, ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΡ… Ρ‚ΠΎΠΊΠ΅Π½ΠΎΠ², Π²Ρ‹Ρ…ΠΎΠ΄ ΠΈΠ· систСмы (logout), ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Π°ΠΌΠΈ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ, ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠ΅.
  3. Bindings β€” ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΡ‹ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ сообщСний Ρ‡Π΅Ρ€Π΅Π· Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ транспортныС ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Ρ‹. ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‚ΡΡ Ρ‚Π°ΠΊΠΈΠ΅ способы, ΠΊΠ°ΠΊ HTTP Redirect, HTTP POST, HTTP Artifact (ссылка Π½Π° сообщСния), SAML SOAP, SAML URI (адрСс получСния сообщСния) ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠ΅.
  4. Profiles β€” Ρ‚ΠΈΠΏΠΈΡ‡Π½Ρ‹Π΅ сцСнарии использования стандарта, ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡŽΡ‰ΠΈΠ΅ Π½Π°Π±ΠΎΡ€ assertions, protocols ΠΈ bindings Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Ρ… для ΠΈΡ… Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ, Ρ‡Ρ‚ΠΎ позволяСт Π΄ΠΎΡΡ‚ΠΈΡ‡ΡŒ Π»ΡƒΡ‡ΡˆΠ΅ΠΉ совмСстимости. Web Browser SSO β€” ΠΎΠ΄ΠΈΠ½ ΠΈΠ· ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΎΠ² Ρ‚Π°ΠΊΠΈΡ… ΠΏΡ€ΠΎΡ„ΠΈΠ»Π΅ΠΉ.

ΠšΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, стандарт опрСдСляСт Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ ΠΎΠ±ΠΌΠ΅Π½Π° ΠΌΠ΅Ρ‚Π°ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠ΅ΠΉ ΠΌΠ΅ΠΆΠ΄Ρƒ участниками, которая Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ список ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅ΠΌΡ‹Ρ… Ρ€ΠΎΠ»Π΅ΠΉ, ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»ΠΎΠ², Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ΠΎΠ², ΠΊΠ»ΡŽΡ‡ΠΈ ΡˆΠΈΡ„Ρ€ΠΎΠ²Π°Π½ΠΈΡ ΠΈ Ρ‚. ΠΏ.

Рассмотрим ΠΊΡ€Π°Ρ‚ΠΊΠΈΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ использования SAML для сцСнария Single Sign-On. ΠŸΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ Ρ…ΠΎΡ‡Π΅Ρ‚ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ доступ Π½Π° Π·Π°Ρ‰ΠΈΡ‰Π΅Π½Π½Ρ‹ΠΉ рСсурс сСрвис-ΠΏΡ€ΠΎΠ²Π°ΠΉΠ΄Π΅Ρ€Π° (шаг β„– 1 Π½Π° Π΄ΠΈΠ°Π³Ρ€Π°ΠΌΠΌΠ΅ Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ пассивных ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ²). Π’. ΠΊ. ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ Π½Π΅ Π±Ρ‹Π» Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Π½, SP отправляСт Π΅Π³ΠΎ Π½Π° сайт identity provider’а для создания Ρ‚ΠΎΠΊΠ΅Π½Π° (шаг β„– 2). НиТС ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΎΡ‚Π²Π΅Ρ‚Π° SP, Π³Π΄Π΅ послСдний ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ SAML HTTP Redirect binding для ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ сообщСния с запросом Ρ‚ΠΎΠΊΠ΅Π½Π°:

Π’ случаС Ρ‚Π°ΠΊΠΎΠ³ΠΎ запроса, identity provider Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΡ†ΠΈΡ€ΡƒΠ΅Ρ‚ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ (шаги β„–3-4), послС Ρ‡Π΅Π³ΠΎ Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ Ρ‚ΠΎΠΊΠ΅Π½. НиТС ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΎΡ‚Π²Π΅Ρ‚Π° IP с использованиСм HTTP POST binding (шаг β„– 5):

ПослС Ρ‚ΠΎΠ³ΠΎ ΠΊΠ°ΠΊ Π±Ρ€Π°ΡƒΠ·Π΅Ρ€ автоматичСски ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ эту Ρ„ΠΎΡ€ΠΌΡƒ Π½Π° сайт service provider’а (шаг β„– 6), послСдний Π΄Π΅ΠΊΠΎΠ΄ΠΈΡ€ΡƒΠ΅Ρ‚ Ρ‚ΠΎΠΊΠ΅Π½ ΠΈ Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΡ†ΠΈΡ€ΡƒΠ΅Ρ‚ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ. По Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°ΠΌ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠΉ Π°Π²Ρ‚ΠΎΡ€ΠΈΠ·Π°Ρ†ΠΈΠΈ запроса ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ доступ ΠΊ Π·Π°ΠΏΡ€ΠΎΡˆΠ΅Π½Π½ΠΎΠΌΡƒ рСсурсу (шаг β„– 7).

Π‘Ρ‚Π°Π½Π΄Π°Ρ€Ρ‚Ρ‹ WS-Trust ΠΈ WS-Federation

WS-Trust ΠΈ WS-Federation входят Π² Π³Ρ€ΡƒΠΏΠΏΡƒ стандартов WS-*, ΠΎΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‰ΠΈΡ… SOAP/XML-Π²Π΅Π± сСрвисы. Π­Ρ‚ΠΈ стандарты Ρ€Π°Π·Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°ΡŽΡ‚ΡΡ Π³Ρ€ΡƒΠΏΠΏΠΎΠΉ ΠΊΠΎΠΌΠΏΠ°Π½ΠΈΠΉ, ΠΊΡƒΠ΄Π° входят Microsoft, IBM, VeriSign ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠ΅. Наряду с SAML, эти стандарты достаточно слоТныС, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ прСимущСствСнно Π² ΠΊΠΎΡ€ΠΏΠΎΡ€Π°Ρ‚ΠΈΠ²Π½Ρ‹Ρ… сцСнариях.

Π‘Ρ‚Π°Π½Π΄Π°Ρ€Ρ‚ WS-Trust описываСт интСрфСйс сСрвиса Π°Π²Ρ‚ΠΎΡ€ΠΈΠ·Π°Ρ†ΠΈΠΈ, ΠΈΠΌΠ΅Π½ΡƒΠ΅ΠΌΠΎΠ³ΠΎ Secure Token Service (STS). Π­Ρ‚ΠΎΡ‚ сСрвис Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ ΠΏΠΎ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Ρƒ SOAP ΠΈ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ созданиС, ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ ΠΈ Π°Π½Π½ΡƒΠ»ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Ρ‚ΠΎΠΊΠ΅Π½ΠΎΠ². ΠŸΡ€ΠΈ этом стандарт допускаСт использованиС Ρ‚ΠΎΠΊΠ΅Π½ΠΎΠ² Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΎΠ³ΠΎ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π°, ΠΎΠ΄Π½Π°ΠΊΠΎ Π½Π° ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠ΅ Π² основном ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ SAML-Ρ‚ΠΎΠΊΠ΅Π½Ρ‹.

Π‘Ρ‚Π°Π½Π΄Π°Ρ€Ρ‚ WS-Federation касаСтся ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠΎΠ² взаимодСйствия сСрвисов ΠΌΠ΅ΠΆΠ΄Ρƒ компаниями, Π² частности, ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»ΠΎΠ² ΠΎΠ±ΠΌΠ΅Π½Π° Ρ‚ΠΎΠΊΠ΅Π½ΠΎΠ². ΠŸΡ€ΠΈ этом WS-Federation Ρ€Π°ΡΡˆΠΈΡ€ΡΠ΅Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΈ интСрфСйс сСрвиса STS, описанного Π² стандартС WS-Trust. Π‘Ρ€Π΅Π΄ΠΈ ΠΏΡ€ΠΎΡ‡Π΅Π³ΠΎ, стандарт WS-Federation опрСдСляСт:

  • Π€ΠΎΡ€ΠΌΠ°Ρ‚ ΠΈ способы ΠΎΠ±ΠΌΠ΅Π½Π° ΠΌΠ΅Ρ‚Π°Π΄Π°Π½Π½Ρ‹ΠΌΠΈ ΠΎ сСрвисах.
  • Π€ΡƒΠ½ΠΊΡ†ΠΈΡŽ Π΅Π΄ΠΈΠ½ΠΎΠ³ΠΎ Π²Ρ‹Ρ…ΠΎΠ΄Π° ΠΈΠ· всСх систСм (single sign-out).
  • БСрвис Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ΠΎΠ², ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΡŽΡ‰ΠΈΠΉ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΡƒΡŽ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅.
  • БСрвис псСвдонимов, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‰ΠΈΠΉ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ Π°Π»ΡŒΡ‚Π΅Ρ€Π½Π°Ρ‚ΠΈΠ²Π½Ρ‹Π΅ ΠΈΠΌΠ΅Π½Π° ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ.
  • ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΡƒ пассивных ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ² (Π±Ρ€Π°ΡƒΠ·Π΅Ρ€ΠΎΠ²) посрСдством пСрСнаправлСния.

МоТно ΡΠΊΠ°Π·Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ WS-Federation позволяСт Ρ€Π΅ΡˆΠΈΡ‚ΡŒ Ρ‚Π΅ ΠΆΠ΅ Π·Π°Π΄Π°Ρ‡ΠΈ, Ρ‡Ρ‚ΠΎ ΠΈ SAML, ΠΎΠ΄Π½Π°ΠΊΠΎ ΠΈΡ… ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Ρ‹ ΠΈ рСализация Π² Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ стСпСни ΠΎΡ‚Π»ΠΈΡ‡Π°ΡŽΡ‚ΡΡ.

Π‘Ρ‚Π°Π½Π΄Π°Ρ€Ρ‚Ρ‹ OAuth ΠΈ OpenID Connect

Π’ ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ SAML ΠΈ WS-Federation, стандарт OAuth (Open Authorization) Π½Π΅ описываСт ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ. ВмСсто этого ΠΎΠ½ опрСдСляСт ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ получСния доступа ΠΎΠ΄Π½ΠΎΠ³ΠΎ прилоТСния ΠΊ Π΄Ρ€ΡƒΠ³ΠΎΠΌΡƒ ΠΎΡ‚ ΠΈΠΌΠ΅Π½ΠΈ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ. Однако ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‚ схСмы, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‰ΠΈΠ΅ ΠΎΡΡƒΡ‰Π΅ΡΡ‚Π²ΠΈΡ‚ΡŒ Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΡŽ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ Π½Π° Π±Π°Π·Π΅ этого стандарта (ΠΎΠ± этом β€” Π½ΠΈΠΆΠ΅).

ΠŸΠ΅Ρ€Π²Π°Ρ вСрсия стандарта Ρ€Π°Π·Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π»Π°ΡΡŒ Π² 2007 – 2010 Π³Π³., Π° тСкущая вСрсия 2.0 ΠΎΠΏΡƒΠ±Π»ΠΈΠΊΠΎΠ²Π°Π½Π° Π² 2012 Π³. ВСрсия 2.0 Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Ρ€Π°ΡΡˆΠΈΡ€ΡΠ΅Ρ‚ ΠΈ Π² Ρ‚ΠΎ ΠΆΠ΅ врСмя ΡƒΠΏΡ€ΠΎΡ‰Π°Π΅Ρ‚ стандарт, Π½ΠΎ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ нСсовмСстима с вСрсиСй 1.0. БСйчас OAuth 2.0 ΠΎΡ‡Π΅Π½ΡŒ популярСн ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ повсСмСстно для прСдоставлСния Π΄Π΅Π»Π΅Π³ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ доступа ΠΈ Ρ‚Ρ€Π΅Ρ‚ΡŒΠ΅-стороннСй Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ.

Π§Ρ‚ΠΎΠ±Ρ‹ Π»ΡƒΡ‡ΡˆΠ΅ ΠΏΠΎΠ½ΡΡ‚ΡŒ сам стандарт, рассмотрим ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π²Π΅Π±-прилоТСния, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ΠΏΠΎΠΌΠΎΠ³Π°Π΅Ρ‚ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡΠΌ ΠΏΠ»Π°Π½ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΡƒΡ‚Π΅ΡˆΠ΅ΡΡ‚Π²ΠΈΡ. Как Ρ‡Π°ΡΡ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ ΠΎΠ½ΠΎ ΡƒΠΌΠ΅Π΅Ρ‚ Π°Π½Π°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠΎΡ‡Ρ‚Ρƒ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ Π½Π° Π½Π°Π»ΠΈΡ‡ΠΈΠ΅ писСм с подтвСрТдСниями Π±Ρ€ΠΎΠ½ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠΉ ΠΈ автоматичСски Π²ΠΊΠ»ΡŽΡ‡Π°Ρ‚ΡŒ ΠΈΡ… Π² ΠΏΠ»Π°Π½ΠΈΡ€ΡƒΠ΅ΠΌΡ‹ΠΉ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚. Π’ΠΎΠ·Π½ΠΈΠΊΠ°Π΅Ρ‚ вопрос, ΠΊΠ°ΠΊ это Π²Π΅Π±-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ бСзопасно ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ доступ ΠΊ ΠΏΠΎΡ‡Ρ‚Π΅ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΊ Gmail?

> ΠŸΠΎΠΏΡ€ΠΎΡΠΈΡ‚ΡŒ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ своСй ΡƒΡ‡Π΅Ρ‚Π½ΠΎΠΉ записи? β€” ΠΏΠ»ΠΎΡ…ΠΎΠΉ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚.

> ΠŸΠΎΠΏΡ€ΠΎΡΠΈΡ‚ΡŒ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ ΠΊΠ»ΡŽΡ‡ доступа? β€” Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, Π½ΠΎ вСсьма слоТно.

Как Ρ€Π°Π· эту ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡƒ ΠΈ позволяСт Ρ€Π΅ΡˆΠΈΡ‚ΡŒ стандарт OAuth: ΠΎΠ½ описываСт, ΠΊΠ°ΠΊ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΏΡƒΡ‚Π΅ΡˆΠ΅ΡΡ‚Π²ΠΈΠΉ (client) ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ доступ ΠΊ ΠΏΠΎΡ‡Ρ‚Π΅ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ (resource server) с Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ (resource owner). Π’ ΠΎΠ±Ρ‰Π΅ΠΌ Π²ΠΈΠ΄Π΅ вСсь процСсс состоит ΠΈΠ· Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… шагов:

  1. ΠŸΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ (resource owner) Π΄Π°Π΅Ρ‚ Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡŽ (client) Π½Π° доступ ΠΊ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠΌΡƒ рСсурсу Π² Π²ΠΈΠ΄Π΅ Π³Ρ€Π°Π½Ρ‚Π°. Π§Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅ Π³Ρ€Π°Π½Ρ‚, рассмотрим Ρ‡ΡƒΡ‚ΡŒ Π½ΠΈΠΆΠ΅.
  2. ΠŸΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ обращаСтся ΠΊ сСрвСру Π°Π²Ρ‚ΠΎΡ€ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ Ρ‚ΠΎΠΊΠ΅Π½ доступа ΠΊ рСсурсу Π² ΠΎΠ±ΠΌΠ΅Π½ Π½Π° свой Π³Ρ€Π°Π½Ρ‚. Π’ нашСм ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ сСрвСр Π°Π²Ρ‚ΠΎΡ€ΠΈΠ·Π°Ρ†ΠΈΠΈ β€” Google. ΠŸΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ аутСнтифицируСтся ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ ΠΊΠ»ΡŽΡ‡Π° доступа, Π²Ρ‹Π΄Π°Π½Π½Ρ‹ΠΌ Π΅ΠΌΡƒ ΠΏΡ€ΠΈ ΠΏΡ€Π΅Π΄Π²Π°Ρ€ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΉ рСгистрации.
  3. ΠŸΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ этот Ρ‚ΠΎΠΊΠ΅Π½ для получСния Ρ‚Ρ€Π΅Π±ΡƒΠ΅ΠΌΡ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ… ΠΎΡ‚ сСрвСра рСсурсов (Π² нашСм случаС β€” сСрвис Gmail).

ВзаимодСйствиС ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ² Π² стандартС OAuth.

Π‘Ρ‚Π°Π½Π΄Π°Ρ€Ρ‚ описываСт Ρ‡Π΅Ρ‚Ρ‹Ρ€Π΅ Π²ΠΈΠ΄Π° Π³Ρ€Π°Π½Ρ‚ΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡŽΡ‚ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Π΅ сцСнарии примСнСния:

  1. Authorization Code β€” этот Π³Ρ€Π°Π½Ρ‚ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΎΡ‚ сСрвСра Π°Π²Ρ‚ΠΎΡ€ΠΈΠ·Π°Ρ†ΠΈΠΈ послС ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠΉ Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΈ подтвСрТдСния согласия Π½Π° прСдоставлСниС доступа. Π’Π°ΠΊΠΎΠΉ способ Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ часто ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Π² Π²Π΅Π±-прилоТСниях. ΠŸΡ€ΠΎΡ†Π΅ΡΡ получСния Π³Ρ€Π°Π½Ρ‚Π° ΠΎΡ‡Π΅Π½ΡŒ ΠΏΠΎΡ…ΠΎΠΆ Π½Π° ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ пассивных ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ² Π² SAML ΠΈ WS-Federation.
  2. Implicit β€” примСняСтся, ΠΊΠΎΠ³Π΄Π° Ρƒ прилоТСния Π½Π΅Ρ‚ возмоТности бСзопасно ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ Ρ‚ΠΎΠΊΠ΅Π½ ΠΎΡ‚ сСрвСра Π°Π²Ρ‚ΠΎΡ€ΠΈΠ·Π°Ρ†ΠΈΠΈ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, JavaScript-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π² Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π΅). Π’ этом случаС Π³Ρ€Π°Π½Ρ‚ прСдставляСт собой Ρ‚ΠΎΠΊΠ΅Π½, ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹ΠΉ ΠΎΡ‚ сСрвСра Π°Π²Ρ‚ΠΎΡ€ΠΈΠ·Π°Ρ†ΠΈΠΈ, Π° шаг β„– 2 ΠΈΡΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ ΠΈΠ· сцСнария Π²Ρ‹ΡˆΠ΅.
  3. Resource Owner Password Credentials β€” Π³Ρ€Π°Π½Ρ‚ прСдставляСт собой ΠΏΠ°Ρ€Ρƒ username/password ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ. ΠœΠΎΠΆΠ΅Ρ‚ ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡ‚ΡŒΡΡ, Ссли ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ являСтся «интСрфСйсом» для сСрвСра рСсурсов (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ β€” ΠΌΠΎΠ±ΠΈΠ»ΡŒΠ½Ρ‹ΠΉ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ для Gmail).
  4. Client Credentials β€” Π² этом случаС Π½Π΅Ρ‚ Π½ΠΈΠΊΠ°ΠΊΠΎΠ³ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ, Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ доступ ΠΊ своим рСсурсам ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ своих ΠΊΠ»ΡŽΡ‡Π΅ΠΉ доступа (ΠΈΡΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ шаг β„– 1).

Π‘Ρ‚Π°Π½Π΄Π°Ρ€Ρ‚ Π½Π΅ опрСдСляСт Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ Ρ‚ΠΎΠΊΠ΅Π½Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅: Π² сцСнариях, адрСсуСмых стандартом, ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡŽ Π½Π΅Ρ‚ нСобходимости Π°Π½Π°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚ΠΎΠΊΠ΅Π½, Ρ‚. ΠΊ. ΠΎΠ½ лишь ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для получСния доступа ΠΊ рСсурсам. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ Π½ΠΈ Ρ‚ΠΎΠΊΠ΅Π½, Π½ΠΈ Π³Ρ€Π°Π½Ρ‚ сами ΠΏΠΎ сСбС Π½Π΅ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Π½Ρ‹ для Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ. Однако Ссли ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡŽ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ Π΄ΠΎΡΡ‚ΠΎΠ²Π΅Ρ€Π½ΡƒΡŽ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅, ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‚ нСсколько способов это ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ:

  1. Π—Π°Ρ‡Π°ΡΡ‚ΡƒΡŽ API сСрвСра рСсурсов Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ, ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΡŽΡ‰ΡƒΡŽ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎ самом ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, /me Π² Facebook API). ΠŸΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ эту ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ€Π°Π· послС получСния Ρ‚ΠΎΠΊΠ΅Π½Π° для ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°. Π’Π°ΠΊΠΎΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄ ΠΈΠ½ΠΎΠ³Π΄Π° Π½Π°Π·Ρ‹Π²Π°ΡŽΡ‚ псСвдо-Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠ΅ΠΉ.
  2. Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ стандарт OpenID Connect, Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Π°Π½Π½Ρ‹ΠΉ ΠΊΠ°ΠΊ слой ΡƒΡ‡Π΅Ρ‚Π½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ… ΠΏΠΎΠ²Π΅Ρ€Ρ… OAuth (ΠΎΠΏΡƒΠ±Π»ΠΈΠΊΠΎΠ²Π°Π½ Π² 2014 Π³.). Π’ соотвСтствии с этим стандартом, сСрвСр Π°Π²Ρ‚ΠΎΡ€ΠΈΠ·Π°Ρ†ΠΈΠΈ прСдоставляСт Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ identity token Π½Π° шагС β„– 2. Π­Ρ‚ΠΎΡ‚ Ρ‚ΠΎΠΊΠ΅Π½ Π² Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅ JWT Π±ΡƒΠ΄Π΅Ρ‚ ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ Π½Π°Π±ΠΎΡ€ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹Ρ… ΠΏΠΎΠ»Π΅ΠΉ (claims) с ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠ΅ΠΉ ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅.

Π‘Ρ‚ΠΎΠΈΡ‚ Π·Π°ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ OpenID Connect, замСнивший ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΠΈΠ΅ вСрсии стандарта OpenID 1.0 ΠΈ 2.0, Ρ‚Π°ΠΊΠΆΠ΅ содСрТит Π½Π°Π±ΠΎΡ€ Π½Π΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… Π΄ΠΎΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΉ для поиска сСрвСров Π°Π²Ρ‚ΠΎΡ€ΠΈΠ·Π°Ρ†ΠΈΠΈ, динамичСской рСгистрации ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ² ΠΈ управлСния сСссиСй ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ.

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

Π’ этой ΡΡ‚Π°Ρ‚ΡŒΠ΅ ΠΌΡ‹ рассмотрСли Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ Π² Π²Π΅Π±-прилоТСниях. НиТС β€” Ρ‚Π°Π±Π»ΠΈΡ†Π°, которая Ρ€Π΅Π·ΡŽΠΌΠΈΡ€ΡƒΠ΅Ρ‚ описанныС способы ΠΈ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Ρ‹:







Бпособ

ОсновноС ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅

ΠŸΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Ρ‹

По ΠΏΠ°Ρ€ΠΎΠ»ΡŽ

АутСнтификация ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ

HTTP, Forms

По сСртификатам

АутСнтификация ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ Π² бСзопасных прилоТСниях; аутСнтификация сСрвисов

SSL/TLS

По ΠΎΠ΄Π½ΠΎΡ€Π°Π·ΠΎΠ²Ρ‹ΠΌ паролям

Π”ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Π°Ρ аутСнтификация ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ (для достиТСния two-factor authentication)

Forms

По ΠΊΠ»ΡŽΡ‡Π°ΠΌ доступа

АутСнтификация сСрвисов ΠΈ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ

По Ρ‚ΠΎΠΊΠ΅Π½Π°ΠΌ

ДСлСгированная аутСнтификация ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ; дСлСгированная авторизация ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ

SAML, WS-Federation, OAuth, OpenID Connect

НадСюсь, Ρ‡Ρ‚ΠΎ информация оказалась ΠΏΠΎΠ»Π΅Π·Π½Π°, ΠΈ Π²Ρ‹ смоТСтС ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΡ‚ΡŒ Π΅Π΅ ΠΏΡ€ΠΈ Π΄ΠΈΠ·Π°ΠΉΠ½Π΅ ΠΈ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅ Π½ΠΎΠ²Ρ‹Ρ… ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ. Π”ΠΎ Π½ΠΎΠ²Ρ‹Ρ… встрСч!

Автор: Π”ΠΌΠΈΡ‚Ρ€ΠΈΠΉ Выростков, Solutions Architect Π² DataArt.

Как Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚ Π²Π΅Π±-сокСты? — КСвин Π‘ΡƒΠΊΠΎΡ‡Π΅Ρ„Ρ„

WebSocket — это постоянноС соСдинСниС ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ ΠΈ сСрвСром.
WebSockets обСспСчиваСт Π΄Π²ΡƒΠ½Π°ΠΏΡ€Π°Π²Π»Π΅Π½Π½Ρ‹ΠΉ полнодуплСксный ΠΊΠ°Π½Π°Π» связи.
ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Ρ‡Π΅Ρ€Π΅Π· HTTP Ρ‡Π΅Ρ€Π΅Π· ΠΎΠ΄Π½ΠΎ соСдинСниС сокСта TCP / IP. На своСм
core ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» WebSocket ΡƒΠΏΡ€ΠΎΡ‰Π°Π΅Ρ‚ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Ρƒ сообщСний ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ
ΠΈ сСрвСр. Π­Ρ‚Π° ΡΡ‚Π°Ρ‚ΡŒΡ прСдставляСт собой Π²Π²Π΅Π΄Π΅Π½ΠΈΠ΅ Π² WebSocket.
ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ», Π² Ρ‚ΠΎΠΌ числС ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Ρ€Π΅ΡˆΠ°ΡŽΡ‚ WebSockets, ΠΈ ΠΎΠ±Π·ΠΎΡ€ Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ
WebSockets ΠΎΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‚ΡΡ Π½Π° ΡƒΡ€ΠΎΠ²Π½Π΅ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π°.

ΠŸΠΎΡ‡Π΅ΠΌΡƒ ΠΈΠΌΠ΅Π½Π½ΠΎ WebSocket?

ИдСя WebSockets Π²ΠΎΠ·Π½ΠΈΠΊΠ»Π° ΠΈΠ·-Π·Π° ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠΉ HTTP-Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠΉ.
Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈ. ΠŸΡ€ΠΈ использовании HTTP ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π·Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°Π΅Ρ‚ рСсурс, Π° сСрвСр
ΠΎΡ‚Π²Π΅Ρ‡Π°Π΅Ρ‚ Π·Π°ΠΏΡ€ΠΎΡˆΠ΅Π½Π½Ρ‹ΠΌΠΈ Π΄Π°Π½Π½Ρ‹ΠΌΠΈ. HTTP — строго ΠΎΠ΄Π½ΠΎΠ½Π°ΠΏΡ€Π°Π²Π»Π΅Π½Π½Ρ‹ΠΉ
ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» — Π»ΡŽΠ±Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅, ΠΎΡ‚ΠΏΡ€Π°Π²Π»Π΅Π½Π½Ρ‹Π΅ с сСрвСра ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ, Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ ΠΏΠ΅Ρ€Π²Ρ‹ΠΌΠΈ
ΠΏΠΎ запросу ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°. Π”ΠΎΠ»Π³ΠΎΠ΅ голосованиС Ρ‚Ρ€Π°Π΄ΠΈΡ†ΠΈΠΎΠ½Π½ΠΎ дСйствовало ΠΊΠ°ΠΊ
ΠΎΠ±Ρ…ΠΎΠ΄Π½ΠΎΠΉ ΠΏΡƒΡ‚ΡŒ для этого ограничСния. ΠŸΡ€ΠΈ Π΄Π»ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΌ опросС ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π΄Π΅Π»Π°Π΅Ρ‚
HTTP-запрос с Π΄Π»ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ ΠΏΠ΅Ρ€ΠΈΠΎΠ΄ΠΎΠΌ оТидания, ΠΈ сСрвСр ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ это врСмя.
Ρ‚Π°ΠΉΠΌ-Π°ΡƒΡ‚ для ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ Π΄Π°Π½Π½Ρ‹Ρ… ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ.Π”Π»ΠΈΠ½Π½Ρ‹ΠΉ опрос Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚, Π½ΠΎ Π΅ΡΡ‚ΡŒ
нСдостаток — рСсурсы Π½Π° сСрвСрС связаны Π½Π° всСм протяТСнии
Π΄Π»ΠΈΠ½Π½Ρ‹ΠΉ опрос, Π΄Π°ΠΆΠ΅ Ссли Π½Π΅Ρ‚ Π΄Π°Π½Π½Ρ‹Ρ… для ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ.

WebSockets, с Π΄Ρ€ΡƒΠ³ΠΎΠΉ стороны, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚ ΠΎΡ‚ΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ Π½Π° основС сообщСний,
Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½ΠΎ UDP, Π½ΠΎ с Π½Π°Π΄Π΅ΠΆΠ½ΠΎΡΡ‚ΡŒΡŽ TCP. WebSocket ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ HTTP ΠΊΠ°ΠΊ
Π½Π°Ρ‡Π°Π»ΡŒΠ½Ρ‹ΠΉ транспортный ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ, Π½ΠΎ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ соСдинСниС TCP послС
ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ ΠΎΡ‚Π²Π΅Ρ‚ HTTP, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π΅Π³ΠΎ ΠΌΠΎΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ для ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ сообщСний
ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ ΠΈ сСрвСром. WebSockets ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚ Π½Π°ΠΌ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ «Π² Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠΌ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ»
прилоТСния Π±Π΅Π· использования Π΄Π»ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ опроса.

ΠžΠ±Π·ΠΎΡ€ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π°

ΠŸΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» состоит ΠΈΠ· ΠΎΡ‚ΠΊΡ€Ρ‹Π²Π°ΡŽΡ‰Π΅Π³ΠΎ рукопоТатия, Π·Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ слСдуСт Π±Π°Π·ΠΎΠ²ΠΎΠ΅ сообщСниС.
ΠΊΠ°Π΄Ρ€ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅, Π½Π°Π»ΠΎΠΆΠ΅Π½Π½ΠΎΠ΅ Π½Π° TCP.

RFC 6455 — ΠŸΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» WebSocket

WebSockets Π½Π°Ρ‡ΠΈΠ½Π°ΡŽΡ‚ свою Тизнь ΠΊΠ°ΠΊ стандартный HTTP-запрос ΠΈ ΠΎΡ‚Π²Π΅Ρ‚. Π’Π½ΡƒΡ‚Ρ€ΠΈ этого
Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠ° ΠΎΡ‚Π²Π΅Ρ‚ΠΎΠ² Π½Π° запросы, ΠΊΠ»ΠΈΠ΅Π½Ρ‚ просит ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΡŒ соСдинСниС WebSocket,
ΠΈ сСрвСр ΠΎΡ‚Π²Π΅Ρ‡Π°Π΅Ρ‚ (Ссли ΠΌΠΎΠΆΠ΅Ρ‚). Если это ΠΏΠ΅Ρ€Π²ΠΎΠ½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎΠ΅ Ρ€ΡƒΠΊΠΎΠΏΠΎΠΆΠ°Ρ‚ΠΈΠ΅
ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ, ΠΊΠ»ΠΈΠ΅Π½Ρ‚ ΠΈ сСрвСр согласились ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ TCP / IP
соСдинСниС, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π±Ρ‹Π»ΠΎ установлСно для HTTP-запроса ΠΊΠ°ΠΊ WebSocket
ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅.Π’Π΅ΠΏΠ΅Ρ€ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ ΠΌΠΎΠ³ΡƒΡ‚ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒΡΡ Ρ‡Π΅Ρ€Π΅Π· это соСдинСниС с использованиСм Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ Ρ„Ρ€Π΅ΠΉΠΌΠΎΠ²ΠΎΠ³ΠΎ
ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» сообщСний. Как Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ±Π΅ стороны ΠΏΡ€ΠΈΠ·Π½Π°ΡŽΡ‚, Ρ‡Ρ‚ΠΎ WebSocket
соСдинСниС Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±Ρ‹Ρ‚ΡŒ Π·Π°ΠΊΡ€Ρ‹Ρ‚ΠΎ, TCP соСдинСниС Ρ€Π°Π·ΠΎΡ€Π²Π°Π½ΠΎ.

УстановлСниС соСдинСния WebSocket — ΠžΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΎΠ΅ Ρ€ΡƒΠΊΠΎΠΏΠΎΠΆΠ°Ρ‚ΠΈΠ΅ WebSocket

WebSockets Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ схСму http: // ΠΈΠ»ΠΈ https: // (ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ ΠΎΠ½ΠΈ
Π½Π΅ ΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Ρƒ HTTP). Π‘ΠΊΠΎΡ€Π΅Π΅, URI WebSocket ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ Π½ΠΎΠ²ΡƒΡŽ схСму
ws: (ΠΈΠ»ΠΈ wss: для бСзопасного WebSocket).ΠžΡΡ‚Π°Π»ΡŒΠ½Π°Ρ Ρ‡Π°ΡΡ‚ΡŒ URI — это
Ρ‚ΠΎ ΠΆΠ΅, Ρ‡Ρ‚ΠΎ ΠΈ HTTP URI: хост, ΠΏΠΎΡ€Ρ‚, ΠΏΡƒΡ‚ΡŒ ΠΈ Π»ΡŽΠ±Ρ‹Π΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ запроса.

  "ws:" "//" хост [":" ΠΏΠΎΡ€Ρ‚] ΠΏΡƒΡ‚ΡŒ ["?" запрос]
"wss:" "//" хост [":" ΠΏΠΎΡ€Ρ‚] ΠΏΡƒΡ‚ΡŒ ["?" запрос]
  

БоСдинСния WebSocket ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ установлСны Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для URI, ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΡ… Π·Π° этим
схСма. Π’ΠΎ Π΅ΡΡ‚ΡŒ, Ссли Π²Ρ‹ Π²ΠΈΠ΄ΠΈΡ‚Π΅ URI со схСмой ws: // (ΠΈΠ»ΠΈ wss: // ),
Ρ‚ΠΎΠ³Π΄Π° ΠΈ ΠΊΠ»ΠΈΠ΅Π½Ρ‚, ΠΈ сСрвСр Π”ΠžΠ›Π–ΠΠ« ΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚ΡŒ соСдинСнию WebSocket.
ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» Π² соотвСтствии со спСцификациСй WebSocket.

ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ WebSocket
установлСно ΠΏΡ€ΠΈ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠΈ ΠΏΠ°Ρ€Ρ‹ HTTP-запрос / ΠΎΡ‚Π²Π΅Ρ‚. ΠšΠ»ΠΈΠ΅Π½Ρ‚, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ
ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ WebSockets ΠΈ Ρ…ΠΎΡ‡Π΅Ρ‚ ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ соСдинСниС, ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ HTTP
запрос, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ нСсколько ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΎΠ²:

  • ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅: ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅
    • Π—Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ Connection ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ опрСдСляСт,
      сСтСвоС соСдинСниС остаСтся ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΌ послС Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ
      ΠΎΡ‚Π΄Π΅Π»ΠΊΠ°. ΠžΠ±Ρ‹Ρ‡Π½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ для этого Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° — keep-alive , Ρ‡Ρ‚ΠΎΠ±Ρ‹
      ΡƒΠ±Π΅Π΄ΠΈΡ‚Π΅ΡΡŒ, Ρ‡Ρ‚ΠΎ соСдинСниС являСтся постоянным, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Ρ€Π°Π·Ρ€Π΅ΡˆΠΈΡ‚ΡŒ ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ запросы
      Π½Π° Ρ‚ΠΎΡ‚ ΠΆΠ΅ сСрвСр.Π’ΠΎ врСмя рукопоТатия открытия WebSocket ΠΌΡ‹ установили
      Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ Π΄ΠΎ ΠžΠ±Π½ΠΎΠ²ΠΈΡ‚Π΅ , сигнализируя, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ Ρ…ΠΎΡ‚ΠΈΠΌ ΡΠΎΡ…Ρ€Π°Π½ΠΈΡ‚ΡŒ соСдинСниС
      ΠΆΠΈΠ², ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π΅Π³ΠΎ для запросов, ΠΎΡ‚Π»ΠΈΡ‡Π½Ρ‹Ρ… ΠΎΡ‚ HTTP.
  • ОбновлСниС: websocket
    • Π—Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ Upgrade ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°ΠΌΠΈ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠΏΡ€ΠΎΡΠΈΡ‚ΡŒ сСрвСр ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒΡΡ
      ΠΊ ΠΎΠ΄Π½ΠΎΠΌΡƒ ΠΈΠ· пСрСчислСнных ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»ΠΎΠ² Π² порядкС убывания прСдпочтСния. ΠœΡ‹
      ΡƒΠΊΠ°ΠΆΠΈΡ‚Π΅ здСсь websocket , Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Ρ…ΠΎΡ‡Π΅Ρ‚
      ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ соСдинСниС WebSocket.
  • Sec-WebSocket-ΠΊΠ»ΡŽΡ‡: q4xkcO32u266gldTuKaSOw ==
    • Sec-WebSocket-Key — ΠΎΠ΄Π½ΠΎΡ€Π°Π·ΠΎΠ²ΠΎΠ΅ случайноС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ (nonce)
      гСнСрируСтся ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ.Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ — это случайно Π²Ρ‹Π±Ρ€Π°Π½Π½ΠΎΠ΅ 16-Π±Π°ΠΉΡ‚ΠΎΠ²ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, ΠΈΠΌΠ΅ΡŽΡ‰Π΅Π΅
      Π±Ρ‹Π» Π·Π°ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²Π°Π½ base64.
  • Sec-WebSocket-ВСрсия: 13
    • ЕдинствСнная допустимая вСрсия ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π° WebSocket — 13. Π›ΡŽΠ±Π°Ρ другая
      вСрсия, указанная Π² этом Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ΅, Π½Π΅Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½Π°.

ВмСстС эти Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ ΠΏΡ€ΠΈΠ²Π΅Π΄ΡƒΡ‚ ΠΊ HTTP-запросу GET ΠΎΡ‚
ΠΊΠ»ΠΈΠ΅Π½Ρ‚ ΠΊ URI ws: // , ΠΊΠ°ΠΊ Π² ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅:

  ΠŸΠžΠ›Π£Π§Π˜Π’Π¬ ws: //example.com: 8181 / HTTP / 1.1
Π₯ост: localhost: 8181
ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅: ОбновлСниС
ΠŸΡ€Π°Π³ΠΌΠ°: Π±Π΅Π· ΠΊΠ΅ΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ
Cache-Control: бСз кСша
ОбновлСниС: websocket
Sec-WebSocket-ВСрсия: 13
Sec-WebSocket-ΠΊΠ»ΡŽΡ‡: q4xkcO32u266gldTuKaSOw ==
  

Когда ΠΊΠ»ΠΈΠ΅Π½Ρ‚ отправляСт Π½Π°Ρ‡Π°Π»ΡŒΠ½Ρ‹ΠΉ запрос Π½Π° ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ соСдинСния WebSocket, ΠΎΠ½
ΠΆΠ΄Π΅Ρ‚ ΠΎΡ‚Π²Π΅Ρ‚Π° ΠΎΡ‚ сСрвСра.ΠžΡ‚Π²Π΅Ρ‚ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΈΠΌΠ΅Ρ‚ΡŒ ΠΊΠΎΠ΄ ΠΎΡ‚Π²Π΅Ρ‚Π° HTTP 101 Switching Protocols . ΠžΡ‚Π²Π΅Ρ‚ HTTP 101 Switching Protocols
ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ сСрвСр ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π½Π° ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ», ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΊΠ»ΠΈΠ΅Π½Ρ‚
Π·Π°ΠΏΡ€ΠΎΡˆΠ΅Π½ Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ΅ запроса Upgrade . ΠšΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, сСрвСр Π΄ΠΎΠ»ΠΆΠ΅Π½
Π²ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ HTTP, ΠΏΠΎΠ΄Ρ‚Π²Π΅Ρ€ΠΆΠ΄Π°ΡŽΡ‰ΠΈΠ΅, Ρ‡Ρ‚ΠΎ соСдинСниС Π±Ρ‹Π»ΠΎ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ
ΡƒΠ»ΡƒΡ‡ΡˆΠ΅Π½ΠΎ:

  HTTP / 1.1 101 ΠŸΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Ρ‹ ΠΊΠΎΠΌΠΌΡƒΡ‚Π°Ρ†ΠΈΠΈ
ОбновлСниС: websocket
ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅: ОбновлСниС
Sec-WebSocket-Accept: fA9dggdnMPU79lJgAE3W4TRnyDM =
  
  • ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅: ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅
    • ΠŸΠΎΠ΄Ρ‚Π²Π΅Ρ€ΠΆΠ΄Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ соСдинСниС Π±Ρ‹Π»ΠΎ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΎ.
  • ОбновлСниС: websocket
    • ΠŸΠΎΠ΄Ρ‚Π²Π΅Ρ€ΠΆΠ΄Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ соСдинСниС Π±Ρ‹Π»ΠΎ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΎ.
  • Sec-WebSocket-Accept : fA9dggdnMPU79lJgAE3W4TRnyDM = `
    • Sec-WebSocket-Accept ΠΈΠΌΠ΅Π΅Ρ‚ ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²ΠΊΡƒ base64, Ρ…Π΅ΡˆΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ SHA-1. Π’Ρ‹
      ΡΠ³Π΅Π½Π΅Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ это Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΡƒΡ‚Π΅ΠΌ объСдинСния ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ² Sec-WebSocket-Key
      nonce ΠΈ статичСскоС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ 258EAFA5-E914-47DA-95CA-C5AB0DC85B11
      ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΎ Π² RFC 6455. Π₯отя Sec-WebSocket-Key ΠΈ Sec-WebSocket-Accept каТутся слоТными, ΠΎΠ½ΠΈ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‚, Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ ΠΎΠ±Π°
      ΠΊΠ»ΠΈΠ΅Π½Ρ‚ ΠΈ сСрвСр ΠΌΠΎΠ³ΡƒΡ‚ Π·Π½Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΈΡ… ΠΊΠΎΠ»Π»Π΅Π³Π° ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚
      WebSockets.ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ WebSocket ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ HTTP-соСдинСниС, Ρ‚Π°ΠΌ
      ΡΠ²Π»ΡΡŽΡ‚ΡΡ ΠΏΠΎΡ‚Π΅Π½Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹ΠΌΠΈ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°ΠΌΠΈ бСзопасности, Ссли любая ΠΈΠ· сторон ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚ WebSocket
      Π΄Π°Π½Π½Ρ‹Π΅ ΠΊΠ°ΠΊ HTTP-запрос.

ПослС Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ ΠΎΡ‚Π²Π΅Ρ‚ сСрвСра, соСдинСниС WebSocket
ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π½Π°Ρ‡Π°Ρ‚ΡŒ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Ρƒ Π΄Π°Π½Π½Ρ‹Ρ….

ΠŸΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» WebSocket

WebSocket — это ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» с Ρ„Ρ€Π΅ΠΉΠΌΠ°ΠΌΠΈ , Ρ‡Ρ‚ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚ Π΄Π°Π½Π½Ρ‹Ρ… (сообщСниС)
дСлится Π½Π° нСсколько дискрСтных частСй, Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ…
Π·Π°ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²Π°Π½ΠΎ Π² ΠΊΠ°Π΄Ρ€Π΅.ΠšΠ°Π΄Ρ€ Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ Ρ‚ΠΈΠΏ ΠΊΠ°Π΄Ρ€Π°, Π΄Π»ΠΈΠ½Ρƒ ΠΏΠΎΠ»Π΅Π·Π½ΠΎΠΉ Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ,
ΠΈ Ρ‡Π°ΡΡ‚ΡŒ Π΄Π°Π½Π½Ρ‹Ρ…. ΠžΠ±Π·ΠΎΡ€ ΠΊΠ°Π΄Ρ€Π° ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ Π² RFC.
6455 ΠΈ воспроизвСдСно
Π’ΠΎΡ‚.

  0 1 2 3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ - + - + - + - + ------- + - + ------------- + ----------------- -------------- +
| F | R | R | R | ΠΊΠΎΠ΄ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ | M | Π”Π»ΠΈΠ½Π° ΠΏΠΎΠ»Π΅Π·Π½ΠΎΠΉ Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ | УвСличСнная Π΄Π»ΠΈΠ½Π° ΠΏΠΎΠ»Π΅Π·Π½ΠΎΠΉ Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ |
| I | S | S | S | (4) | A | (7) | (16/64) |
| N | V | V | V | | S | | (Ссли полСзная Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠ° len == 126/127) |
| | 1 | 2 | 3 | | K | | |
+ - + - + - + - + ------- + - + ------------- + - - - - - - - - - - - - - - - +
| УвСличСнная Π΄Π»ΠΈΠ½Π° ΠΏΠΎΠ»Π΅Π·Π½ΠΎΠΉ Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ продолТаСтся, Ссли полСзная Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠ° len == 127 |
+ - - - - - - - - - - - - - - - + ------------------------------- +
| | ΠœΠ°ΡΠΊΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ ΠΊΠ»ΡŽΡ‡, Ссли МАБКА установлСна ​​в 1 |
+ ------------------------------- + ----------------- -------------- +
| ΠœΠ°ΡΠΊΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ ΠΊΠ»ΡŽΡ‡ (ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ΅Π½ΠΈΠ΅) | Π”Π°Π½Π½Ρ‹Π΅ ΠΏΠΎΠ»Π΅Π·Π½ΠΎΠΉ Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ |
+ -------------------------------- - - - - - - - - - - - - - - - - +
: Π”Π°Π½Π½Ρ‹Π΅ ΠΏΠΎΠ»Π΅Π·Π½ΠΎΠΉ Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ΅Π½ΠΈΠ΅...:
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| Π”Π°Π½Π½Ρ‹Π΅ ΠΏΠΎΠ»Π΅Π·Π½ΠΎΠΉ Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ΅Π½ΠΈΠ΅ ... |
+ ------------------------------------------------- -------------- +
  

Π― Π½Π΅ Π±ΡƒΠ΄Ρƒ здСсь ΠΎΡΡ‚Π°Π½Π°Π²Π»ΠΈΠ²Π°Ρ‚ΡŒΡΡ Π½Π° всСх дСталях ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π° ΠΊΠ°Π΄Ρ€ΠΎΠ². ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ΡΡŒ ΠΊ RFC
6455 для получСния ΠΏΠΎΠ»Π½ΠΎΠΉ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ. Π‘ΠΊΠΎΡ€Π΅Π΅,
Π― расскаТу ΠΎ самых Π²Π°ΠΆΠ½Ρ‹Ρ… ΠΌΠΎΠΌΠ΅Π½Ρ‚Π°Ρ…, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΌΡ‹ ΠΌΠΎΠ³Π»ΠΈ ΠΏΠΎΠ½ΡΡ‚ΡŒ
ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π° WebSocket.

Π Π΅Π±Ρ€ΠΎ-Π±ΠΈΡ‚

ΠŸΠ΅Ρ€Π²Ρ‹ΠΉ Π±ΠΈΡ‚ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° WebSocket — это Π±ΠΈΡ‚ Fin.Π­Ρ‚ΠΎΡ‚ Π±ΠΈΡ‚ устанавливаСтся, Ссли
этот Ρ„Ρ€Π΅ΠΉΠΌ — послСдниС Π΄Π°Π½Π½Ρ‹Π΅ для Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ этого сообщСния.

Π‘ΠΈΡ‚Ρ‹ RSV1, RSV2, RSV3

Π­Ρ‚ΠΈ Π±ΠΈΡ‚Ρ‹ Π·Π°Ρ€Π΅Π·Π΅Ρ€Π²ΠΈΡ€ΠΎΠ²Π°Π½Ρ‹ для использования Π² Π±ΡƒΠ΄ΡƒΡ‰Π΅ΠΌ.

ΠΊΠΎΠ΄ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ

Π£ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΊΠ°Π΄Ρ€Π° Π΅ΡΡ‚ΡŒ ΠΊΠΎΠ΄ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ опрСдСляСт, ΠΊΠ°ΠΊ ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ
Π΄Π°Π½Π½Ρ‹Π΅ ΠΏΠΎΠ»Π΅Π·Π½ΠΎΠΉ Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ.

Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΊΠΎΠ΄Π° ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ ОписаниС
0x00 Π­Ρ‚ΠΎΡ‚ ΠΊΠ°Π΄Ρ€ ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ°Π΅Ρ‚ ΠΏΠΎΠ»Π΅Π·Π½ΡƒΡŽ Π½Π°Π³Ρ€ΡƒΠ·ΠΊΡƒ ΠΈΠ· ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅Π³ΠΎ ΠΊΠ°Π΄Ρ€Π°.
0x01 ΠžΠ±ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚ тСкстовый Ρ„Ρ€Π΅ΠΉΠΌ.ВСкстовыС Ρ„Ρ€Π΅ΠΉΠΌΡ‹ Π΄Π΅ΠΊΠΎΠ΄ΠΈΡ€ΡƒΡŽΡ‚ΡΡ сСрвСром Π² ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²ΠΊΠ΅ UTF-8.
0x02 ΠžΠ±ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚ Π΄Π²ΠΎΠΈΡ‡Π½Ρ‹ΠΉ Ρ„Ρ€Π΅ΠΉΠΌ. Π”Π²ΠΎΠΈΡ‡Π½Ρ‹Π΅ Ρ„Ρ€Π΅ΠΉΠΌΡ‹ Π΄ΠΎΡΡ‚Π°Π²Π»ΡΡŽΡ‚ΡΡ сСрвСром Π±Π΅Π· ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ.
0x03-0x07 Π—Π°Ρ€Π΅Π·Π΅Ρ€Π²ΠΈΡ€ΠΎΠ²Π°Π½ΠΎ для использования Π² Π±ΡƒΠ΄ΡƒΡ‰Π΅ΠΌ.
0x08 ΠžΠ±ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Ρ…ΠΎΡ‡Π΅Ρ‚ Π·Π°ΠΊΡ€Ρ‹Ρ‚ΡŒ соСдинСниС.
0x09 Π€Ρ€Π΅ΠΉΠΌ ping. Π‘Π»ΡƒΠΆΠΈΡ‚ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠΎΠΌ подтвСрТдСния связи, Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΌ, Ρ‡Ρ‚ΠΎ соСдинСниС всС Π΅Ρ‰Π΅ ΠΆΠΈΠ²ΠΎ. ΠŸΠΎΠ»ΡƒΡ‡Π°Ρ‚Π΅Π»ΡŒ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΎΡ‚Π²Π΅Ρ‚ΠΈΡ‚ΡŒ ΠΏΠΎΠ½Π³ΠΎΠΌ.
0x0a Π Π°ΠΌΠ° для ΠΏΠΎΠ½Π³Π°. Π‘Π»ΡƒΠΆΠΈΡ‚ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠΎΠΌ подтвСрТдСния связи, Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΌ, Ρ‡Ρ‚ΠΎ соСдинСниС всС Π΅Ρ‰Π΅ ΠΆΠΈΠ²ΠΎ. ΠŸΠΎΠ»ΡƒΡ‡Π°Ρ‚Π΅Π»ΡŒ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΎΡ‚Π²Π΅Ρ‚ΠΈΡ‚ΡŒ Ρ„Ρ€Π΅ΠΉΠΌΠΎΠΌ ping.
0x0b-0x0f Π—Π°Ρ€Π΅Π·Π΅Ρ€Π²ΠΈΡ€ΠΎΠ²Π°Π½ΠΎ для использования Π² Π±ΡƒΠ΄ΡƒΡ‰Π΅ΠΌ.
Маска

Установка этого Π±ΠΈΡ‚Π° Π² 1 Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ маскированиС . WebSockets Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚, Ρ‡Ρ‚ΠΎΠ±Ρ‹ всС
полСзная Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠ° обфусцирована с использованиСм случайного ΠΊΠ»ΡŽΡ‡Π° (маски), Π²Ρ‹Π±Ρ€Π°Π½Π½ΠΎΠ³ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ.
ΠšΠ»ΡŽΡ‡ маскировки ΠΎΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΠ΅Ρ‚ΡΡ с Π΄Π°Π½Π½Ρ‹ΠΌΠΈ ΠΏΠΎΠ»Π΅Π·Π½ΠΎΠΉ Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ XOR.
ΠΏΠ΅Ρ€Π΅Π΄ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΎΠΉ Π΄Π°Π½Π½Ρ‹Ρ… Π² ΠΏΠΎΠ»Π΅Π·Π½ΡƒΡŽ Π½Π°Π³Ρ€ΡƒΠ·ΠΊΡƒ.Π­Ρ‚Π° маскировка ΠΏΡ€Π΅Π΄ΠΎΡ‚Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ появлСниС кСшСй.
нСвСрная интСрпрСтация Ρ„Ρ€Π΅ΠΉΠΌΠΎΠ² WebSocket ΠΊΠ°ΠΊ ΠΊΡΡˆΠΈΡ€ΡƒΠ΅ΠΌΡ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ…. ΠŸΠΎΡ‡Π΅ΠΌΡƒ ΠΌΡ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΏΡ€Π΅Π΄ΠΎΡ‚Π²Ρ€Π°Ρ‰Π°Ρ‚ΡŒ
ΠΊΠ΅ΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π΄Π°Π½Π½Ρ‹Ρ… WebSocket? Π‘Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡ‚ΡŒ.

ΠŸΡ€ΠΈ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π° WebSocket Π±Ρ‹Π»ΠΎ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ, Ρ‡Ρ‚ΠΎ Ссли
развСртываСтся скомпромСтированный сСрвСр, ΠΈ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρ‹ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π°ΡŽΡ‚ΡΡ ΠΊ этому сСрвСру, ΠΎΠ½
ΠΌΠΎΠΆΠ½ΠΎ ΠΈΠΌΠ΅Ρ‚ΡŒ ΠΏΡ€ΠΎΠΌΠ΅ΠΆΡƒΡ‚ΠΎΡ‡Π½Ρ‹Π΅ прокси ΠΈΠ»ΠΈ кСш инфраструктуры
ΠΎΡ‚Π²Π΅Ρ‚Ρ‹ скомпромСтированного сСрвСра, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π±ΡƒΠ΄ΡƒΡ‰ΠΈΠ΅ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρ‹, Π·Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°ΡŽΡ‰ΠΈΠ΅
data ΠΏΠΎΠ»ΡƒΡ‡Π°ΡŽΡ‚ Π½Π΅Π²Π΅Ρ€Π½Ρ‹ΠΉ ΠΎΡ‚Π²Π΅Ρ‚. Π­Ρ‚Π° Π°Ρ‚Π°ΠΊΠ° называСтся cache.
ΠΎΡ‚Ρ€Π°Π²Π»Π΅Π½ΠΈΠ΅
, ΠΈ являСтся Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠΌ Ρ‚ΠΎΠ³ΠΎ Ρ„Π°ΠΊΡ‚Π°, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ Π½Π΅ ΠΌΠΎΠΆΠ΅ΠΌ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ, ΠΊΠ°ΠΊ
прокси-сСрвСры Π²Π΅Π΄ΡƒΡ‚ сСбя Π² Π΄ΠΈΠΊΠΎΠΉ ΠΏΡ€ΠΈΡ€ΠΎΠ΄Π΅.Π­Ρ‚ΠΎ особСнно ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°Ρ‚ΠΈΡ‡Π½ΠΎ
ΠΏΡ€ΠΈ Π²Π½Π΅Π΄Ρ€Π΅Π½ΠΈΠΈ Π½ΠΎΠ²ΠΎΠ³ΠΎ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π°, Ρ‚Π°ΠΊΠΎΠ³ΠΎ ΠΊΠ°ΠΊ WebSocket, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ с
ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰Π°Ρ инфраструктура ΠΈΠ½Ρ‚Π΅Ρ€Π½Π΅Ρ‚Π°.

Π”Π»ΠΈΠ½Π° ΠΏΠΎΠ»Π΅Π·Π½ΠΎΠΉ Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ

ПолС Payload len ΠΈ Extended payload length ΠΏΠΎΠ»Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ для
ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠ±Ρ‰ΡƒΡŽ Π΄Π»ΠΈΠ½Ρƒ Π΄Π°Π½Π½Ρ‹Ρ… ΠΏΠΎΠ»Π΅Π·Π½ΠΎΠΉ Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ для этого ΠΊΠ°Π΄Ρ€Π°. Если полСзная Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠ°
Π΄Π°Π½Π½Ρ‹Π΅ нСбольшиС (ΠΌΠ΅Π½Π΅Π΅ 126 Π±Π°ΠΉΡ‚), Π΄Π»ΠΈΠ½Π° кодируСтся Π² ΠΏΠΎΠ»Π΅ Payload len . По ΠΌΠ΅Ρ€Π΅ роста Π΄Π°Π½Π½Ρ‹Ρ… ΠΏΠΎΠ»Π΅Π·Π½ΠΎΠΉ Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ поля для
Π·Π°ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π΄Π»ΠΈΠ½Ρƒ ΠΏΠΎΠ»Π΅Π·Π½ΠΎΠΉ Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ.

ΠœΠ°ΡΠΊΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ ΠΊΠ»ΡŽΡ‡

Как ΠΎΠ±ΡΡƒΠΆΠ΄Π°Π»ΠΎΡΡŒ с Π±ΠΈΡ‚ΠΎΠΌ MASK , всС ΠΊΠ°Π΄Ρ€Ρ‹, ΠΎΡ‚ΠΏΡ€Π°Π²Π»Π΅Π½Π½Ρ‹Π΅ ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° ΠΊ
сСрвСры ΠΌΠ°ΡΠΊΠΈΡ€ΡƒΡŽΡ‚ΡΡ 32-Π±ΠΈΡ‚Π½Ρ‹ΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ, содСрТащимся Π² ΠΊΠ°Π΄Ρ€Π΅.
Π­Ρ‚ΠΎ ΠΏΠΎΠ»Π΅ присутствуСт, Ссли Π±ΠΈΡ‚ маски установлСн Π² 1, ΠΈ отсутствуСт, Ссли
Π±ΠΈΡ‚ маски установлСн Π½Π° 0.

Π”Π°Π½Π½Ρ‹Π΅ ΠΏΠΎΠ»Π΅Π·Π½ΠΎΠΉ Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ

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

Π—Π°ΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ соСдинСния WebSocket — Ρ€ΡƒΠΊΠΎΠΏΠΎΠΆΠ°Ρ‚ΠΈΠ΅ закрытия WebSocket

Π§Ρ‚ΠΎΠ±Ρ‹ Π·Π°ΠΊΡ€Ρ‹Ρ‚ΡŒ соСдинСниС WebSocket, отправляСтся Π·Π°ΠΊΡ€Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΉ ΠΊΠ°Π΄Ρ€ (ΠΊΠΎΠ΄ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ 0x08 ).
Помимо ΠΊΠΎΠ΄Π° ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ, Π·Π°ΠΊΡ€Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΉ ΠΊΠ°Π΄Ρ€ ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ Ρ‚Π΅Π»ΠΎ, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅
ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ ΠΏΡ€ΠΈΡ‡ΠΈΠ½Ρƒ закрытия. Если ΠΎΠ΄Π½Π° ΠΈΠ· сторон соСдинСния ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚
Π·Π°ΠΊΡ€Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΉ ΠΊΠ°Π΄Ρ€, ΠΎΠ½ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ Π·Π°ΠΊΡ€Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΉ ΠΊΠ°Π΄Ρ€ Π² ΠΎΡ‚Π²Π΅Ρ‚, ΠΈ большС Π½ΠΈΠΊΠ°ΠΊΠΈΡ… Π΄Π°Π½Π½Ρ‹Ρ…
Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ ΠΎΡ‚ΠΏΡ€Π°Π²Π»Π΅Π½Ρ‹ Ρ‡Π΅Ρ€Π΅Π· соСдинСниС. ПослС получСния ΠΊΠ°Π΄Ρ€Π° закрытия
ΠΎΠ±Π΅ стороны Ρ€Π°Π·Ρ€Ρ‹Π²Π°ΡŽΡ‚ TCP-соСдинСниС.Π‘Π΅Ρ€Π²Π΅Ρ€ всСгда
ΠΈΠ½ΠΈΡ†ΠΈΠΈΡ€ΡƒΠ΅Ρ‚ Π·Π°ΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ TCP-соСдинСния.

Π”ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ ссылки

Π­Ρ‚Π° ΡΡ‚Π°Ρ‚ΡŒΡ прСдставляСт собой Π²Π²Π΅Π΄Π΅Π½ΠΈΠ΅ Π² ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» WebSocket ΠΈ
ΠΏΠΎΠΊΡ€Ρ‹Π²Π°Π΅Ρ‚ ΠΌΠ½ΠΎΠ³ΠΎ Π·Π΅ΠΌΠ»ΠΈ. Однако ΠΏΠΎΠ»Π½Ρ‹ΠΉ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» содСрТит большС Π΄Π΅Ρ‚Π°Π»Π΅ΠΉ, Ρ‡Π΅ΠΌ
Ρ‡Ρ‚ΠΎ я ΠΌΠΎΠ³ Π±Ρ‹ Π²ΠΏΠΈΡΠ°Ρ‚ΡŒ Π² этот пост Π² Π±Π»ΠΎΠ³Π΅. Если Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ ΡƒΠ·Π½Π°Ρ‚ΡŒ большС, Ρ‚Π°ΠΌ
Π΅ΡΡ‚ΡŒ нСсколько ΠΎΡ‚Π»ΠΈΡ‡Π½Ρ‹Ρ… рСсурсов Π½Π° Π²Ρ‹Π±ΠΎΡ€:

Π‘ΠΌ. Π’Π°ΠΊΠΆΠ΅

.

WebSocket — Π²Π΅Π±-тСхнология для Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠ²

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
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°

.

WebSocket API (WebSockets) — Π²Π΅Π±-тСхнология для Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠ²

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
Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

Π”Π°

.

Начало Ρ€Π°Π±ΠΎΡ‚Ρ‹ — докумСнтация ΠΏΠΎ websockets 8.1

ВрСбования

Π²Π΅Π±-сокСтов Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ Python β‰₯ 3.6.1.

По возмоТности слСдуСт ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ послСднюю Π²Π΅Ρ€ΡΠΈΡŽ Python. Если Π²Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚Π΅
старая вСрсия, ΠΈΠΌΠ΅ΠΉΡ‚Π΅ Π² Π²ΠΈΠ΄Ρƒ, Ρ‡Ρ‚ΠΎ для ΠΊΠ°ΠΆΠ΄ΠΎΠΉ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΉ вСрсии (3.x) Ρ‚ΠΎΠ»ΡŒΠΊΠΎ послСдняя
Выпуск bugfix (3.x.y) ΠΎΡ„ΠΈΡ†ΠΈΠ°Π»ΡŒΠ½ΠΎ поддСрТиваСтся.

Установка

УстановитС Π²Π΅Π±-сокСтов с:

Π‘Π°Π·ΠΎΠ²Ρ‹ΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€

Π’ΠΎΡ‚ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ сСрвСра WebSocket.

Π‘Ρ‡ΠΈΡ‚Ρ‹Π²Π°Π΅Ρ‚ имя ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°, отправляСт привСтствиС ΠΈ Π·Π°ΠΊΡ€Ρ‹Π²Π°Π΅Ρ‚ соСдинСниС.

 #! / Usr / bin / env python

# ΠŸΡ€ΠΈΠΌΠ΅Ρ€ сСрвСра WS

ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ asyncio
ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π²Π΅Π±-сокСты

async def ΠΏΡ€ΠΈΠ²Π΅Ρ‚ (Π²Π΅Π±-сокСт, ΠΏΡƒΡ‚ΡŒ):
    name = ΠΆΠ΄Π°Ρ‚ΡŒ websocket.recv ()
    print (f "<{имя}")

    welcome = f "ΠŸΡ€ΠΈΠ²Π΅Ρ‚, {имя}!"

    ΠΆΠ΄Π°Ρ‚ΡŒ websocket.send (привСтствиС)
    print (f "> {привСтствиС}")

start_server = websockets.serve (ΠΏΡ€ΠΈΠ²Π΅Ρ‚, "localhost", 8765)

asyncio.get_event_loop (). run_until_complete (Π½Π°Ρ‡Π°Π»ΡŒΠ½Ρ‹ΠΉ_сСрвСр)
asyncio.get_event_loop (). run_forever ()
 

На сторонС сСрвСра websockets выполняСт сопрограмму ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ° hello
ΠΎΠ΄ΠΈΠ½ Ρ€Π°Π· для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ WebSocket. Он Π·Π°ΠΊΡ€Ρ‹Π²Π°Π΅Ρ‚ соСдинСниС, ΠΊΠΎΠ³Π΄Π° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ
сопрограмма возвращаСтся.

Π’ΠΎΡ‚ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° WebSocket.

 #! / Usr / bin / env python

# ΠŸΡ€ΠΈΠΌΠ΅Ρ€ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° WS

ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ asyncio
ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π²Π΅Π±-сокСты

async def hello ():
    uri = "ws: // localhost: 8765"
    async с websockets.connect (uri) как websocket:
        name = input ("Как вас Π·ΠΎΠ²ΡƒΡ‚?")

        ΠΆΠ΄Ρƒ Π²Π΅Π±-сокСта.ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ (имя)
        print (f "> {имя}")

        привСтствиС = ΠΆΠ΄Π°Ρ‚ΡŒ websocket.recv ()
        print (f "<{привСтствиС}")

asyncio.get_event_loop (). run_until_complete (ΠΏΡ€ΠΈΠ²Π΅Ρ‚ ())
 

ИспользованиС connect () Π² качСствС асинхронного диспСтчСра контСкста обСспСчиваСт
соСдинСниС закрываСтся ΠΏΠ΅Ρ€Π΅Π΄ Π²Ρ‹Ρ…ΠΎΠ΄ΠΎΠΌ ΠΈΠ· сопрограммы hello .

БСзопасный ΠΏΡ€ΠΈΠΌΠ΅Ρ€

Secure WebSocket-соСдинСния ΠΏΠΎΠ²Ρ‹ΡˆΠ°ΡŽΡ‚ ΠΊΠΎΠ½Ρ„ΠΈΠ΄Π΅Π½Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ, Π° Ρ‚Π°ΠΊΠΆΠ΅ Π½Π°Π΄Π΅ΠΆΠ½ΠΎΡΡ‚ΡŒ
ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ ΠΎΠ½ΠΈ ΡΠ½ΠΈΠΆΠ°ΡŽΡ‚ риск Π²ΠΌΠ΅ΡˆΠ°Ρ‚Π΅Π»ΡŒΡΡ‚Π²Π° ΠΏΠ»ΠΎΡ…ΠΈΡ… прокси.

ΠŸΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» WSS для WS Ρ‚ΠΎ ΠΆΠ΅, Ρ‡Ρ‚ΠΎ HTTPS для HTTP: соСдинСниС Π·Π°ΡˆΠΈΡ„Ρ€ΠΎΠ²Π°Π½ΠΎ
с Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡ‚ΡŒΡŽ транспортного уровня (TLS), ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ часто Π½Π°Π·Ρ‹Π²Π°ΡŽΡ‚ бСзопасным
Π£Ρ€ΠΎΠ²Π΅Π½ΡŒ сокСтов (SSL). WSS Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ сСртификатов TLS, Ρ‚Π°ΠΊΠΈΡ… ΠΊΠ°ΠΊ HTTPS.

Π’ΠΎΡ‚ ΠΊΠ°ΠΊ ΠΌΠΎΠΆΠ½ΠΎ Π°Π΄Π°ΠΏΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ сСрвСра для обСспСчСния бСзопасных соСдинСний. Π£Π²ΠΈΠ΄Π΅Ρ‚ΡŒ
докумСнтация модуля ssl для бСзопасной настройки контСкста.

 #! / Usr / bin / env python

# ΠŸΡ€ΠΈΠΌΠ΅Ρ€ сСрвСра WSS (WS over TLS) с самоподписанным сСртификатом

ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ asyncio
ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ pathlib
ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ssl
ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π²Π΅Π±-сокСты

async def ΠΏΡ€ΠΈΠ²Π΅Ρ‚ (Π²Π΅Π±-сокСт, ΠΏΡƒΡ‚ΡŒ):
    name = ΠΆΠ΄Π°Ρ‚ΡŒ Π²Π΅Π±-сокСта.recv ()
    print (f "<{имя}")

    welcome = f "ΠŸΡ€ΠΈΠ²Π΅Ρ‚, {имя}!"

    ΠΆΠ΄Π°Ρ‚ΡŒ websocket.send (привСтствиС)
    print (f "> {привСтствиС}")

ssl_context = ssl.SSLContext (ssl.PROTOCOL_TLS_SERVER)
localhost_pem = pathlib.Path (__ Ρ„Π°ΠΉΠ» __). with_name ("localhost.pem")
ssl_context.load_cert_chain (localhost_pem)

start_server = websockets.serve (
    ΠΏΡ€ΠΈΠ²Π΅Ρ‚, "localhost", 8765, ssl = ssl_context
)

asyncio.get_event_loop (). run_until_complete (Π½Π°Ρ‡Π°Π»ΡŒΠ½Ρ‹ΠΉ_сСрвСр)
asyncio.get_event_loop (). run_forever ()
 

Π’ΠΎΡ‚ ΠΊΠ°ΠΊ Π°Π΄Π°ΠΏΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°.

 #! / Usr / bin / env python

# ΠŸΡ€ΠΈΠΌΠ΅Ρ€ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° WSS (WS over TLS) с самоподписанным сСртификатом

ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ asyncio
ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ pathlib
ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ssl
ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π²Π΅Π±-сокСты

ssl_context = ssl.SSLContext (ssl.PROTOCOL_TLS_CLIENT)
localhost_pem = pathlib.Path (__ Ρ„Π°ΠΉΠ» __). with_name ("localhost.pem")
ssl_context.load_verify_locations (localhost_pem)

async def hello ():
    uri = "wss: // localhost: 8765"
    асинхронный с websockets.connect (
        uri, ssl = ssl_context
    ) ΠΊΠ°ΠΊ Π²Π΅Π±-сокСт:
        name = input ("Как вас Π·ΠΎΠ²ΡƒΡ‚?")

        ΠΆΠ΄Ρƒ Π²Π΅Π±-сокСта.ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ (имя)
        print (f "> {имя}")

        привСтствиС = ΠΆΠ΄Π°Ρ‚ΡŒ websocket.recv ()
        print (f "<{привСтствиС}")

asyncio.get_event_loop (). run_until_complete (ΠΏΡ€ΠΈΠ²Π΅Ρ‚ ())
 

Π­Ρ‚ΠΎΠΌΡƒ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ Π½ΡƒΠΆΠ΅Π½ контСкст, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ сСрвСр ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ ΡΠ°ΠΌΠΎΠ·Π°Π²Π΅Ρ€ΡΡŽΡ‰ΠΈΠΉ сСртификат.

ΠšΠ»ΠΈΠ΅Π½Ρ‚ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ ΠΊ Π·Π°Ρ‰ΠΈΡ‰Π΅Π½Π½ΠΎΠΌΡƒ сСрвСру WebSocket с Π΄Π΅ΠΉΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΌ сСртификатом.
(Ρ‚. Π΅. подписанный Ρ†Π΅Π½Ρ‚Ρ€ΠΎΠΌ сСртификации, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌΡƒ довСряСт ваша установка Python), ΠΌΠΎΠΆΠ½ΠΎ просто ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ
ssl = True ΠΎΡ‚ Π΄ΠΎ connect () вмСсто создания контСкста.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ Π½Π° основС Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π°

Π’ΠΎΡ‚ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ Π·Π°ΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ сСрвСр WebSocket ΠΈ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒΡΡ ΠΈΠ· Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π°.

ЗапуститС этот скрипт Π² консоли:

 #! / Usr / bin / env python

# WS-сСрвСр, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ отправляСт сообщСния Ρ‡Π΅Ρ€Π΅Π· случайныС ΠΏΡ€ΠΎΠΌΠ΅ΠΆΡƒΡ‚ΠΊΠΈ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ

ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ asyncio
Π΄Π°Ρ‚Π° ΠΈ врСмя ΠΈΠΌΠΏΠΎΡ€Ρ‚Π°
случайный ΠΈΠΌΠΏΠΎΡ€Ρ‚
ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π²Π΅Π±-сокСты

async def time (Π²Π΅Π±-сокСт, ΠΏΡƒΡ‚ΡŒ):
    Π² Ρ‚ΠΎ врСмя ΠΊΠ°ΠΊ True:
        сСйчас = datetime.datetime.ut 

.

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

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