NestjsとPostgreSQLを使用してリアルタイムチャットアプリケーションを構築する

このチュートリアルのコードは、私のGithubリポジトリで入手できます。手順に従って、自由にクローンを作成してください。さぁ、始めよう!

NestJSとは何ですか?

NestJSは、TypeScriptを使用する、高速でテスト可能、スケーラブルな、疎結合のサーバー側アプリケーションを作成するためのNode.jsフレームワークです。ExpressやFastifyなどの強力なHTTPサーバーフレームワークを利用します。

Nestは、Node.jsフレームワークに抽象化レイヤーを追加し、そのAPIを開発者に公開します。PostgreSQLやMySQLなどのデータベース管理システムをサポートしています。NestJSは、依存性注入WebsocketとAPIGetawaysも提供します。

Websocketとは何ですか?

WebSocketは、単一のTCP接続を介して全二重通信チャネルを提供するコンピューター通信プロトコルです。IETFは、2011年にWebSocketプロトコルをRFC6455として標準化しました。

現在の仕様は、HTMLLivingStandardとして知られています。HTTP / HTTPSとは異なり、Websocketはステートフルプロトコルです。つまり、サーバーまたはクライアントによって終了されない限り、サーバーとクライアントの間で確立された接続は有効です。WebSocket接続が一方の端で閉じられると、もう一方の端まで拡張されます。

前提条件

このチュートリアルは実践的なデモンストレーションです。フォローするには、次のものがインストールされていることを確認してください。

プロジェクトの設定

コーディングに取り掛かる前に、NestJSプロジェクトとプロジェクト構造を設定しましょう。プロジェクトフォルダを作成することから始めます。次に、ターミナルを開き、次のコマンドを実行します。

mkdir chatapp && cd chatapp

プロジェクトフォルダの作成

次に、以下のコマンドを使用してNestJSCLIをインストールします。

npm i -g @nestjs/cli

インストールが完了したら、以下のコマンドを実行してNestJSプロジェクトをスキャフォールディングします。

nest new chat

ご希望のnpmパッケージマネージャーを選択してください。このチュートリアルではnpm、必要なパッケージがインストールされるのを使用して待機します。インストールが完了したら、以下のコマンドを使用してインストールWebSocketします。Socket.io

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

次に、以下のコマンドを使用してゲートウェイアプリケーションを作成します。

nest g gateway app

次に、以下のコマンドを実行してサーバーを起動しましょう。

npm run start:dev

Postgresデータベースのセットアップ

これで、サーバー設定でユーザーレコードを保存するようにPostgresデータベースを設定できます。

まず、TypeORM(Object Relational Mapper)を使用して、データベースをアプリケーションに接続します。まず、次の手順でデータベースを作成する必要があります。まず、システムのPostgresユーザーアカウントに切り替えます。

sudo su - postgres

次に、以下のコマンドを使用して新しいユーザーアカウントを作成します。

createuser --interactive

次に、新しいデータベースを作成します。次のコマンドでこれを行うことができます。

createdb chat

次に、作成したデータベースに接続します。まず、app.module.tsファイルを開き、次のコードスニペットを次の配列に追加しますimports[]

...
import { TypeOrmModule } from '@nestjs/typeorm';
import { Chat } from './chat.entity';
imports: [
   TypeOrmModule.forRoot({
     type: 'postgres',
     host: 'localhost',
     username: '<USERNAME>',
     password: '<PASSWORD>',
     database: 'chat',
     entities: [Chat],
     synchronize: true,
   }),
   TypeOrmModule.forFeature([Chat]),
 ],
...

上記のコードスニペットでは、メソッドを使用してアプリケーションをPostgresSQLデータベースに接続TypeOrmModule forRootし、データベースのクレデンシャルを渡しました。<USERNAME>データベース用に作成したユーザーと<PASSWORD>パスワードに置き換えchatます。

チャットエンティティの作成

アプリケーションをデータベースに接続したので、チャットエンティティを作成してユーザーのメッセージを保存します。これを行うには、srcフォルダーにファイルを作成し、chat.entity.ts以下のコードスニペットを追加します。

import {
 Entity,
 Column,
 PrimaryGeneratedColumn,
 CreateDateColumn,
} from 'typeorm';
 
