У вас включен AdBlock или иной блокировщик рекламы.

Пожалуйста, отключите его, доход от рекламы помогает развитию сайта и появлению новых статей.

Спасибо за понимание.

В другой раз
DevGang блог о програмировании
Авторизоваться

Создание realtime чата в NestJS

Websockets - это протокол связи, который обеспечивает полнодуплексные каналы связи по одному TCP-соединению, установленному между веб-браузером и веб-сервером. Это позволяет серверу отправлять данные в браузер без запроса с клиента.

Сегодня мы рассмотрим, как мы можем использовать Websockets для обеспечения связи в реальном времени между различными браузерами, создав приложение чата в NestJS .

Итак, без лишних слов, давайте начнем.

Введение в веб-сокеты

Веб-сокеты являются альтернативой HTTP-коммуникации в веб-приложениях. Они обеспечивают постоянную связь между клиентом и сервером, которую обе стороны могут использовать для начала отправки данных в любое время.

Это может принести следующие преимущества:

  • Сервер может отправлять сообщения клиенту без явного запроса клиента
  • Низкая задержка связи
  • Клиент и сервер могут одновременно общаться друг с другом

Вот почему Websockets превосходит HTTP, когда речь идет о долгосрочном общении в реальном времени.

Настройка проекта

Прежде чем мы сможем начать разработку проекта, давайте сначала настроим наш его и установим необходимые зависимости. Для этого вам нужно открыть свой терминал и выполнить следующие команды.

Сначала создайте проект и перейдите в его каталог.

nest new nestchat
cd nestchat

После этого нам просто нужно установить зависимости с помощью менеджера пакетов npm.

npm i --save @nestjs/websockets @nestjs/platform-socket.io

Теперь, когда у нас все установлено и произведена базовая настройка проекта, давайте создадим файлы, в которых мы будем работать.

Начнем с создания модуля, службы и контроллера с помощью интерфейса командной строки NestJS.

nest g gateway app

После этого вам просто нужно создать папку с именем static в вашем каталоге src, которая содержит три файла:

  • index.html - Дизайн для нашего чата
  • main.js - клиентская логика websockets
  • styles.css - стиль для нашего HTML-файла

Теперь структура вашего проекта должна выглядеть примерно так.

Теперь, когда мы завершили первоначальную настройку, мы можем запустить наш сервер, выполнив следующую команду.

npm run start:dev

Вуаля, первоначальная настройка завершена, теперь давайте приступим к реализации конфигурации Websockets.

Сервер веб-сокетов

Во-первых, давайте начнем с создания нашего сервера Websockets, реализовав инструменты Websocket, которые мы установили ранее. Это очень простой процесс, который требует только AppGateway, который мы создали выше.

import {
SubscribeMessage,
WebSocketGateway,
OnGatewayInit,
WebSocketServer,
OnGatewayConnection,
OnGatewayDisconnect,
} from '@nestjs/websockets';
import { Logger } from '@nestjs/common';
import { Socket, Server } from 'socket.io';

@WebSocketGateway()
export class AppGateway implements OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect {
  @WebSocketServer() 
  server: Server;

  private logger: Logger = new Logger('AppGateway');
  
  @SubscribeMessage('msgToServer')
  handleMessage(client: Socket, payload: string): void {
    this.server.emit('msgToClient', payload);
  }

  afterInit(server: Server) {
    this.logger.log('Init');
  }

  handleDisconnect(client: Socket) {
    this.logger.log(`Client disconnected: ${client.id}`);
  }

  handleConnection(client: Socket, ...args: any[]) {
    this.logger.log(`Client connected: ${client.id}`);
  }
}

Это в основном все, что нам нужно для взаимодействия с приложением, поэтому давайте разберем его.

Сначала вы заметите, что мы украсили наш класс декоратором @WebsocketGateway(), который дает нам доступ к функциональности socket.io.

Мы также реализовать три интерфейса OnGatewayInit, OnGatewayConnection и OnGatewayDisconnect которые мы используем , чтобы добавить некоторые ключевые состояния нашего приложения. Например, мы регистрируем, когда новый клиент подключается к серверу или когда текущий клиент отключается.

