この記事では、問題のチャットをゼロから作成する方法を学びます。 ちなみに、ここで彼との仕事はどのように見えるかです。
TypeScriptチャット
リアルタイムアプリケーションについて
ウィキペディアのこの定義によると、リアルタイムアプリケーションを使用すると、情報のソースを定期的に調査する必要なく、関心のあるエンティティが公開後すぐに情報を受け取ることができます。 したがって、この種のアプリケーションは、特定のアクションが即座に、遅延なく発生するという感覚をユーザーに与える必要があります。
WebSocketプロトコル
WebSocketは、双方向データチャネルを整理できるプロトコルです。 私たちの場合、これは、ブラウザーとWebサーバーがリアルタイムで通信できることを意味し、それらの間にオープンな接続がある場合、互いにメッセージを送信します。
WebSocket通信
アプリケーション構造
アプリケーションのクライアント部分とサーバー部分に関連するコードを別々のフォルダーに配置します。 完成したアプリケーションの構造を以下に示します。 プロジェクトの主要なファイルについて話すときは、以下の詳細を検討します。
server/ |- src/ |- package.json |- tsconfig.json |- gulpfile.js client/ |- src/ |- package.json |- tsconfig.json |- .angular-cli.json
WebSocket実装の選択
WebSocketプロトコルは仕様であるため 、いくつかの実用的な実装を見つけることができます。 ここでは、
この場合、 Socket.IOライブラリを使用します。 これは、リアルタイムのデータ交換機能を実装する最も高速で信頼性の高いライブラリの1つです。
サーバーでTypeScriptを使用する理由
TypeScriptはプログラマに優れた機能を提供し、開発チームは言語を最新の状態に保ちます。 さらに、タイピングを使用すると、通常のJSを使用する場合と比較して、コードのエラーの数を減らすことができます。 私にとって、これらの理由は、サーバーでTSを使用するのに十分です。
サーバーアプリケーションの初期化
package.json
ファイルを作成し 、次の依存関係をインストールします。
npm install --save express socket.io @types/express @types/socket.io
さらに、
gulp
と
typescript
をプロジェクトに統合するために、いくつかの開発依存関係をインストールする必要があります。これらはすべて、完成したプロジェクトの作成とアセンブリ中に役立ちます。
npm install --save-dev typescript gulp gulp-typescript
TypeScriptコンパイラのセットアップ
tsconfig.json
ファイルを作成し、
tsconfig.json
ファイルを入れます。
{ "files": [ "src/*.ts", "src/model/*.ts" ], "compilerOptions": { "target": "es5" } }
データモデルの説明
静的型付けの機能を使用して、小さなデータモデルを作成します。
export class User { constructor(private name: string) {} } export class Message { constructor(private from: User, private content: string) {} } export class ChatMessage extends Message{ constructor(from: User, content: string) { super(from, content); } }
server/src
ディレクトリ構造を見てください:
server/ |- src/ |- model/ |- message.model.ts |- user.model.ts |- index.ts |- server.ts |- package.json |- tsconfig.json |- gulpfile.js
チャットサーバーの実装
server
ディレクトリのメインファイルは
index.ts
および
chat-server.ts
です。 1つ目は
ChatServer
アプリケーションの作成とエクスポートを可能にし、2つ目はexpressおよびSocket.IO構成を含みます:
index.js
ファイルのコードは次のとおりです。
import { ChatServer } from './chat-server'; let app = new ChatServer().getApp(); export { app };
chat-server.ts
次の
chat-server.ts
。
import { createServer, Server } from 'http'; import * as express from 'express'; import * as socketIo from 'socket.io'; import { Message } from './model'; export class ChatServer { public static readonly PORT:number = 8080; private app: express.Application; private server: Server; private io: SocketIO.Server; private port: string | number; constructor() { this.createApp(); this.config(); this.createServer(); this.sockets(); this.listen(); } private createApp(): void { this.app = express(); } private createServer(): void { this.server = createServer(this.app); } private config(): void { this.port = process.env.PORT || ChatServer.PORT; } private sockets(): void { this.io = socketIo(this.server); } private listen(): void { this.server.listen(this.port, () => { console.log('Running server on port %s', this.port); }); this.io.on('connect', (socket: any) => { console.log('Connected client on port %s.', this.port); socket.on('message', (m: Message) => { console.log('[server](message): %s', JSON.stringify(m)); this.io.emit('message', m); }); socket.on('disconnect', () => { console.log('Client disconnected'); }); }); } public getApp(): express.Application { return this.app; } }
サーバークラス
上記のコードは、次のクラスとそれらの関係を提供します。
サーバークラス図
サーバーを構築して起動する
Node.jsのベースとなっているV8エンジンに必要なJavaScriptファイルを取得するために、
gulpfile.js
ファイルに
build
タスクを追加します。
var gulp = require("gulp"); var ts = require("gulp-typescript"); var tsProject = ts.createProject("tsconfig.json"); gulp.task("build", function () { return tsProject.src() .pipe(tsProject()) .js.pipe(gulp.dest("./dist")); });
ご覧のとおり、ビルドプロセスの出力(JSファイル)は
dist
ディレクトリにあります。 アセンブリを完了するには、次のコマンドが必要です。
gulp build
サーバーを起動するには、次のコマンドを使用する必要があります。
node dist/index.js
チャットクライアント開発
Angular CLIを使用して、クライアント用のフォルダーを作成します。
ng new typescript-chat-client --routing --prefix tcc --skip-install
プロジェクトの依存関係をインストールします。 ここで
npm install
コマンドを実行できますが、このステップではYarnを使用することを好みます。
cd typescript-chat-client yarn install
角材コンポーネントセットをプロジェクトに追加する
Angular CLIを使用して作成されたプロジェクトで設定されたAngular Materialコンポーネントを活用するには、material.angular.ioの最新のマニュアルを参照し、それに応じて行動してください。
Angularプロジェクトの構造に関する推奨事項に従って、
shared
モジュールと
material
モジュールを作成します。
client/ |- src/ |- app/ |- chat/ |- shared/ |- material/ |- material.module.ts |- shared.module.ts |-app.module.ts
コマンドラインからこれを行うことができます:
ng generate module shared --module app ng generate module shared/material --module shared
これらのモジュール間の関係を評価するには、ファイル
app.module.ts
および
shared.module.ts
分析します。
ExpressとSocket.IOを接続する
次に、
express
および
socket.io
モジュールをクライアントアプリケーションに接続する必要があります。
npm install express socket.io --save
チャットモジュールとコンポーネント
チャットコンポーネントを作成する前に、新しいモジュールを作成します。
ng generate module chat --module app
次に、このモジュールにコンポーネントを追加します。
ng generate component chat --module chat
Webソケットと独自のモデルを使用するには、別の
shared
フォルダーを作成
shared
ます。 今回は、
chat
ディレクトリ内で:
ng generate service chat/shared/services/socket --module chat ng generate class chat/shared/model/user ng generate class chat/shared/model/message
結果は次の構造になります。
client/ |- src/ |- app/ |- chat/ |- shared/ |- model/ |- user.ts |- message.ts |- services/ |- socket.service.ts |- shared/ |-app.module.ts
観察されたオブジェクトとWebソケット
AngularアプリケーションはRxJSをサポートしているため、監視可能なオブジェクトを使用してSocket.IOイベントを操作できます。 したがって、
socket.services.ts
ファイルは次のようになります。
import { Injectable } from '@angular/core'; import { Observable } from 'rxjs/Observable'; import { Observer } from 'rxjs/Observer'; import { Message } from '../model/message'; import { Event } from '../model/event'; import * as socketIo from 'socket.io-client'; const SERVER_URL = 'http://localhost:8080'; @Injectable() export class SocketService { private socket; public initSocket(): void { this.socket = socketIo(SERVER_URL); } public send(message: Message): void { this.socket.emit('message', message); } public onMessage(): Observable<Message> { return new Observable<Message>(observer => { this.socket.on('message', (data: Message) => observer.next(data)); }); } public onEvent(event: Event): Observable<any> { return new Observable<Event>(observer => { this.socket.on(event, () => observer.next()); }); } }
これで、サーバーからのメッセージに応答する準備ができたので、
chat.component.ts
ファイルを考慮します(ここでは、マテリアルイベントとユーザーインターフェイスイベントに関するコードは省略されています)。
import { Component, OnInit } from '@angular/core'; import { Action } from './shared/model/action'; import { Event } from './shared/model/event'; import { Message } from './shared/model/message'; import { User } from './shared/model/user'; import { SocketService } from './shared/services/socket.service'; @Component({ selector: 'tcc-chat', templateUrl: './chat.component.html', styleUrls: ['./chat.component.css'] }) export class ChatComponent implements OnInit { action = Action; user: User; messages: Message[] = []; messageContent: string; ioConnection: any; constructor(private socketService: SocketService) { } ngOnInit(): void { this.initIoConnection(); } private initIoConnection(): void { this.socketService.initSocket(); this.ioConnection = this.socketService.onMessage() .subscribe((message: Message) => { this.messages.push(message); }); this.socketService.onEvent(Event.CONNECT) .subscribe(() => { console.log('connected'); }); this.socketService.onEvent(Event.DISCONNECT) .subscribe(() => { console.log('disconnected'); }); } public sendMessage(message: string): void { if (!message) { return; } this.socketService.send({ from: this.user, content: message }); this.messageContent = null; } public sendNotification(params: any, action: Action): void { let message: Message; if (action === Action.JOINED) { message = { from: this.user, action: action } } else if (action === Action.RENAME) { message = { action: action, content: { username: this.user.name, previousUsername: params.previousUsername } }; } this.socketService.send(message); } }
ChatComponent
初期化されるとすぐに、
ChatComponent
された
SocketService
オブジェクトをサブスクライブして、接続関連のイベントまたは着信メッセージを受信します。
sendMessage
sendNotification
と
sendNotification
は、それぞれ同じサービスを介してメッセージと通知を送信します。 通知は、新しいユーザーがチャットに参加したことをシステムに通知し、チャット参加者の名前を変更するために使用されます。
まとめ
この資料から、TypeScriptを使用してリアルタイムアプリケーションを作成する方法を学びました。TSはクライアントとサーバーの両方で使用され、WebSockets、Node.js、Angularなどのテクノロジーが関与するチャットです。 プロジェクトのソースコードはこちらにあります 。 そして、 ここに実際のチャットがあります(体験するには、ブラウザでこのページのタブをいくつか開いてください)。
親愛なる読者! TypeScriptを使用してサーバーアプリケーションを開発していますか?