1652526000
このチュートリアルのコードは、私の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');
...
}
次に、ディレクトリにstatic
とviews
フォルダを作成します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インスタンスを作成し、サーバー上のイベントをリッスンして、サーバーとの間でメッセージを送受信しました。ユーザーがデフォルトでチャットに参加するときに、古いチャットを利用できるようにする必要があります。アプリケーションは次のスクリーンショットのようになります。
Arctypeを使用したユーザーデータの表示
これで、チャットアプリケーションが正常に作成されました。まず、Arctypeでユーザーのデータを見てみましょう。開始するには、Arctypeを起動し、[MySQL]タブをクリックして、次のスクリーンショットに示すように、次のMySQLクレデンシャルを入力します。
次に、以下のスクリーンショットに示すように、チャットテーブルをクリックして、ユーザーのチャットメッセージを表示します。
アプリケーションのテスト
次に、2つの異なるタブまたはウィンドウでアプリケーションを開き、下のスクリーンショットに示すように、異なる電子メールアドレスでメッセージを送信してみます。
また、コンソールを見ると、ユーザーがhandleDisconnect
andhandleConnection
メソッドによって処理されるサーバーに参加および切断したときにログが表示されます。
結論
このチュートリアル全体を通して、NestjsとPostgreSQLを使用してリアルタイムチャットアプリケーションを作成する方法を探りました。まず、NestjsとWebSocketの簡単な紹介から始めました。次に、実装を示すデモアプリケーションを作成しました。あなたが求めている知識を得たことを願っています。おそらく、NestjsのドキュメントからWebSocketの実装について詳しく学び、アプリケーションを追加拡張することができます。
1652526000
このチュートリアルのコードは、私の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');
...
}
次に、ディレクトリにstatic
とviews
フォルダを作成します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インスタンスを作成し、サーバー上のイベントをリッスンして、サーバーとの間でメッセージを送受信しました。ユーザーがデフォルトでチャットに参加するときに、古いチャットを利用できるようにする必要があります。アプリケーションは次のスクリーンショットのようになります。
Arctypeを使用したユーザーデータの表示
これで、チャットアプリケーションが正常に作成されました。まず、Arctypeでユーザーのデータを見てみましょう。開始するには、Arctypeを起動し、[MySQL]タブをクリックして、次のスクリーンショットに示すように、次のMySQLクレデンシャルを入力します。
次に、以下のスクリーンショットに示すように、チャットテーブルをクリックして、ユーザーのチャットメッセージを表示します。
アプリケーションのテスト
次に、2つの異なるタブまたはウィンドウでアプリケーションを開き、下のスクリーンショットに示すように、異なる電子メールアドレスでメッセージを送信してみます。
また、コンソールを見ると、ユーザーがhandleDisconnect
andhandleConnection
メソッドによって処理されるサーバーに参加および切断したときにログが表示されます。
結論
このチュートリアル全体を通して、NestjsとPostgreSQLを使用してリアルタイムチャットアプリケーションを作成する方法を探りました。まず、NestjsとWebSocketの簡単な紹介から始めました。次に、実装を示すデモアプリケーションを作成しました。あなたが求めている知識を得たことを願っています。おそらく、NestjsのドキュメントからWebSocketの実装について詳しく学び、アプリケーションを追加拡張することができます。