📘
TypeScript で WebSocket サーバを立てる
はじめに
TypeScript で WebSocket サーバを立てる方法を記載します。
こちらの記事の内容を参考にしながら備忘録のために記載しました。
作業プロジェクトの準備
TypeScript の簡易プロジェクトを作成します。
長いので折りたたんでおきます。
package.json を作成
package.json
を作成します。
$ mkdir -p node-ws-sample
$ cd node-ws-sample
$ pnpm init
package.json
を変更します。
package.json
{
"name": "mute-sample",
"version": "1.0.0",
"description": "",
- "main": "index.js",
- "scripts": {
- "test": "echo \"Error: no test specified\" && exit 1"
- },
- "keywords": [],
- "author": "",
- "license": "ISC"
+ "main": "index.ts",
+ "scripts": {
+ "typecheck": "tsc --noEmit",
+ "dev": "vite-node index.ts",
+ "build": "tsc"
+ },
+ "keywords": [],
+ "author": "",
}
TypeScript & vite-node をインストール
TypeScript と vite-node をインストールします。補足としてこちらの理由のため ts-node
ではなく vite-node
を利用します。
$ pnpm install -D typescript vite-node @types/node
TypeScriptの設定ファイルを作成
tsconfig.json
を作成します。
$ npx tsc --init
tsconfig.json
を上書きします。
tsconfig.json
{
"compilerOptions": {
/* Base Options: */
"esModuleInterop": true,
"skipLibCheck": true,
"target": "ES2022",
"allowJs": true,
"resolveJsonModule": true,
"moduleDetection": "force",
"isolatedModules": true,
/* Strictness */
"strict": true,
"noUncheckedIndexedAccess": true,
"checkJs": true,
/* Bundled projects */
"noEmit": true,
"outDir": "dist",
"module": "ESNext",
"moduleResolution": "Bundler",
"jsx": "preserve",
"incremental": true,
"sourceMap": true,
},
"include": ["**/*.ts", "**/*.js"],
"exclude": ["node_modules", "dist"]
}
git
を初期化します。
$ git init
.gitignore
を作成します。
$ touch .gitignore
.gitignore
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
.yarn/install-state.gz
# testing
/coverage
# next.js
/.next/
/out/
# production
/build
dist/
# misc
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# local env files
.env*.local
.env
# vercel
.vercel
# typescript
*.tsbuildinfo
next-env.d.ts
動作確認コードを作成
動作を確認するためのコードを作成します。
$ touch index.ts
index.ts
console.log('Hello, World');
型チェック
型チェックします。
$ pnpm run typecheck
動作確認
動作確認を実施します。
$ pnpm run dev
Hello, World
コミットします。
$ git add .
$ git commit -m "初回コミット"
Node.js で WebSocket を利用
インストール
WebSocket を利用するためのライブラリと型をインストールします。
$ pnpm install ws
$ pnpm install --save-dev @types/ws
サーバ
サーバ用のコードを作成します。
$ touch server.ts
server.ts
import { WebSocket, WebSocketServer } from "ws";
// サーバーのポート番号
const port = 8080;
// WebSocketサーバーを作成
const server = new WebSocketServer({ port });
// 接続中のクライアントを格納するSet
const clients = new Set<WebSocket>();
console.log(`WebSocket Server is running on port ${port}`);
// 接続が確立されたときの処理
server.on("connection", (ws) => {
console.log("Client has connected");
// クライアントを追加
clients.add(ws);
ws.on("message", (message) => {
console.log(`Received message => ${message}`);
// すべてのクライアントにメッセージをブロードキャスト
clients.forEach((client) => {
if (client.readyState === WebSocket.OPEN) {
client.send(`\nClient said: ${message}`);
}
});
});
// クライアントが切断されたときの処理
ws.on("close", () => {
console.log("Client has disconnected");
clients.delete(ws); // クライアントを削除
});
});
クライアント
クライアント用のコードを作成します。
$ touch client.ts
client.ts
import WebSocket from "ws";
import readline from "readline";
// 接続先のURL
const url = "ws://localhost:8080";
// WebSocketクライアントを作成
const ws = new WebSocket(url);
// コマンドラインからの入力を受け付けるためのインターフェースを作成
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
// open イベントは、 WebSocket のコネクションが開かれたときに発生します
ws.onopen = () => {
console.log("Connected to the server.");
// ユーザーからの入力を受け付けます
promptInput();
};
// ユーザーからの入力を受け付ける関数です
function promptInput() {
rl.question("Enter message to send: ", (message) => {
if (message === "exit") {
// 'exit'と入力した場合、プログラムを終了します
rl.close();
ws.close();
} else {
ws.send(message);
}
});
}
// onmessage イベントは、WebSocketからメッセージを受信したときに発生します。
ws.onmessage = (e) => {
console.log(`Received: ${e.data}`);
promptInput();
};
// onerror イベントは、WebSocketのエラーが発生したときに発生します。
ws.onerror = (error) => {
console.error(`WebSocket Error: ${error}`);
};
// oncloseは、WebSocketのコネクションが閉じられたときに発生します。
ws.onclose = () => {
console.log("Disconnected from the server");
rl.close();
};
動作確認
サーバーを起動します。
$ pnpm vite-node server.ts
クライアントで接続します。今回は接続するクライアントを 2 つ準備しています。
$ pnpm vite-node client.ts
クライアント1,クライアント2からメッセージを送受信できます。
コミットします。
$ git add .
$ git commit -m "WebSocketの機能を追加"
作業リポジトリ
参考
Discussion