@Entity()
export class Chat {
 @PrimaryGeneratedColumn('uuid')
 id: number;
 
 @Column()
 email: string;
 
 @Column({ unique: true })
 text: string;
 
 @CreateDateColumn()
 createdAt: Date;
}

上記のコードスニペットでは、TypeOrmが提供する、、、、およびデコレータを使用してチャットの列を作成しましEntityた。ColumnCreatedDateColumnPrimaryGenerateColumn

Webソケットのセットアップ

リアルタイムメッセージを送信するために、サーバーにWebソケット接続を設定しましょう。まず、必要なモジュールを以下のコードスニペットでインポートします。

import {
 SubscribeMessage,
 WebSocketGateway,
 OnGatewayInit,
 WebSocketServer,
 OnGatewayConnection,
 OnGatewayDisconnect,
} from '@nestjs/websockets';
import { Socket, Server } from 'socket.io';
import { AppService } from './app.service';
import { Chat } from './chat.entity';

上記のコードスニペットでは、socket.ioへのアクセスを提供するSubscribeMessage()クライアントからのイベントをリッスンするためにインポートしました。、、、およびインスタンスWebSocketGateway()もインポートしました。OnGatewayInitOnGatewayConnectionOnGatewayDisconnect

このWebSocketインスタンスを使用すると、アプリケーションの状態を知ることができます。たとえば、サーバーがチャットに参加したり、チャットから切断したりしたときに、サーバーに処理を実行させることができます。Chat次に、エンティティとをインポートしましたAppService。これにより、ユーザーのメッセージを保存するために必要なメソッドが公開されます。

@WebSocketGateway({
 cors: {
   origin: '*',
 },
})

クライアントがサーバーと通信できるようにするために、を初期化することでCORSを有効にしますWebSocketGateway

export class AppGateway
 implements OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect
{
 constructor(private appService: AppService) {}
 
 @WebSocketServer() server: Server;
 
 @SubscribeMessage('sendMessage')
 async handleSendMessage(client: Socket, payload: Chat): Promise<void> {
   await this.appService.createMessage(payload);
   this.server.emit('recMessage', payload);
 }
 
 afterInit(server: Server) {
   console.log(server);
   //Do stuffs
 }
 
 handleDisconnect(client: Socket) {
   console.log(`Disconnected: ${client.id}`);
   //Do stuffs
 }
 
 handleConnection(client: Socket, ...args: any[]) {
   console.log(`Connected ${client.id}`);
   //Do stuffs
 }
}

次に、AppGateWay クラスでは、上記でインポートしたWebSocketインスタンスを実装しました。コンストラクターメソッドを作成し、AppServiceをバインドしてそのメソッドにアクセスできるようにしました。WebSocketServerデコレータからサーバーインスタンスを作成しました。

次に、インスタンスとメソッドをhandleSendMessage使用してデータをクライアント側に送信するを作成します。@SubscribeMessage()handleMessage()

クライアントからこの関数にメッセージが送信されると、それをデータベースに保存し、クライアント側で接続されているすべてのユーザーにメッセージを送り返します。

afterInitクライアントが接続した後にhandleDisconnectトリガーされる、ユーザーが切断したときにトリガーされるなど、実験できる他の多くの方法もあります。このhandleConnectionメソッドは、ユーザーが接続に参加したときに開始されます。

コントローラ/サービスの作成

次に、チャットを保存して静的ページをレンダリングするためのサービスとコントローラーを作成しましょう。ファイルを開き、app.service.ts以下のコードスニペットでコンテンツを更新します。

import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Chat } from './chat.entity';
 
@Injectable()
export class AppService {
 constructor(
   @InjectRepository(Chat) private chatRepository: Repository<Chat>,
 ) {}
 async createMessage(chat: Chat): Promise<Chat> {
   return await this.chatRepository.save(chat);
 }
 
 async getMessages(): Promise<Chat[]> {
   return await this.chatRepository.find();
 }
}

app.controller.ts 次に、以下のコードスニペットでファイルを更新します。

import { Controller, Render, Get, Res } from '@nestjs/common';
import { AppService } from './app.service';
import { Chat } from './chat.entity';
 
@Controller()
export class AppController {
 constructor(private readonly appService: AppService) {}
 
