Что такое веб-сокет? Создаете приложение для чата в реальном времени, используя Socket.IO с NodeJS? Насколько легко это может быть? Мы увидим!
WebSocket обеспечивает двустороннюю связь в реальном времени между двумя или более клиентами через подключающийся сервер. Это противоречит WebRTC, который обеспечивает прямую двустороннюю связь в реальном времени между двумя или более клиентами без необходимости в постоянном наличии сервера [это означает, что после того, как сервер соединит клиентов, клиенты теперь могут общаться непосредственно друг с другом]. В следующий раз планирую писать на WebRTC 😃
Понимание преимуществ WebSocket может быть лучше реализовано при разработке приложения для чата. Прежде всего, отправка HTTP-запросов по сети для облегчения активной связи между клиентами была бы очень дорогостоящей. Избыточная информация заголовка должна будет передаваться по сети каждый раз. В то время как в случае соединений WebSocket, как только дорогостоящий первоначальный вызов устанавливает соединение между любыми двумя клиентами, теперь между собой можно отправлять очень небольшие пакеты данных. Это может способствовать более быстрой и легкой передаче данных, а также непрерывной передаче данных или потоков данных для аудио/видео и т. д. типов информации.
ОСТОРОЖНО, ЛЮДИ! в этой статье показаны фрагменты кода со смесью Javascript ES5 и ES6 😛
Как создать базовое приложение WebSocket в NodeJS?
* Серверное приложение для установления связи между клиентами. [NodeJS, NodeExpress, Socket.IO и т. д.]
* Клиентское приложение для прослушивания и отправки сообщений своей аудитории. [JS, HTML, CSS и т. д.]
Рекомендуется:
* Nodemon (для горячей загрузки, только для среды разработки, установите, если он еще не установлен глобально на вашем компьютере)
баш
npm i express npm i socket.io npm i -D nodemon //as dev dependency, use -g if desired
Скелет серверного приложения:
сервер.js
var app = require('express')(); var http = require('http').Server(app); var io = require('socket.io')(http); var PORT = process.env.PORT || 5000; //WE WILL USE THIS SERVER APP TO SERVE THE CLIENT ALSO!! app.get('/', (req, res) => { res.sendFile(__dirname + '/index.html'); }); // ALL WEBSOCKET CODE GOES HERE... http.listen(PORT, function () { console.log('WebSocket App started on PORT: ' + PORT); });
Как видите, здесь мы загрузили нашу библиотеку Socket IO. Давайте используем его для прослушивания любого клиента, который хочет подключиться к нашему приложению на хосте и заданном порту. Любой клиент, который откроет соединение WebSocket, используя наш хост и порт, неявно инициирует событие соединения «соединение» и будет подключен.
сервер.js
var app = require('express')(); var http = require('http').Server(app); var io = require('socket.io')(http); var PORT = process.env.PORT || 5000; // Listening to clients getting connected and disconnected io.sockets.on('connection', function(socket) { console.log("LOG: [EVENT=connection] New client connected."); //A client left socket.on('disconnect', function() { console.log("LOG: [EVENT=disconnect] client has disconnected."); }); }); http.listen(PORT, function() { console.log('WebSocket App started on PORT: ' + PORT); });
Клиентская сторона:
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <title>terminal-x</title> </head> <body> <!-- ALL HTML GOES HERE --> <textarea id="outputID" row="0" readonly></textarea> <input id="inputID" type="text" /> <!-- SCRIPT GOES HERE --> <script src="/socket.io/socket.io.js"></script> <script src="/client.js"></script> </body> </html>
client.js:
//SOCKET CONNECTION CHATROOM var sock = io.connect(); //THIS IS WHERE WE WILL EVENTUALLY ADD CODES //TO EMIT AND LISTEN FOR MESSAGES FOR EACH EVENT
🌹КОМНАТЫ!
Для обеспечения конфиденциальности и облегчения групповых чатов мы будем использовать комнаты. Комнаты — это отдельные каналы, созданные внутри одного и того же сокетного соединения. Несколько клиентов могут присоединиться к каждому каналу/комнате и вести отдельные групповые беседы.
🍓 Приведенный ниже пример кода в значительной степени завершает работу над серверным приложением:
Как видите, первое событие, которое мы хотим прослушать, — это событие «соединение», когда клиенты подключаются к нашему веб-сокету, теперь мы слушаем для события 'join_room'. Каждый раз, когда клиент хочет создать комнату с новым именем, мы создаем для этого комнату/канал. Если клиент хочет создать канал/комнату с существующим именем, он просто игнорируется. Дублирование теперь разрешено. Может быть реализован механизм добавления уникального идентификатора каждый раз, когда клиенты пытаются открыть комнаты/каналы с тем же именем.
client.js
room_name = "room name I want to create and subscribe"; sock.emit('join_room', room_name);
сервер.js
// server side code: ROOM io.sockets.on('connection', function(socket) { socket.on('join_room', function(room_name) { socket.join(room_name); console.log(socket.rooms); //all rooms created so far }); });
Прослушивание комнат. Со стороны сервера мы прослушиваем событие «message_to_server», это событие может быть запущено на стороне клиента из любой комнаты. Затем мы передадим это сообщение каждому клиенту в этой комнате. Теперь, как мы узнаем, из какой комнаты он пришел? Мы добавим это имя комнаты в данные самим клиентом. Как вы можете видеть в коде ниже
сервер.js
//LISTEN TO ROOMS socket.on('message_to_server', function({ room_name, from, msg }) { //we will emit this message to all clients in given room });
Передача в комнаты: мы получили это со стороны клиента, сообщая пользователю, что это за комната, кто пользователь и что это за сообщение. Теперь мы можем отправить это сообщение
сервер.js
//LISTEN TO ROOMS AND EMITTING TO ALL CLIENTS IN THAT ROOM socket.on('message_to_server', function({ room_name, from, msg }) { //we will emit this message to all clients in given room io.in(room_name).emit('message_to_client', { from, msg }); });
client.js
// EMITTING MESSAGES FROM CLIENT TO ROOM var room_name = "name of room to which we will emit" var from = "could be username, some way to identifiy who sent it" var msg = "the message from this client" sock.emit('message_to_server', { room_name, from: username, msg });
Приведенный выше код будет запущен пользователем из пользовательского интерфейса клиента, используя событие 'message_to_server', мы добавляем имя пользователя и имя комнаты в полезную нагрузку, поэтому серверная сторона может знать, в какой комнате это сообщение. должны быть отправлены в.
Вот, полный код с комментариями! давайте изучим не требующий пояснений полный пример кода.
сервер.js
"use strict"; var app = require('express')(); var http = require('http').Server(app); var io = require('socket.io')(http); var PORT = process.env.PORT || 5000; app.get('/', (req, res) => { res.sendFile(__dirname + '/index.html'); }); // server side code: ROOM io.sockets.on('connection', function(socket) { console.log("LOG: [EVENT=connection] New client connected."); //EACH TIME WE WANT TO CREATE A NEW ROOM FROM CLEINT SIDE, EVENT = CREATE socket.on('join_room', function(room_name) { console.log("LOG: [EVENT=join_room] [room_name=" + room_name + "]"); console.log(socket.rooms); socket.join(room_name); }); //LISTEN TO ROOMS socket.on('message_to_server', function({ room_name, from, msg }) { //we will emit this message to all clients in given room io.in(room_name).emit('message_to_client', { from, msg }); }); //A user disconnected from room socket.on('disconnect', function() { console.log("LOG: [EVENT=disconnect] A client has disconnected."); }); }); http.listen(PORT, function() { console.log('WebSocket App started on PORT: ' + PORT); });
Давайте посмотрим на клиентский скрипт. Большая часть кода статична для простоты понимания. После базового понимания его можно сделать динамическим и запускаемым по событию.
client.js
//SOCKET CONNECTION CHATROOM var sock = io.connect(); var outputDOM = document.getElementById("outputID"); var inputDOM = document.getElementById("inputID"); var username = ""; var msg = ""; var room_name = ""; //+++++++++++++++++++++++++++++++++++++ // REQUEST SERVER TO CREATE A NEW ROOM: //+++++++++++++++++++++++++++++++++++++ room_name = "some room name"; sock.emit('join_room', room_name); //+++++++++++++++++++++++++++++++++++++ // LISTENER TO SERVER: //+++++++++++++++++++++++++++++++++++++ sock.on('message_to_client', function({ from, msg }) { // ****** outputDOM.innerHTML += "</br>" + decryptedMSG(data); outputDOM.rows += 1; // ****** }); //+++++++++++++++++++++++++++++++++++++ // SEND TO SERVER: //+++++++++++++++++++++++++++++++++++++ function sendToServer(msg, room_name) { sock.emit('message_to_server', { room_name, from: username, msg }); } //USER GAVE INPUT: SEND TO SERVER inputDOM.addEventListener("keyup", function(event) { if (event.keyCode === 13) { event.preventDefault(); //+++++++++++++++++++++++++++++++++++++ if (inputDOM.value != "") { //SEND TO SERVER sendToServer(inputDOM.value, token); //RESET INPUT TERMINAL inputDOM.value = "" } else { inputDOM.placeholder = "empty message cant be sent!"; } //+++++++++++++++++++++++++++++++++++++ } });
Если все еще есть путаница, взгляните на полный проект на WebSocket с использованием комнат. Клонируйте его и следуйте инструкциям в readme.md. Это не базовый шаблон для приложения Socket, но он должен быть достаточно простым для понимания.
ССЫЛКА: полный пример проекта, написанный с помощью Socket.IO в nodeJS.
Данный проект можно легко развернуть в Heroku. Добавлены два сценария оболочки. Наслаждаться!! пожалуйста, оставьте комментарии или аплодисменты!!