Реализация сервера на PHP
Исходники простого WebSocket echo-сервера выложил сюда.
Код хорошо документирован, но я всё же опишу некоторые тонкости реализации.
Чтобы «поднять» WebSocket сервер нужно создать обычный TCP-сервер.
В PHP TCP-сервер реализуется через «stream_socket» или через PHP расширение «sockets».
Различия между ними в том, что «stream_socket» работает на встроенных функциях PHP для работы с потоками, «sockets» же работает через модуль PHP и повторяет функции для работы с сокетами в языке «C».
Я выбрал «sockets».
Процесс реализован через «while» с задержкой 0.2 секунды.
Процесс не форкается и сообщения выбрасывает в консоль, поэтому запускать необходимо только через консоль.
Для того, чтобы обслуживать несколько клиентов одновременно, сокет делаю неблокирующим и через «socket_select»
каждые 0.2 секунды прослушиваю сокет.
При рукопожатии проверяю только наличие заголовков.
Фреймы парсю через «pack/unpack».
Сервер не понимает фрагментированных фреймов.
Сервер выдаёт только незамаскированные сообщения, т.к. некоторые браузеры не понимают замаскированных сообщений.
Сервер реагирует только на текстовые фреймы и фрейм закрытия соединения, бинарные фреймы не понимает.
Ну собственно всё, удачи в исследовании этого не простого протокола.
bind()¶
См.также
- http://unixhelp.ed.ac.uk/CGI/man-cgi?bind+2
Связывает сокет с конкретным адресом. Когда сокет создается при помощи socket(), он ассоциируется с некоторым семейством адресов, но не с конкретным адресом. До того как сокет сможет принять входящие соединения, он должен быть связан с адресом. bind() принимает три аргумента:
- sockfd — дескриптор, представляющий сокет при привязке
- serv_addr — указатель на структуру sockaddr, представляющую адрес, к которому привязываем.
- addrlen — поле socklen_t, представляющее длину структуры sockaddr.
Примечание
Возвращает 0 при успехе и −1 при возникновении ошибки.
Пример на Си
#include <sys/types.h> #include <sys/socket.h> int bind(int sockfd, const struct sockaddr *my_addr, socklen_t addrlen);
Пример на Python
server_address = ('localhost', 8080) sock_obj.bind(server_address) # Привязка адреса и порта к сокету.
Автоматическое получение имени хоста.
Разговор об отношениях
«Парень есть?» Что ответить?
Если у тебя есть парень, скажи, что да, есть. Но если не хочешь признаваться, потому что хочешь замутить и с этим парнем тоже, скажи, что нет. Или, например, Хочешь им стать? По приколу еще можно ответить А у тебя?
Что ответить бывшему?
Бывший парень пишет тебе. Что ему ответить? Ты не уверена. С одной стороны, хочется послать его подальше, с другой — вернуть приятные моменты (даже если ты не признаешься себе в этом). Что же делать? Если он хочет вернуть тебя, а ты в принципе допускаешь такую возможность, предложи встретиться и поговорить. Не раскрывай свои чувства. Если ты не хочешь его видеть, напиши, что пока не готова к разговору. А если ты уже встречаешься с другим и точно не хочешь бывшего, скажи, что счастлива, и чтобы он жил своей жизнью. Будь королевой!
«Я люблю тебя». Что написать в ответ?
Если парень подозрительно легко признается в своих чувствах, то учти, что его слова могут быть неправдой. Но если ты его любишь и уверена в нем, то ответь Я тоже (тебя люблю). Иначе, просто скажи, что тебе приятно.
SOCK_STREAM vs SOCK_DGRAM¶
См.также
- UDP
- TCP
Потоковый (SOCK_STREAM) | Дейтаграммный (SOCK_DGRAM) |
---|---|
Устанавливает соединение | Нет |
Гарантирует доставку данных | Нет в случае UDP |
Гарантирует порядок доставки пакетов | Нет в случае UDP |
Гарантирует целостность пакетов | Тоже |
Разбивает сообщение на пакеты | Нет |
Контролирует поток данных | Нет |
TCP гарантирует доставку пакетов, их очередность, автоматически разбивает
данные на пакеты и контролирует их передачу, в отличии от UDP.
Но при этом TCP работает медленнее за счет повторной передачи потерянных
пакетов и большему количеству выполняемых операций над пакетами. Поэтому
там где требуется гарантированная доставка (Веб-браузер, telnet, почтовый клиент) используется TCP, если же требуется передавать данные в реальном
времени (многопользовательские игры, видео, звук) используют UDP.
Принципы сокетов¶
Каждый процесс может создать слушающий сокет (серверный сокет) и привязать его
к какому-нибудь порту операционной системы (в UNIX непривилегированные
процессы не могут использовать порты меньше 1024). Слушающий процесс обычно
находится в цикле ожидания, то есть просыпается при появлении нового
соединения. При этом сохраняется возможность проверить наличие соединений на
данный момент, установить тайм-аут для операции и т.д.
Каждый сокет имеет свой адрес. ОС семейства UNIX могут поддерживать много
типов адресов, но обязательными являются INET-адрес и UNIX-адрес. Если
привязать сокет к UNIX-адресу, то будет создан специальный файл (файл сокета)
по заданному пути, через который смогут сообщаться любые локальные процессы
путём чтения/записи из него (см. Доменный сокет Unix). Сокеты типа INET
доступны из сети и требуют выделения номера порта.
Оставьте что-нибудь на память о себе
Даже самые маленькие и незначительные вещи напоминают нам о любимых людях и заставляют скучать. Что, если, убирая свою комнату, парень «случайно» наткнётся на вашу серёжку?
Это наверняка заставит его подумать о вас.
Просто оставьте какую-то свою личную вещь, будучи у него дома в гостях. Это должно быть что-то милое и неброское, чтобы сразу не заметил. Например, заколку для волос.
Не переусердствуйте в своём рвении, потому что, если оставите, например, зубную щетку, то это его попросту испугает. А вот очаровательная заколка для волос или серьга — сделают свое дело.
Как только он найдёт эту вещь, вспомнит о том, как скучает, как ему вас не хватает. Кстати, неплохо, если это будет ваш шарфик с ароматом его любимых духов. Ведь он пахнет вами, пахнет теми днями, когда вам было так здорово вместе…
Необязательно «забывать» что-то в доме. Можно и в машине, и на работе.
Если эти незамысловатые уловки работают, то грех было бы не воспользоваться.
Не бегите сразу же отвечать на его звонки и сообщения
Ваш первый импульс — немедленно ответить, когда парень пишет или звонит. Тем более, что вы так ждали, когда он это сделает, думали над тем, что напишет, что скажет…
Поверьте, если сразу же броситесь отвечать — парень немедленно поймёт, как вы ждали его весточки.
Поэтому покажите, что у вас есть дела поважнее, чем ждать, пока он примет решение. Тем более — переживать по этому поводу.
Парни обожают покорять вершины, и, проявив немного терпения, вы позволите ему почувствовать себя охотником, а вас — желанной добычей.
Когда он напишет или позвонит, по крайней мере, выдержите паузу. Это его только заведёт ещё больше.
На первый взгляд подобные игры могут показаться немного глупыми, но дело в том, что они работают. Так почему бы не использовать?
Слишком доступные девушки не привлекают парней. А вот загадка, таинственность, манят и притягивают.
«Я — не зануда, не зануда, не зануда!»
Вместо того, чтобы обижаться, злиться или еще как-то демонстрировать, что вопрос собеседника вас задел, начните ровным монотонным голосом отвечать. Самое главное — это детали. Излагайте мельчайшие подробности и начинайте очень издалека!
– Когда же ты выйдешь замуж?
– Астрологи говорят, что для заключения счастливого брака необходимо, чтобы асценденты у влюбленных сходились (не спрашивайте нас, что такое асценденты и должны ли они сходиться на самом деле — годится любая заумная теория, в которой ваш визави не слишком разбирается, хоть «звездограмма», хоть крутой поворот линии жизни, хоть индекс Наздака). И вот в тот момент, когда я пойму, что встретила свою вторую половинку и проверю, подходим ли мы друг другу (придется уточнить где и во сколько он родился), тогда скажу ему: «Да». И ни минутой раньше.
Будьте весёлыми и загадочными
Кто не любит маленькие тайны? Мужчинам это, безусловно, нравится ещё больше, чем нам, поэтому не стоит отказывать им в небольшом приключении. Позвольте им как бы «случайно» открыть, каким ценным «трофеем» являетесь!
Не рассказывайте ему о себе всё сразу. Заставьте задуматься и постараться понять вас.
Парень вовсе не хочет сходу узнать всю историю вашей жизни. Ему нравится открывать вас — постепенно и день за днём.
Поэтому держите некоторые секреты при себе. У вас будет достаточно времени, чтобы «дозировано» открывать их один за другим. Мужчины это любят.
Быть честными и искренними — это хорошо, но часто приводит к тому, что парням становится скучно и они попросту теряют интерес.
Если же сможете сохранить интригу, подогреть его любопытство, удивить, — он захочет вас ещё больше.
Еще одна вещь, которая нравится мужчинам не меньше, чем тайны, — это развлечения. Пока с вами весело, он захочет быть рядом — как можно чаще.
Добавьте немного азарта в свидания. Вместо ужина или похода в кино, например, предложите прогуляться ночным парком.
Поверьте, когда вы включите «режим тишины», ему будет очень недоставать этого веселья и загадочности.
Миша (имя изменено по просьбе героя)
31 год, первые и последние серьезные романтические отношения закончились девять лет назад
О стереотипах и одинокой жизни
Говорят, что если мужику за 30, а он без жены и детей, то с ним, наверное, что-то не то. Но это ***** все, стереотипы. Если человек одинокий, может, его просто устраивают несерьезные отношения. Может, он вообще их не хочет.
С другой стороны, я точно знаю, что конкретно со мной не так. Некоторые друзья называют меня странным, но я бы выбрал другое прилагательное: я *****. Очень упрямый и принципиальный, в некоторых моментах даже чересчур. В моей трудовой книжке 13 мест работы указано, и где-то десяток из них — это я бросил, потому что посрался с начальником из-за своего принципиального отношения по какому-то вопросу. Не захотел, например, бабку обманывать и говорить, что с ее краном что-то не так, чтобы она у нас новый купила. Таким людям, как я, в нашем обществе трудно жить.
Ни друзья, ни родители в мою личную жизнь не лезут. Хотя мать с отцом иногда могут сказать, что внуков хотят. Если сильно давить начинают, то я рычу в ответ, и они отстают. На работе меня часто спрашивают, когда свадьба. Еще говорят: «Смотри, пара лет и все — один навсегда останешься». Я таким людям отвечаю: «Пошли *****». Ну а что еще на такие вопросы можно ответить? Я коллег не считаю близкими людьми, не надо им в мою личную жизнь соваться.
Я бы хотел завести семью с любимой женщиной. И в любовь я верю. Как можно не верить в то чувство, которое сам испытывал. Но я слабо верю, что когда-то встречу любовь еще раз. Хотя надежда, она, скотина, упрямая, все равно есть.
Дайте ему время и свободу.
Когда мы влюбляемся в кого-то, хотим проводить с ним всё свое время.
Это естественно, но при этом возникает ощущение, что свободы — намного меньше. А для парней она — жизненно необходима.
Поэтому вместо того чтобы проводить с ним все выходные, сошлитесь на то, что договорились о встрече с подругами, и повеселитесь где-то.
Не проводите с парнем всё время — это пойдёт на пользу обоим. Вы сможете расслабиться и встретиться с друзьями, а он — осознать, как скучает.
Дайте ему время и свободу, и увидите, что парень захочет проводить с вами ещё больше часов и дней. Кроме того, ему будет любопытно, как вы проводите время и с кем.
Встречайтесь с другими людьми и помните, что не обязаны ему ничего объяснять. Если хочет узнать, где вы, пусть позвонит и спросит.
listen()¶
См.также
- http://unixhelp.ed.ac.uk/CGI/man-cgi?listen+2
Подготавливает привязываемый сокет к принятию входящих соединений. Данная функция применима только к типам сокетов SOCK_STREAM и SOCK_SEQPACKET. Принимает два аргумента:
- sockfd — корректный дескриптор сокета.
- backlog — целое число, означающее число установленных соединений, которые могут быть обработаны в любой момент времени. Операционная система обычно ставит его равным максимальному значению.
Примечание
После принятия соединения оно выводится из очереди. В случае успеха возвращается 0, в случае возникновения ошибки возвращается −1.
Пример на Си
#include <sys/socket.h> int listen(int sockfd, int backlog);
Пример на Python
Он замечает каждую вашу ошибку, зато игнорирует свои.
Этому парню нужно, чтобы вы были идеальными и считали его идеальным. При этом он может вести себя самым неподобающим образом, грубить, унижать, но указывать ему на ошибки — категорически запрещено. В лучшем случае он просто обидится, а так — набросится на вас с обвинениями в подозрительности, повышенной чувствительности к мелочам, а то и в неадекватности. А вот каждая ваша ошибка, даже самая крохотная, будет немедленно подчёркнута, высмеяна и доведена до размеров «динозавра».
Ожидается, что вы будете искренне раскаиваться, извиняться, стыдиться, ну и, естественно, всегда слушать его, прежде чем что-то сказать или сделать. Другое дело он: ему — можно всё. Почему? Потому, что он, в отличие от вас, «не делает никогда ничего плохого». И вы должны всегда помнить об этом.
Получение сообщений
При получении сообщения вызывается событие message. Оно включает в себя свойство data, которое можно использовать для доступа к содержимому сообщения.
Нам нужно создать обработчик события, который будет вызываться при получении нового сообщения. Он должен получать сообщение от события и отображать его в messagesList.
Чтобы добиться этого, скопируйте следующий код в файл app.js.
// Обработка сообщений, отправленных сервером. socket.onmessage = function(event) { var message = event.data; messagesList.innerHTML += '<liclass="received"><span>Received:</span>' + message + '</li>'; };
Закрытие соединений
Когда вы закончите работу с веб-сокетом, нужно разорвать соединение, используя метод close().
socket.close();
После того, как соединение будет разорвано, браузер вызовет событие close. Добавление обработчика события close позволит выполнить любую «уборку», которая потребуется.
Теперь нам нужно обновить статус соединения при его разрыве. Добавьте следующий код в файл app.js:
// Показываем сообщение «disconnected», когда соединение разорвано. socket.onclose = function(event) { socketStatus.innerHTML = 'Disconnectedfrom WebSocket.'; socketStatus.className = 'closed'; };
Чтобы завершить приложение, нужно добавить обработчик события, который будет вызываться при нажатии кнопки «Close Connection». Он должен вызывать метод close() объекта WebSocket.
// Закрываем соединение при нажатии кнопки «close» closeBtn.onclick = function(e) { e.preventDefault(); // Закрываем веб-сокет. socket.close(); return false; };
Наше приложение готово!
Откройте файл index.html в браузере и попробуйте отправить несколько сообщений. Вы увидите, что сервер отправляет сообщения обратно.
Создание приложения на основе веб-сокетов
Мы создадим простое приложение, которое соединяется с сервером по веб-сокету. Перед тем, как мы углубимся в детали 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 id="page-wrapper"> <h1>WebSockets Demo</h1> <div id="status">Connecting...</div> <ul id="messages"></ul> <form id="message-form" action="#" method="post"> <textarea id="message" placeholder="Write your message here..." required></textarea> <button type="submit">Send Message</button> <button type="button" id="close">Close Connection</button> </form> </div> <script src="app.js"></script> </body> </html>
Элемент <div> предназначен для вывода сообщений о статусе соединения. Список будет использоваться для отображения сообщений, отправленных и полученных от сервера. Веб-форма предназначена для ввода сообщений.
Файл style.css, на который ссылается этот код, находится в архиве для загрузки. Далее создадим файл app.js и добавим в него следующий код.
window.onload = function() { // Получаем ссылки на элементы страницы. var form = document.getElementById('message-form'); var messageField = document.getElementById('message'); var messagesList = document.getElementById('messages'); varsocketStatus = document.getElementById('status'); varcloseBtn = document.getElementById('close'); // Остальной код из этой статьи будет добавляться ниже... };
Мы создали несколько переменных и инициализировали их ссылками на ключевые элементы страницы.
Разное
Что ответить на «Можно вопрос?»
Это значит, человек хочет задать тебе вопрос, но не какой-нибудь ерундовый, а более серьезный. Может быть, связанный с твоей личной жизнью. А может, этот человек хочет выведать, как ты к нему относишься. Во всяком случае, можешь ответить: Да, конечно! — это покажет, что между вами уже появилось доверие, и ты не прочь увидеть вопрос.
Если вопрос окажется таким, что на него не хочется отвечать, напиши: Можно, я не буду отвечать на этот вопрос? Не обижайся, пожалуйста.
Как ответить на вопрос «Почему?»
Допустим, парень предлагает встретиться, а ты не хочешь. Он спрашивает: «Почему?» — то есть хочет понять причину и в то же время еще надеется, что ты передумаешь. Скорее всего, ему обидно. «Почему?» — как ответить на этот вопрос? Лучше всего сказать правду. Например, ты не хочешь с ним встречаться, потому что он тебе не нравится. Тогда так и напиши: «Ты мне не нравишься». Этого будет достаточно.
А что ответить на «Потому что?»
Спросив «Почему», ты можешь получить ответ «Потому что». Видимо, человек хочет сказать что-то в духе «Неужели непонятно?!». Если непонятно, попроси вежливо: Объясни, пожалуйста. Не стоит отвечать грубо.
«Какая ты?» Что ответить, какая я?
Что можно ответить о себе? Какая я? Представь, что о тебе разговаривают твои хорошие подруги. Как бы они тебя описывали? Какая ты — серьезная, забавная, красивая, клевая, крутая? Так и ответь. Напиши буквально в двух-трех словах, чтобы заинтересовать парня, но в то же время и не испугать, если у тебя есть к нему интерес. Ведь девушки любят интриговать мужчин.
«Я думал, не ответишь»
Этими словами мужчина как бы выражает: он думал о тебе и волновался, что ты больше не захочешь с ним общаться. Но поскольку ты все-таки ответила, он очень рад и надеется на дальнейшее общение и развитие отношений.
Почему человек не пишет, отвечает?
Возможно, он не прочитал твое сообщение. Или прочитал, но не ответил, потому что забыл или его отвлекли. Не накручивай себя, это ничего не означает. Позже попробуй написать снова, подать сигнал. Если вы общались в ВК, но общение прервалось, можно еще отправить СМС.
Как ответить на хамство?
Лучше всего игнорировать хама, то есть не обращать на него внимания и ничего не отвечать. А для полного спокойствия — заблокировать этого человека, если есть возможность. Подробнее об этом здесь:
- Что делать, если оскорбили ВКонтакте
- Как заблокировать человека ВКонтакте
Как ответить на обидный, негативный комментарий?
Можно ответить так: Послушай, в твоей жизни что-то происходит, и я знаю, что это не имеет отношения ко мне. Такое не пишут в хорошем настроении. Что-то заставляет тебя проецировать свои проблемы на меня. Мне жаль, что бы там у тебя ни происходило. Но я точно знаю, что меня это никак не касается. Хорошего дня!
Ответы на вопрос «Почему одна/один?»
-
Потому что в карточной схватке меня еще не никто не победил!
-
Я слишком профессионален!
-
Я слишком хорош(а) для уродов, но слишком уродлив(а) для красивых.
-
Это потому, что я слишком дорогой(ая).
-
Что ты имеешь в виду, я все еще не замужем? К твоему сведению, у меня отличные отношения с едой. Кстати, есть что-то перекусить?
-
Это потому, что я предпочитаю картофель парням/девушкам.
-
Это потому, что мне больше всего нравится вымышленный персонаж.
-
Я влюбляюсь только в персонажей аниме.
-
Кто тебе это сказал? Полиция? Правительство?
-
Это потому, что я граммар-наци!
-
Никто не любит супергероев. Вот почему я холост.
-
Сири, почему я до сих пор не замужем? * Siri активирует фронтальную камеру *
-
Я смеюсь над своими шутками, прежде чем закончу их.
-
Это потому, что я неуклюжий увалень.
-
Я еще не готов(а) ни с кем делиться своей едой.
-
Это потому, что я слишком громко ем чипсы.
-
Потому что мой молочный коктейль не приводит мальчиков во двор.
-
Это потому, что моя настоящая любовь — это еда.
-
Я предпочитаю иметь на пальце пончик, чем настоящее кольцо.
-
Я еще не нашел нужного человека. У меня такое чувство, что моя вторая половинка сейчас где-то далеко.
-
Потому что я предпочитаю компанию собак/кошек, а не людей.
-
Тот, кто наложил проклятие на мою личную жизнь, теперь может остыть. Я усвоил(а) урок.
-
Может быть, потому что я хлопаю в ладоши, когда в конце фильма появляются титры?
-
У меня странная одержимость вафлями.
-
Это потому, что мой муж/жена не разрешают мне встречаться.
-
Я еще не нашел никого, кто бы соответствовал моим причудам.
-
Я совершенно уверен(а), что я холост(ая), потому что я не пересылал(а) письма, в которых говорилось: «Перешлите это 10 людям, и вы встретите любовь всей своей жизни через 10 дней, иначе вам не повезет».
Привычка жениться: самые интересные истории множественных браков
Как общаться с манипулятором мужчиной
Осознанно игнорируйте его. Унижая других, агрессор хочет получить чувство собственной значимости, которое для него словно наркотик. Манипулятору на руку, когда обрабатываемая им жертва переживает из-за его слов и не находит себе места. Таким образом, она полностью сосредотачивается на нём. Именно этого и добивается манипулятор.
Поэтому нужно лишить манипулятора внимания и тогда ему придется искать его в другом месте.
Как это можно сделать?
Не стоит отвечать ему или что-то объяснять, нужно просто игнорировать его. Если не получается полностью игнорировать, а хочется что-то ответить на обидные замечания, тогда используйте прием «мнение большинства».
Цель манипуляторов — посеять в своей жертве сомнение в правильности ее точки зрения. А значит, защититься от мужчины манипулятора и поставить его на место можно, если показать, что это его точка зрения неправильная. Например, можно сказать следующее: «с моей точкой зрения согласны очень значимые люди, которым ты явно не чета».
Условная ситуация
Манипулятор обидел вас какой-то язвительной шуткой с целью продолжить издеваться над вашей ранимостью, говоря: «Да у тебя просто нет чувства юмора».
Как ответить на это манипулятору?
Например, так: «Среди нормальных людей хорошей шуткой всегда считалась та, которая вызывала улыбку не только у шутника, но и у того, над кем шутят. А если смешно только тебе, тогда, разочарую тебя — это не шутка, а глупость».
Так вы даёте понять ему, что ваше мнение согласуется с мнением большого количества нормальных людей. Можно также подтвердить свои слова знаменитой цитатой или афоризмом всемирно известного человека. Тогда ему придется спорить уже не с вашим мнением, а с точкой зрения знаменитых и уважаемых людей.
Все дальнейшие попытки влиять на вас просто игнорируйте. Это поднимет вашу самооценку, ведь словесная победа осталась за вами.
(Советуем узнать, как женщине повысить собственную самооценку и стать намного уверенней в себе?)
Подведем итог
Что мы выяснили из этой статьи?
- Что мужчина-манипулятор — прекрасный актер, гениально играющий роль жертвы.
- Когда он захочет, то может «лить слезы рекой», подделывать любовь, радость и другие эмоции.
- Чтобы не попасть в ловушку манипуляций нужно внимательно наблюдать за действиями тех, кто с первых дней знакомства утверждает, что любит вас, пытается расчувствовать своими слезами или игнорирует ваши чувства.
- Не стать жертвой манипулятора, обыграть или даже проучить и поставить его на место, возможно, если знать, как правильно вести себя с ним.
В этом видео вы можете узнать, способы общения с манипулятором и, как противостоять его манипуляциям.
Краткая история веб-приложений реального времени
Интернет был построен на представлении о том, что забота браузера– запрос данных с сервера, а забота сервера – обслуживание этих запросов. Эта парадигма не подвергалась сомнению несколько лет. Но с появлением AJAX в 2005 году многие начали работать над созданием двунаправленных соединений.
Веб-приложения значительно увеличивались в размере. Сдерживающим фактором для их роста была традиционная модель HTTP. Чтобы преодолеть это, были созданы несколько стратегий, позволяющих серверам «проталкивать» (push) данные клиенту. Одной из наиболее популярных стала стратегия «длинного опроса». Она подразумевает поддержание HTTP- соединения открытым до тех пор,пока у сервера есть данные для отправки клиенту.
Но все эти технологии приводят к перегрузке HTTP. Каждый раз, когда вы делаете запрос HTTP, набор заголовков и cookie передаются на сервер. Они накапливаются в большие массивы информации, которые нужно передать. Это увеличивает время ожидания, что может быть критично для равномерной работы приложения.
Чтобы решить данную проблему, нужен был способ создания постоянного соединения с минимальными задержками, которое могло бы поддерживать транзакции, инициированные как клиентом, так и сервером. Это как раз то, что предоставляют веб-сокеты.
Открытие соединений
Теперь, когда готов костяк приложения, можно начать изучать WebSocket API. Для начала узнаем, как создать новое соединение WebSocket. Для этого нужно вызвать конструктор класса WebSocket и передать ему URL сервера.
Скопируйте следующий код в файл app.js, чтобы создать новое соединение.
// Создаём новый объект WebSocket. varsocket = new WebSocket('ws://echo.websocket.org');
После того, как соединение установлено, возникнет событие open объекта WebSocket. Добавим обработчик события, который обновит статус элемента <div> сообщением о том, что соединение установлено.
Добавьте следующий код в файл app.js.
// Показываем сообщение «connected» при открытии веб-сокета. socket.onopen = function(event) { socketStatus.innerHTML = 'Connected to: ' + event.currentTarget.url; socketStatus.className = 'open'; };
Также мы добавляем класс open элементу <div>.
«Театр одного актера»
Услышав какой-то неприятный вопрос, вы всегда можете представить себя великой драматической актрисой, проникновенно заглянуть собеседнику в глаза, глубоко вздохнуть, прижать руки к груди (при желании можно «ломать» пальцы), изобразить бездну отчаяния и сказать трагическим голосом: «Умоляю тебя! Никогда, ты слышишь, никогда меня об этом не спрашивай!».
Второй вариант — вы изображаете человека, дающего пресс-конференцию (мы не будем называть конкретных имен, но рекомендуем обратить внимание на лиц первого эшелона власти) и произносите фразу: «Пожалуйста, следующий вопрос!». Третья версия — для поклонниц сериала «Универ»
Вспоминайте каратиста Эдуарда Кузьмина (он же Кузя) и говорите: «Это секретная информация!».
Реализация клиента на Javascript
Протокол веб-сокет создан уже давно (приобрёл статус RFC в 11.12.2011) и поддерживается большинством браузеров.
Чтобы узнать поддерживает ли ваш браузер веб-сокеты перейдите по .
Работа в браузерах с вебсокетам проходит в несколько этапов:
- Установка соединения или рукопожатие (handshake).
- Создание обработчиков событий: onopen (соединение создано), onclose(соединение закрыто), onmessage (пришло сообщение от сервера), onerror (ошибка при работе веб-сокетов).
- Отправка сообщений (фреймов) на сервер.
Тестировать веб-сокеты мы будем на сервере websocket.org «ws://echo.websocket.org», который будет принимать от нас сообщения и отвечать на них повторением сообщением.
Этот сайт как раз существует, что лучше понять веб-сокеты, он понимает кросс-доменные запросы, поэтому страницу с JavaScript будем размещать у себя на локальном компьютере.
Этап. Рукопожатие
Чтобы создать соединение по веб-сокету достаточно создать объект WebSocket, в котором указывается урл для подключения.
Используйте протокол «ws://», если нужно не шифрованное соединение или протокол «wss://» для шифрованного соединения.
Этап. Создание обработчиков событий.
После того как мы создали объект WebSocket необходимо повесить функции-обработчики на события.
Если нужно повесить несколько функций на событие используем методы «addEventListener» и «removeEventListener». Пример:
Этап. Отправка сообщений на сервер
По веб-сокету сообщения отправляются в виде строки. Пример отправки простого текстового сообщения.
Обработка приходящих данных лежит уже на стороне сервера. Чаще для удобства работы по вебсокету отправляют JSON данные серилизованные в строку и обрабатывают приходящие данные как строка в JSON-e. Пример использования:
Удобный способ отправки сообщений по веб-сокету служит протокол «JSON-RPC» (ссылка). Это очень простой протокол, который облегчит взаимодействие браузера и сервера. Пример использования JSON RPC:
Параметры json-rpc объекта:
- jsonrpc — версия протокола, может быть «2.0» или «1.0»
- id — идентификатор запроса. Используется для идентификации ответа от сервера по своем запросу. Т.е. если отправить два запроса, то ответ от сервера по каждому запросу прийдёт в разное время, для этого и нужен id. На сервере необходимо учитывать этот параметр и в ответ прислать именно нужный id.
- method — наименование метода, любая строка, к примеру «get», «hello», «set» и др.
- params — параметры связанные с этим методом, тип переменной может быть любой, всё зависит от сервера.
Чтобы закрыть соединение используем метод close().