 @Get('/chat')
 @Render('index')
 Home() {
   return;
 }
 
 @Get('/api/chat')
 async Chat(@Res() res) {
   const messages = await this.appService.getMessages();
   res.json(messages);
 }
}

上記のコードスニペットでは、静的ページとユーザーのメッセージをレンダリングするための2つのルートを作成しました。

静的ページを提供する

次に、静的ファイルとページをレンダリングするようにアプリケーションを構成しましょう。そのために、サーバー側のレンダリングを実装します。まず、main.tsファイルで、次のコマンドを使用して静的サーバーファイルにアプリケーションを構成します。

async function bootstrap() {
 ...
 app.useStaticAssets(join(__dirname, '..', 'static'));
 app.setBaseViewsDir(join(__dirname, '..', 'views'));
 app.setViewEngine('ejs');
 ...
}

次に、ディレクトリにstaticviewsフォルダを作成しますsrc。ビューフォルダにindex.ejsファイルを作成し、以下のコードスニペットを追加します。

<!DOCTYPE html>
<html lang="en">
 
<head>
 <!-- Required meta tags -->
 <meta charset="utf-8" />
 <meta name="viewport" content="width=device-width, initial-scale=1" />
 
 <!-- Bootstrap CSS -->
 <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"
   integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous" />
 
 <title>Let Chat</title>
</head>
 
<body>
 <nav class="navbar navbar-light bg-light">
   <div class="container-fluid">
     <a class="navbar-brand">Lets Chat</a>
   </div>
 </nav>
 <div class="container">
   <div class="mb-3 mt-3">
     <ul style="list-style: none" id="data-container"></ul>
   </div>
   <div class="mb-3 mt-4">
     <input class="form-control" id="email" rows="3" placeholder="Your Email" />
   </div>
   <div class="mb-3 mt-4">
     <input class="form-control" id="exampleFormControlTextarea1" rows="3" placeholder="Say something..." />
   </div>
 </div>
 <script src="https://cdn.socket.io/4.3.2/socket.io.min.js"
   integrity="sha384-KAZ4DtjNhLChOB/hxXuKqhMLYvx3b5MlT55xPEiNmREKRzeEm+RVPlTnAn0ajQNs"
   crossorigin="anonymous"></script>
 <script src="app.js"></script>
 <!-- Option 1: Bootstrap Bundle with Popper -->
 <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"
   integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
   crossorigin="anonymous"></script>
</body>
</html>

テンプレートの処理を高速化するために、Bootstrapを使用していくつかのスタイルを追加しました。次に、ユーザーのメッセージを表示するために、2つの入力フィールドと順序付けされていないリストを追加しました。app.jsまた、このセクションの後半で作成するファイルとsocket.ioクライアントへのリンクも含めました。

次に、ファイルを作成し、app.js以下のコードスニペットを追加します。

const socket = io('http://localhost:3002');
const msgBox = document.getElementById('exampleFormControlTextarea1');
const msgCont = document.getElementById('data-container');
const email = document.getElementById('email');
 
//get old messages from the server
const messages = [];
function getMessages() {
 fetch('http://localhost:3002/api/chat')
   .then((response) => response.json())
   .then((data) => {
     loadDate(data);
     data.forEach((el) => {
       messages.push(el);
     });
   })
   .catch((err) => console.error(err));
}
getMessages();
 
//When a user press the enter key,send message.
msgBox.addEventListener('keydown', (e) => {
 if (e.keyCode === 13) {
   sendMessage({ email: email.value, text: e.target.value });
   e.target.value = '';
 }
});
 
//Display messages to the users
function loadDate(data) {
 let messages = '';
 data.map((message) => {
   messages += ` <li class="bg-primary p-2 rounded mb-2 text-light">
      <span class="fw-bolder">${message.email}</span>
      ${message.text}
    </li>`;
 });
 msgCont.innerHTML = messages;
}
 
//socket.io
//emit sendMessage event to send message
function sendMessage(message) {
 socket.emit('sendMessage', message);
}
//Listen to recMessage event to get the messages sent by users
socket.on('recMessage', (message) => {
 messages.push(message);
 loadDate(messages);
})