Затем мы создали переменную-член с именем server, которая украшена декоратором @WebsocketServer(), что дает нам доступ к экземпляру сервера Websockets.

Мы используем экземпляр в нашей handleMessage() функции, где мы отправляем данные всем клиентам, подключенным к серверу, используя функцию emit(). Функция handleMessage() также украшена, декоратором @SubscribeMessage() что дает возможность слушать событие с именем msgToServer.

Прежде чем мы перейдем к клиентской части проекта, нам нужно только добавить наш шлюз в модуль.

import { Module } from '@nestjs/common';
import { AppGateway } from './app.gateway';

@Module({
  imports: [],
  controllers: [],
  providers: [AppGateway],
})
export class AppModule {}

Websocket клиент

Закончив сервер, давайте теперь перейдем к клиентской части этого проекта. Для этого мы будем использовать статические файлы непосредственно в нашем проекте NestJS. Для простоты работы с клиенсткой частью мы также будем использовать Vue.js .

Сначала нам нужно сообщить нашему приложению NestJS, что мы хотим использовать статические ресурсы, добавив несколько строк кода в наш файл main.js.

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { NestExpressApplication } from '@nestjs/platform-express';
import { join } from 'path';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useStaticAssets(join(__dirname, '..', 'static'));
  await app.listen(3000);
}

bootstrap();

Здесь мы говорим express, что каталог static будет использоваться для хранения наших статических ресурсов, что мы можем сделать только путем импорта и использования NestExpressApplication.

Затем мы создадим код JavaScript на стороне клиента в нашем файле main.js, который мы позже будем использовать в макете.

const app = new Vue({
  el: '#app',
  data: {
    title: 'Nestjs Websockets Chat',
    name: '',
    text: '',
    messages: [],
    socket: null
  },
  methods: {
    sendMessage() {
      if(this.validateInput()) {
        const message = {
          name: this.name,
          text: this.text
        }
        this.socket.emit('msgToServer', message)
        this.text = ''
      }
    },
    receivedMessage(message) {
      this.messages.push(message)
    },
    validateInput() {
      return this.name.length > 0 && this.text.length > 0
    }
  },
  created() {
    this.socket = io('http://localhost:3000')
    this.socket.on('msgToClient', (message) => {
      this.receivedMessage(message)
    })
  }
})

Здесь мы создаем новый экземпляр Vue.js и создаем некоторые базовые переменные, которые позже будем использовать в нашем макете.

Далее вы можете увидеть функцию created(), которая будет выполняться при создании внешнего интерфейса. В этом методе мы создаем экземпляр нашей переменной socket с помощью библиотеки socket.io, которую мы позже импортируем в наш интерфейс. Мы также добавляем слушатель событий в наш сокет, который прослушивает событие msgToClient, которое мы создали ранее на нашем сервере.

Затем у нас есть функция sendMessage(), которая получает входные данные из нашего макета и отправляет их на наш сервер, используя то же событие, если входные данные верны.

Вот и все для нашей клиентской части - теперь нам нужно только создать макет для нашего приложения.

Макет приложения

Чтобы создать макет, нам просто нужно добавить несколько простых HTML и CSS в наше приложение.

Здесь мы импортируем зависимости socket.io и vue.js с помощью тегов script, а затем создаем простой макет с двумя полями ввода, областью отображения сообщений и кнопкой для отправки сообщений.

Вы также можете заметить, что мы импортируем наш файл main.js, который мы использовали выше, и пользовательскую таблицу стилей, которую мы создадим сейчас.

#messages{
  height:300px;
  overflow-y: scroll;
}

#app {
  margin-top: 2rem;
}

Тестирование приложения

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

npm run start

После запуска мы должны увидеть наш макет на http://localhost: 3000.

Затем вам просто нужно ввести имя и сообщение и нажать кнопку отправить. После отправки сообщение должно появиться во втором окне и должно выглядеть примерно так.

Это оно! Мы завершили наше чат-приложение на NestJS, используя Websockets. Полный код проекта также можно найти в Github.

Заключение

Вы сделали это! Я надеюсь, что эта статья помогла вам понять основы Websockets и как их использовать в NestJS.

#NestJS