DEV Community

bkwebeagle
bkwebeagle

Posted on

Простой WebSocket сервер на Node.js

Сейчас мы с вами напишем простой WebSocket-сервер на node.js. При подключении к этому серверу в ответ придёт приветственное сообщение. А так же будет доступна к выполнению пара не сложных команд.

Для этого потребуется установить Node.js с менеджером пакетов npm, он идёт в комплекте

Настройка проекта
В начале, нам потребуется создать директорию будущего проекта

mkdir websocket-server-node
Enter fullscreen mode Exit fullscreen mode

Переходим в директорию

cd websocket-server-node
Enter fullscreen mode Exit fullscreen mode

Далее нужно инициализировать новый проект через npm

npm init
Enter fullscreen mode Exit fullscreen mode

Установщик потребует ответить на несколько вопросов, их можно пропустить

После инициализации проекта, необходимо добавить в проект библиотеку WS и настройку для работы с текстом в UTF-8

npm install ws
npm install --save-optional utf-8-validate
Enter fullscreen mode Exit fullscreen mode

Код websocket-сервера

Теперь приступим к написанию кода. В директории проекта создадим новый файл server.js, откроем файл. Далее я последовательно опишу весь код, а вот ссылка на полный код на GitHub.

server.js:

В начале нужно подключить библиотеку для работы с websocket

const WebSocket = require('ws');
Enter fullscreen mode Exit fullscreen mode

Далее, создадим константу, экземпляр класса WebSocket, с указанием порта на котором будет запущен WebSocket-сервер.

const wsServer = new WebSocket.Server({port: 9000});
Enter fullscreen mode Exit fullscreen mode

В отличии от HTTP-сервера, WebSocket-сервер принимает подключение и удерживает его. HTTP-сервер принимает запросы напрямую, а WebSocket-сервер принимает запросы от подключения, такое соединение является полнодуплексное.

Напишем обработчик подключения, в качестве обработчика укажем функцию onConnect.

wsServer.on('connection', onConnect);
Enter fullscreen mode Exit fullscreen mode

В момент подключения нового клиента в onConnection передаётся объекта ws-соединения, через него сервер будет общаться с каждым конкретным клиентом.

Функция onConnect принимает только один параметр, назовём его wsClient. В нашем конкретном примере мы подключим только два обработчика событий на объект wsClient: message и close.

message - обрабатывает событие входящего сообщения от клиента.

close - событие разрыва соединения с клиентом.

В самом начале функции onConnect, выведем в консоль сообщение что новый пользователь в сети. И отправим клиенту приветственное сообщение

Далее опишу заготовку для функции onConnect:

function onConnect(wsClient) {
  console.log('Новый пользователь');
  // отправка приветственного сообщения клиенту
  wsClient.send('Привет');

  wsClient.on('message', function(message) {
    /* обработчик сообщений от клиента */
  }

  wsClient.on('close', function() {
    // отправка уведомления в консоль
    console.log('Пользователь отключился');
  }
}
Enter fullscreen mode Exit fullscreen mode

На событие close сервер выведет в консоль уведомление.

Теперь напишем обработчик сообщений со стороны клиента. Договоримся, что команды сервер будет принимать в JSON-формате. JSON позволит отдельно указывать команду и параметры, а ответ сервера будет возвращаться в текстовом формате.

Формат JSON команд от клиента:

{
  action: 'ECHO' | 'PING',
  data?: string // необязательный параметр
}
Enter fullscreen mode Exit fullscreen mode

Как видно из формата, сервер будет принимать две команды:

echo-запрос, в ответ на который сервер отправит содержимое data
ping, в ответ сервер отправит pong
если команда не известна, сервер выведет в консоль уведомление "Неизвестная команда"
Содержимое обработчика сообщений от клиента:

try {
  // сообщение пришло текстом, нужно конвертировать в JSON-формат
  const jsonMessage = JSON.parse(message);
  switch (jsonMessage) {
    case 'ECHO':
      wsClient.send(jsonMessage.data);
      break;
    case: 'PING':
      setTimeout(function() {
        wsClient.send('PONG');
      }, 2000);
      break;
    default:
      console.log('Неизвестная команда');
      break;
  }
} catch (error) {
  console.log('Ошибка', error);
}
Enter fullscreen mode Exit fullscreen mode

Как вы уже видите, на команду PING сервер не сразу ответит, а подождёт 2 секунды.

Добавим в конце файла server.js строку, которая выведет в консоль информацию, на каком порту запущен сервер.

console.log('Сервер запущен на 9000 порту');
Enter fullscreen mode Exit fullscreen mode

Запуск сервера
Для запуска сервера необходимо перейти в консоль и ввести команду:

node server.js
Сервер доступен локально по адресу ws://localhost:9000. Остановить сервер можно сочетанием клавиш:

Для Windows и Linux (Ctrl + C)
Для MacOs (Cmd + C)
Если хотите проверить работу сервера с другого устройства в рамках локальной сети, то откройте ещё одно окно консоли и запустите команду

для Window:

ipconfig
Enter fullscreen mode Exit fullscreen mode

для Linux и MacOS:

ifconfig
Enter fullscreen mode Exit fullscreen mode

В моём случае локальный адрес 192.168.0.15, значит из локальной сети сервер будет доступен по адресу ws://192.168.0.15:9000.

Проверка работы сервера
Чтобы протестировать работу сервера, откроем любую страницу в браузере и нажмём клавишу F12. Откроется DevTools, перейдём в консоль браузера и скопируем следующий код:

const myWs = new WebSocket('ws://localhost:9000');

// обработчик проинформирует в консоль когда соединение установится
myWs.onopen = function () {
  console.log('подключился');
};

// обработчик сообщений от сервера
myWs.onmessage = function (message) {
  console.log('Message: %s', message.data);
};

// функция для отправки echo-сообщений на сервер
function wsSendEcho(value) {
  myWs.send(JSON.stringify({action: 'ECHO', data: value.toString()}));
}

// функция для отправки команды ping на сервер
function wsSendPing() {
  myWs.send(JSON.stringify({action: 'PING'}));
}
Enter fullscreen mode Exit fullscreen mode

Запустите этот код. Далее в консоли браузера вызовите функцию wsSendPing:

wsSendPing()
Enter fullscreen mode Exit fullscreen mode

Через 2 секунды сервер пришлёт ответ, и в консоли выведется:

Message: PONG

Вызовите функцию wsSendEcho, к примеру, с содержимым "Test!", и в консоли будет выведено:

Message: Test!

Вот и всё! Кому понравилось, ставьте Like, подписывайтесь. Всем Добра!

Ссылка на полный код GitHub

Top comments (0)