上記のコードスニペットでは、socket.ioインスタンスを作成し、サーバー上のイベントをリッスンして、サーバーとの間でメッセージを送受信しました。ユーザーがデフォルトでチャットに参加するときに、古いチャットを利用できるようにする必要があります。アプリケーションは次のスクリーンショットのようになります。

NestjsとPostgreSQLを使用してリアルタイムチャットアプリケーションを構築する

Arctypeを使用したユーザーデータの表示

これで、チャットアプリケーションが正常に作成されました。まず、Arctypeでユーザーのデータを見てみましょう。開始するには、Arctypeを起動し、[MySQL]タブをクリックして、次のスクリーンショットに示すように、次のMySQLクレデンシャルを入力します。

NestjsとPostgreSQLを使用してリアルタイムチャットアプリケーションを構築する

次に、以下のスクリーンショットに示すように、チャットテーブルをクリックして、ユーザーのチャットメッセージを表示します。

NestjsとPostgreSQLを使用してリアルタイムチャットアプリケーションを構築する

アプリケーションのテスト

次に、2つの異なるタブまたはウィンドウでアプリケーションを開き、下のスクリーンショットに示すように、異なる電子メールアドレスでメッセージを送信してみます。

NestjsとPostgreSQLを使用してリアルタイムチャットアプリケーションを構築する

また、コンソールを見ると、ユーザーがhandleDisconnectandhandleConnectionメソッドによって処理されるサーバーに参加および切断したときにログが表示されます。

結論

このチュートリアル全体を通して、NestjsとPostgreSQLを使用してリアルタイムチャットアプリケーションを作成する方法を探りました。まず、NestjsとWebSocketの簡単な紹介から始めました。次に、実装を示すデモアプリケーションを作成しました。あなたが求めている知識を得たことを願っています。おそらく、NestjsのドキュメントからWebSocketの実装について詳しく学び、アプリケーションを追加拡張することができます。

ソース:https ://betterprogramming.pub/build-a-real-time-chat-application-with-nestjs-and-postgresql-a212502eb436

#nestjs #postgresql #chat 

What is GEEK

Buddha Community

NestjsとPostgreSQLを使用してリアルタイムチャットアプリケーションを構築する

NestjsとPostgreSQLを使用してリアルタイムチャットアプリケーションを構築する

このチュートリアルのコードは、私のGithubリポジトリで入手できます。手順に従って、自由にクローンを作成してください。さぁ、始めよう!

NestJSとは何ですか?

NestJSは、TypeScriptを使用する、高速でテスト可能、スケーラブルな、疎結合のサーバー側アプリケーションを作成するためのNode.jsフレームワークです。ExpressやFastifyなどの強力なHTTPサーバーフレームワークを利用します。

Nestは、Node.jsフレームワークに抽象化レイヤーを追加し、そのAPIを開発者に公開します。PostgreSQLやMySQLなどのデータベース管理システムをサポートしています。NestJSは、依存性注入WebsocketとAPIGetawaysも提供します。

Websocketとは何ですか?

WebSocketは、単一のTCP接続を介して全二重通信チャネルを提供するコンピューター通信プロトコルです。IETFは、2011年にWebSocketプロトコルをRFC6455として標準化しました。

現在の仕様は、HTMLLivingStandardとして知られています。HTTP / HTTPSとは異なり、Websocketはステートフルプロトコルです。つまり、サーバーまたはクライアントによって終了されない限り、サーバーとクライアントの間で確立された接続は有効です。WebSocket接続が一方の端で閉じられると、もう一方の端まで拡張されます。

前提条件

このチュートリアルは実践的なデモンストレーションです。フォローするには、次のものがインストールされていることを確認してください。

プロジェクトの設定

コーディングに取り掛かる前に、NestJSプロジェクトとプロジェクト構造を設定しましょう。プロジェクトフォルダを作成することから始めます。次に、ターミナルを開き、次のコマンドを実行します。

mkdir chatapp && cd chatapp

プロジェクトフォルダの作成

次に、以下のコマンドを使用してNestJSCLIをインストールします。

npm i -g @nestjs/cli

インストールが完了したら、以下のコマンドを実行してNestJSプロジェクトをスキャフォールディングします。

nest new chat

