Как изучающий веб -разработчик, как только вы научитесь запросить внешние API для отображения данных в вашем пользовательском интерфейсе, открывается целый новый мир.
При проведении собеседования на должности разработчика пользовательского интерфейса в различных компаниях я сказал бы что -то вроде: «Просто дайте мне конечные точки, и я справлюсь с остальными;)».
Все другие их вопросы, такие как «Как вы справляетесь с бедствиями?» или “Как вы справляетесь с спорами с заинтересованными сторонами?” стать спорным.
С помощью HTTP -запросов я могу получить данные, я могу публиковать данные и удалять данные. Я делаю все это – я определенно подходит для вашей команды, знаете ли вы это или нет.
Это звучит великолепно в эхо -камере моего разума. Я отчетливо помню, как чувствовал себя как чемпионский разработчик, потому что я знал, как отправлять запросы на API REST.
Затем они заставили меня сделать приложение в чате.
Если вы похожи на меня, вы не понимали, как работают приложения чата, когда вы стали веб -разработчиком. Возможно, вы подумали, эй, я просто отправляю запрос получить каждую полсекунду или около того, чтобы получить недавние сообщения чата.
В JavaScript это может выглядеть как -то вроде этого:
let clearIntervalId let messages = [] function pollChatMessages() { const clearIntervalId = setInterval(() => { messages = await axios.get('https://api.example.com/threads/1/messages') // totally fake url }, 500) }
Это называется опросом, и это будет работать на некоторое время. Один из моих клиентов не мог сказать разницу, пока была только пара пользователей.
Эта функция будет выполнена в некотором интервале внутри синглтона, который существует в сфере нашего веб -приложения. Если бы мы хотели убить опрос, мы могли бы позвонить clearInterval (clearIntervalid)
Анкет
Если бы мы болтали с 10 людьми, мы бы провели 10 опросов из нашего браузера. Точно так же эти 10 человек также проведут опрос для каждого человека, с которым они болтали.
А что, если в некоторых потоках есть сотни сообщений? Это тонна ненормально больших запросов на простое приложение для чата.
Проблема здесь заключается в том, что использование опроса предполагает, что для клиента, как наш браузер, нет возможности подписаться на сервер. Мы можем добиться большего успеха с небольшим количеством сети.
Давайте начнем с некоторых сетевых оснований, что такое сокет ?
A TCP сокет это экземпляр конечной точки определяется комбинацией IP -адреса с портом, в контексте либо состояния прослушивания (сервера), либо конкретного соединения TCP (клиент, например, ваш браузер).
A TCP Connection определяется спариванием двух розеток.
Есть три основных вида транспорта, которые мы обычно используем в веб -приложениях браузера:
- Xmlhttprequests , или просто http для короткого. Отправьте один запрос и получите один ответ. Они довольно распространены.
- Серверные события , или SSE. Отправьте долгоживущий запрос и смогут транслировать данные с сервера. Отлично подходит для потоковой передачи данных в реальном времени, особенно когда клиенту не нужно отправлять сообщения обратно на сервер.
- ВЕБ -ОКОКА , единственный транспорт, который допускает двунаправленную потоковую передачу текстовых и бинарных данных. Мы немного погрузимся в это.
Вот диаграмма, которую я украл из Высокопроизводительный браузер сеть , что иллюстрирует поток связи между каждым из этих транспортов. Это хорошая книга, чтобы проверить, серьезно ли вы в улучшении производительности ваших веб -приложений.
В большинстве учебных пособий, которые касаются внешних данных, вы будете иметь дело с HTTP-запросами самой левой парадигмы. На самом деле, все эти потоки инициируются с помощью HTTP -запроса, как показано синими стрелками.
Я обычно не вижу статей или учебных пособий по SSE, но MDN имеет хорошую ссылку В случае одностороннего потока данных звучит интригующе.
Третий поток наиболее интересен для нас – он дает нам возможность общаться с сервером в течение одного долгоживущего соединения.
Как описано Mozilla Developer Docs В
Это фантастика, нам не нужно делать опросы! Но как это работает?
Жизненный цикл соединения WebSocket между клиентом и сервером идет так. Представьте, что наш сервер размещен в https://api.example.com
На порту 8080 и наш клиент – чей -то браузер.
- Клиент отправляет запрос на получение
api.example.com:8080
, с несколькими заголовками, которые указывают, что он хочет установить соединение WebSocket с сервером. Один из них называетсяSec-websocket-key
и используется для обеспечения соединения между клиентом и сервером. Сервер получает заголовок ответа из этого ключаSec-websocket-accept
, что указывает на то, что сервер действительно поддерживает веб -питания и что он не пытается обрабатывать запрос как обычный HTTP -запрос. - Сервер отвечает кодом 101 – протоколы переключения, указывая, что рукопожатие завершено, и клиент/сервер может начать обменять сообщения зашифровано над XOR Анкет Спасения деталей этого маскировки данных, теперь мы можем публиковать и подписаться на текстовые или двоичные сообщения по этому соединению.
- В любой момент после успешного рукопожатия клиент или сервер могут отправить пинг, чтобы проверить, подключена ли другая сторона. Если получатель пинга не отправляет обратно вон, он мог быть отключен.
В JavaScript мы можем подключиться к серверу WebSocket, как это:
const thread = document.getElementById('chat-thread-1') const conn = new WebSocket('ws://api.example.com/threads/1') conn.onclose = function(event) { console.log('Connection closed') } conn.onmessage = function(event) { console.log('Message received.') const message = document.createElement('p') message.textContent = event.data thread.append(message) }
Мы можем вызвать встроенный конструктор WebSocket, чтобы создать соединение, и в этот момент мы можем настроить обработчики событий, чтобы решить, что происходит, когда получено сообщение.
Мы также можем отправлять сообщения, что, если у нас был вход
Элемент, который клиент может ввести текст, чтобы общаться с другими пользователями? Это было бы полезно.
function sendMessage() { const input = document.getElementById('chat-thread-1-input') conn.send(input.value) input.value = '' }
Еще лучше, что, если мы хотим сообщить более сложные данные с типом сообщения и временной меткой, возможно, в виде JSON?
function sendMessage() { const input = document.getElementById('chat-thread-1-input') const message = { type: 'message', text: input.value, date: Date.now(), } conn.send(JSON.stringify(message)) input.value = '' }
С небольшим количеством манипуляций с DOM, мы недалеко от несколько реального приложения чата. Чаты аккуратны и все, но что еще мы можем сделать с этой технологией?
Для этого примера в чате приложение веб -питания очевидно: отправить и получать текстовые сообщения.
Если вы часто посещаете Dev.to, то вы могли бы заметить, что у них проходит конкурс, называемый приложением Build Realtime с Pusher.
Pusher API построен на основе веб -копье. Некоторые из его вариантов использования включают:
- Обновление местоположения в режиме реального времени, скажем, для журналов и доставки
- графики в реальном времени
- Сотрудничество над браузером, мобильным или IoT
- онлайн -игры
Лично я подумываю построить редактор облачной маркировки, который поможет мне с редактированием и обменом постами в одном месте. Я бы хранил свой контент Markdown на сервере и в идеале смог просмотреть/редактировать его с моего Mac или моего телефона.
Если я хочу поделиться постом с кем -то для редактирования, я бы бросил им ссылку И я мог бы увидеть их курсор и заметки в режиме реального времени, аналогично тому, как работает Google Doc.
Конечно, часть веселья для меня – это реализация сервера. Потребляю ли я такую услугу, как Pusher, будет зависеть от моей производительности/боли с реализацией.
Если это вас интригует, вы можете найти эти ссылки полезными:
- Написание серверов WebSocket на MDN
- Как построить приложение чата с помощью React, Redux, Redux-Saga и веб-гнезда
- Создайте сервер чата в реальном времени с Go и WebSockets
Любопытно для дополнительных постов или остроумных замечаний? Следуй за мной на Средний , GitHub и Twitter !
Оригинал: “https://dev.to/iwilsonq/build-real-time-apps-by-learning-websockets-3c9m”