--- title: Написание клиентских приложений с помощью веб-сокетов slug: Web/API/WebSockets_API/Writing_WebSocket_client_applications translation_of: Web/API/WebSockets_API/Writing_WebSocket_client_applications original_slug: WebSockets/Writing_WebSocket_client_applications ---
Веб-сокеты - технология, которая позволяет открыть интерактивную сессию общения между браузером пользователя и сервером. Соединяясь через веб-сокеты, веб-приложения могут осуществлять взаимодействие в реальном времени вместо того, чтобы делать запросы к клиенту о входящих/исходящих изменениях.
API веб-сокетов доступно в Javascript коде, область видимости которого включает объект DOM {{ domxref("Window") }} или любой объект, реализующий {{ domxref("WorkerUtils") }}; это означает, что вы можете использовать Web Workers.
Чтобы общаться через протокол веб-сокетов необходимо создать объект WebSocket
; при его создании автоматически происходит попытка открыть соединение с сервером.
Конструктор WebSocket принимает один обязательный и один необязательный параметр:
WebSocket WebSocket( in DOMString url, in optional DOMString protocols ); WebSocket WebSocket( in DOMString url, in optional DOMString[] protocols );
url
protocols
{{ optional_inline() }}В конструкторе могут возникать следующие исключения:
SECURITY_ERR
Если ошибка случается во время попытки подключения, то в объект WebSocket
сначала посылается простое событие с именем «error» (таким образом, задействуя обработчик onerror
), потом - событие CloseEvent
(таким образом, задействуя обработчик onclose
) чтобы обозначить причину закрытия соединения.
Однако, начиная с версии Firefox 11, типичным является получение в консоль от платформы Mozilla расширенного сообщения об ошибке и кода завершения, как то определено в RFC 6455, Section 7.4 посредством CloseEvent
.
Этот простой пример создаёт новый WebSocket, подключаемый к серверу ws://www.example.com/socketserver
. В данном примере в конструктор сокета в качестве дополнительного параметра передаётся пользовательский протокол "protocolOne", хотя эта часть может быть опущена.
var exampleSocket = new WebSocket("ws://www.example.com/socketserver", "protocolOne");
После выполнения функции, exampleSocket
.readyState
будет иметь значение CONNECTING
. readyState
изменится на OPEN
как только соединение станет готовым к передаче данных.
Если нужно открыть соединение, поддерживающее несколько протоколов, можно передать массив протоколов:
var exampleSocket = new WebSocket("ws://www.example.com/socketserver", ["protocolOne", "protocolTwo"]);
Когда соединение установлено (что соответствует, readyState
OPEN
), exampleSocket.protocol
сообщит, какой протокол выбрал сервер.
В приведенных выше примерах ws
заменяет http
, аналогично wss
заменяет https
. Установка соединения через WebSocket зависит от механизма обновления HTTP, таким образом запрос на обновление неявный, когда мы обращаемся к серверу HTTP с помощью ws://www.example.com
или wss://www.example.com
.
Однажды открыв соединение, вы можете передавать данные на сервер. Для осуществления этого, вызовите метод send()
объекта WebSocket
для каждого сообщение, которое желаете отправить:
exampleSocket.send("Вот текст, который будет отправлен серверу.");
Вы можете пересылать данные в виде строки, {{ domxref("Blob") }}, так и ArrayBuffer
.
Так как установка соедиения асинхронна и подвержена сбоям, то нет никакой гарантии, что вызов метода send()
, после создания объекта WebSocket, будет завершен успешно. По крайней мере, мы можем быть уверены, что попытка отправить данные будет иметь место только после того, как соединение будет установлено, определив обработчик onopen
для выполнения этого действия:
exampleSocket.onopen = function (event) { exampleSocket.send("Вот текст, который будет отправлен серверу."); };
Одна удобная вещь которую вы можете сделать, это использовать JSON для пересылки сложных данных на сервер. Например, приложение-чат может взаимодействовать с сервером, используя протокол, реализованный с использованием пакетов данных, инкапсулированных в JSON:
// Отправьте текст всем пользователям через сервер function sendText() { // Создайте объект содержащий данные, необходимые серверу для обрабоки сообщения от клиента чата. var msg = { type: "message", text: document.getElementById("text").value, id: clientID, date: Date.now() }; // Отправьте объект в виде JSON строки. exampleSocket.send(JSON.stringify(msg)); // Очистите элемент ввода текста, чтобы получить следующую строку текста от пользователя. document.getElementById("text").value = ""; }
WebSockets — это API, управляемый событиями; когда сообщения получены, событие "message" доставлено в функцию onmessage
. Чтобы начать прослушивание входящих данных, вы можете сделать что-то вроде этого:
exampleSocket.onmessage = function (event) { console.log(event.data); }
Давайте рассмотрим клиентское приложение чата, которое впервые упоминалось в разделе {{ anch("Использование JSON для передачи объектов") }}. Есть разные типы пакетов данных, которые может получить клиент, например:
Код обрабатывающий эти входящие сообщения, может выглядеть так:
exampleSocket.onmessage = function(event) { var f = document.getElementById("chatbox").contentDocument; var text = ""; var msg = JSON.parse(event.data); var time = new Date(msg.date); var timeStr = time.toLocaleTimeString(); switch(msg.type) { case "id": clientID = msg.id; setUsername(); break; case "username": text = "<b>User <em>" + msg.name + "</em> signed in at " + timeStr + "</b><br>"; break; case "message": text = "(" + timeStr + ") <b>" + msg.name + "</b>: " + msg.text + "<br>"; break; case "rejectusername": text = "<b>Your username has been set to <em>" + msg.name + "</em> because the name you chose is in use.</b><br>" break; case "userlist": var ul = ""; for (i=0; i < msg.users.length; i++) { ul += msg.users[i] + "<br>"; } document.getElementById("userlistbox").innerHTML = ul; break; } if (text.length) { f.write(text); document.getElementById("chatbox").contentWindow.scrollByPages(1); } };
Здесь мы используем JSON.parse()
чтобы преобразовать JSON строку в объект, затем обработайте его.
Текст, полученный через WebSocket должен иметь кодировку UTF-8
До Gecko 9.0 {{ geckoRelease("9.0") }}, некоторые не символьные значения в допустимом тексте UTF-8 могут привести к разрыву соединения. Теперь Gecko допускает эти значения.
Когда вы закончили использовать соединение WebSocket, закройте его используя метод close()
:
exampleSocket.close();
Перед попыткой закрыть соединение может быть полезно проверить атрибут bufferedAmount
чтобы определить, не переданы ли еще какие-либо данные по сети.
WebSocket не следует использовать в среде со смешанным содержимым: то есть вы не должны открывать незащищенное соединение WebSocket со страницы, загруженной с использованием HTTPS, или наоборот. Фактически, некоторые браузеры явно запрещают это, например Firefox 8 и выше.
{{ languages ( {"zh-tw": "zh_tw/WebSockets/Writing_WebSocket_client_applications"} ) }}