ご希望のnpmパッケージマネージャーを選択してください。このチュートリアルではnpm、必要なパッケージがインストールされるのを使用して待機します。インストールが完了したら、以下のコマンドを使用してインストールWebSocketします。Socket.io

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

次に、以下のコマンドを使用してゲートウェイアプリケーションを作成します。

nest g gateway app

次に、以下のコマンドを実行してサーバーを起動しましょう。

npm run start:dev

Postgresデータベースのセットアップ

これで、サーバー設定でユーザーレコードを保存するようにPostgresデータベースを設定できます。

まず、TypeORM(Object Relational Mapper)を使用して、データベースをアプリケーションに接続します。まず、次の手順でデータベースを作成する必要があります。まず、システムのPostgresユーザーアカウントに切り替えます。

sudo su - postgres

次に、以下のコマンドを使用して新しいユーザーアカウントを作成します。

createuser --interactive

次に、新しいデータベースを作成します。次のコマンドでこれを行うことができます。

createdb chat

次に、作成したデータベースに接続します。まず、app.module.tsファイルを開き、次のコードスニペットを次の配列に追加しますimports[]

...
import { TypeOrmModule } from '@nestjs/typeorm';
import { Chat } from './chat.entity';
imports: [
   TypeOrmModule.forRoot({
     type: 'postgres',
     host: 'localhost',
     username: '<USERNAME>',
     password: '<PASSWORD>',
     database: 'chat',
     entities: [Chat],
     synchronize: true,
   }),
   TypeOrmModule.forFeature([Chat]),
 ],
...

上記のコードスニペットでは、メソッドを使用してアプリケーションをPostgresSQLデータベースに接続TypeOrmModule forRootし、データベースのクレデンシャルを渡しました。<USERNAME>データベース用に作成したユーザーと<PASSWORD>パスワードに置き換えchatます。

チャットエンティティの作成

アプリケーションをデータベースに接続したので、チャットエンティティを作成してユーザーのメッセージを保存します。これを行うには、srcフォルダーにファイルを作成し、chat.entity.ts以下のコードスニペットを追加します。

import {
 Entity,
 Column,
 PrimaryGeneratedColumn,
 CreateDateColumn,
} from 'typeorm';
 
@Entity()
export class Chat {
 @PrimaryGeneratedColumn('uuid')
 id: number;
 
 @Column()
 email: string;
 
 @Column({ unique: true })
 text: string;
 
 @CreateDateColumn()
 createdAt: Date;
}

上記のコードスニペットでは、TypeOrmが提供する、、、、およびデコレータを使用してチャットの列を作成しましEntityた。ColumnCreatedDateColumnPrimaryGenerateColumn

Webソケットのセットアップ

リアルタイムメッセージを送信するために、サーバーにWebソケット接続を設定しましょう。まず、必要なモジュールを以下のコードスニペットでインポートします。

import {
 SubscribeMessage,
 WebSocketGateway,
 OnGatewayInit,
 WebSocketServer,
 OnGatewayConnection,
 OnGatewayDisconnect,
} from '@nestjs/websockets';
import { Socket, Server } from 'socket.io';
import { AppService } from './app.service';
import { Chat } from './chat.entity';

上記のコードスニペットでは、socket.ioへのアクセスを提供するSubscribeMessage()クライアントからのイベントをリッスンするためにインポートしました。、、、およびインスタンスWebSocketGateway()もインポートしました。OnGatewayInitOnGatewayConnectionOnGatewayDisconnect

このWebSocketインスタンスを使用すると、アプリケーションの状態を知ることができます。たとえば、サーバーがチャットに参加したり、チャットから切断したりしたときに、サーバーに処理を実行させることができます。Chat次に、エンティティとをインポートしましたAppService。これにより、ユーザーのメッセージを保存するために必要なメソッドが公開されます。

@WebSocketGateway({
 cors: {
   origin: '*',
 },
})

クライアントがサーバーと通信できるようにするために、を初期化することでCORSを有効にしますWebSocketGateway

export class AppGateway
 implements OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect
{
 constructor(private appService: AppService) {}
 
 @WebSocketServer() server: Server;
 
 @SubscribeMessage('sendMessage')
 async handleSendMessage(client: Socket, payload: Chat): Promise<void> {
   await this.appService.createMessage(payload);
   this.server.emit('recMessage', payload);
 }
 
 afterInit(server: Server) {
   console.log(server);
   //Do stuffs
 }
 
 handleDisconnect(client: Socket) {
   console.log(`Disconnected: ${client.id}`);
   //Do stuffs
 }
 
 handleConnection(client: Socket, ...args: any[]) {
   console.log(`Connected ${client.id}`);
   //Do stuffs
 }
}

次に、AppGateWay クラスでは、上記でインポートしたWebSocketインスタンスを実装しました。コンストラクターメソッドを作成し、AppServiceをバインドしてそのメソッドにアクセスできるようにしました。WebSocketServerデコレータからサーバーインスタンスを作成しました。

次に、インスタンスとメソッドをhandleSendMessage使用してデータをクライアント側に送信するを作成します。@SubscribeMessage()handleMessage()

クライアントからこの関数にメッセージが送信されると、それをデータベースに保存し、クライアント側で接続されているすべてのユーザーにメッセージを送り返します。

afterInitクライアントが接続した後にhandleDisconnectトリガーされる、ユーザーが切断したときにトリガーされるなど、実験できる他の多くの方法もあります。このhandleConnectionメソッドは、ユーザーが接続に参加したときに開始されます。

コントローラ/サービスの作成

次に、チャットを保存して静的ページをレンダリングするためのサービスとコントローラーを作成しましょう。ファイルを開き、app.service.ts以下のコードスニペットでコンテンツを更新します。

import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Chat } from './chat.entity';
 
@Injectable()
export class AppService {
 constructor(
   @InjectRepository(Chat) private chatRepository: Repository<Chat>,
 ) {}
 async createMessage(chat: Chat): Promise<Chat> {
   return await this.chatRepository.save(chat);
 }
 
 async getMessages(): Promise<Chat[]> {
   return await this.chatRepository.find();
 }
}

app.controller.ts 次に、以下のコードスニペットでファイルを更新します。

import { Controller, Render, Get, Res } from '@nestjs/common';
import { AppService } from './app.service';
import { Chat } from './chat.entity';
 
@Controller()
export class AppController {
 constructor(private readonly appService: AppService) {}
 
 @Get('/chat')
 @Render('index')
 Home() {
   return;
 }
 
 @Get('/api/chat')
 async Chat(@Res() res) {
   const messages = await this.appService.getMessages();
   res.json(messages);
 }
}

上記のコードスニペットでは、静的ページとユーザーのメッセージをレンダリングするための2つのルートを作成しました。

静的ページを提供する

次に、静的ファイルとページをレンダリングするようにアプリケーションを構成しましょう。そのために、サーバー側のレンダリングを実装します。まず、main.tsファイルで、次のコマンドを使用して静的サーバーファイルにアプリケーションを構成します。

async function bootstrap() {
 ...
 app.useStaticAssets(join(__dirname, '..', 'static'));
 app.setBaseViewsDir(join(__dirname, '..', 'views'));
 app.setViewEngine('ejs');
 ...
}

次に、ディレクトリにstaticviewsフォルダを作成しますsrc。ビューフォルダにindex.ejsファイルを作成し、以下のコードスニペットを追加します。

<!DOCTYPE html>
<html lang="en">
 
<head>
 <!-- Required meta tags -->
 <meta charset="utf-8" />
 <meta name="viewport" content="width=device-width, initial-scale=1" />
 
 <!-- Bootstrap CSS -->
 <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"
   integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous" />
 
 <title>Let Chat</title>
</head>
 
<body>
 <nav class="navbar navbar-light bg-light">
   <div class="container-fluid">
     <a class="navbar-brand">Lets Chat</a>
   </div>
 </nav>
 <div class="container">
   <div class="mb-3 mt-3">
     <ul style="list-style: none" id="data-container"></ul>
   </div>
   <div class="mb-3 mt-4">
     <input class="form-control" id="email" rows="3" placeholder="Your Email" />
   </div>
   <div class="mb-3 mt-4">
     <input class="form-control" id="exampleFormControlTextarea1" rows="3" placeholder="Say something..." />
   </div>
 </div>
 <script src="https://cdn.socket.io/4.3.2/socket.io.min.js"
   integrity="sha384-KAZ4DtjNhLChOB/hxXuKqhMLYvx3b5MlT55xPEiNmREKRzeEm+RVPlTnAn0ajQNs"
   crossorigin="anonymous"></script>
 <script src="app.js"></script>
 <!-- Option 1: Bootstrap Bundle with Popper -->
 <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"
   integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
   crossorigin="anonymous"></script>
</body>
</html>

テンプレートの処理を高速化するために、Bootstrapを使用していくつかのスタイルを追加しました。次に、ユーザーのメッセージを表示するために、2つの入力フィールドと順序付けされていないリストを追加しました。app.jsまた、このセクションの後半で作成するファイルとsocket.ioクライアントへのリンクも含めました。

次に、ファイルを作成し、app.js以下のコードスニペットを追加します。

const socket = io('http://localhost:3002');
const msgBox = document.getElementById('exampleFormControlTextarea1');
const msgCont = document.getElementById('data-container');
const email = document.getElementById('email');
 
//get old messages from the server
const messages = [];
function getMessages() {
 fetch('http://localhost:3002/api/chat')
   .then((response) => response.json())
   .then((data) => {
     loadDate(data);
     data.forEach((el) => {
       messages.push(el);
     });
   })
   .catch((err) => console.error(err));
}
getMessages();
 
//When a user press the enter key,send message.
msgBox.addEventListener('keydown', (e) => {
 if (e.keyCode === 13) {
   sendMessage({ email: email.value, text: e.target.value });
   e.target.value = '';
 }
});
 
//Display messages to the users
function loadDate(data) {
 let messages = '';
 data.map((message) => {
   messages += ` <li class="bg-primary p-2 rounded mb-2 text-light">
      <span class="fw-bolder">${message.email}</span>
      ${message.text}
    </li>`;
 });
 msgCont.innerHTML = messages;
}
 
//socket.io
//emit sendMessage event to send message
function sendMessage(message) {
 socket.emit('sendMessage', message);
}
//Listen to recMessage event to get the messages sent by users
socket.on('recMessage', (message) => {
 messages.push(message);
 loadDate(messages);
})

上記のコードスニペットでは、socket.ioインスタンスを作成し、サーバー上のイベントをリッスンして、サーバーとの間でメッセージを送受信しました。ユーザーがデフォルトでチャットに参加するときに、古いチャットを利用できるようにする必要があります。アプリケーションは次のスクリーンショットのようになります。

NestjsとPostgreSQLを使用してリアルタイムチャットアプリケーションを構築する

Arctypeを使用したユーザーデータの表示

これで、チャットアプリケーションが正常に作成されました。まず、Arctypeでユーザーのデータを見てみましょう。開始するには、Arctypeを起動し、[MySQL]タブをクリックして、次のスクリーンショットに示すように、次のMySQLクレデンシャルを入力します。

NestjsとPostgreSQLを使用してリアルタイムチャットアプリケーションを構築する

次に、以下のスクリーンショットに示すように、チャットテーブルをクリックして、ユーザーのチャットメッセージを表示します。

NestjsとPostgreSQLを使用してリアルタイムチャットアプリケーションを構築する

アプリケーションのテスト

次に、2つの異なるタブまたはウィンドウでアプリケーションを開き、下のスクリーンショットに示すように、異なる電子メールアドレスでメッセージを送信してみます。

NestjsとPostgreSQLを使用してリアルタイムチャットアプリケーションを構築する

また、コンソールを見ると、ユーザーがhandleDisconnectandhandleConnectionメソッドによって処理されるサーバーに参加および切断したときにログが表示されます。

結論

このチュートリアル全体を通して、NestjsとPostgreSQLを使用してリアルタイムチャットアプリケーションを作成する方法を探りました。まず、NestjsとWebSocketの簡単な紹介から始めました。次に、実装を示すデモアプリケーションを作成しました。あなたが求めている知識を得たことを願っています。おそらく、NestjsのドキュメントからWebSocketの実装について詳しく学び、アプリケーションを追加拡張することができます。

ソース:https ://betterprogramming.pub/build-a-real-time-chat-application-with-nestjs-and-postgresql-a212502eb436

#nestjs #postgresql #chat