#Fastify ## [[Fastify]]で[[WebSocket]]を使う [[fastify-websocket]]を使う。 ## プロジェクトベースの作成 ```console:powershell npx degit tadashi-aikawa/typescript-vscode-base fastify-websocket-use cd fastify-websocket-use init.ps1 ``` ## [[Fastify]]と[[fastify-websocket]]インストール ```console:powershell npm i fastify fastify-websocket ``` ## ソースコードを書く [[FastifyでTypeScript]]のコードを書く。まずは[[fastify-websocket]]なしで。 ```ts:index.ts import fastify from 'fastify' const server = fastify() server.get('/ping', async (request, reply) => { return 'pong\n' }) server.listen(8080, (err, address) => { if (err) { console.error(err) process.exit(1) } console.log(`Server listening at ${address}`) }) ``` 疎通確認。 ```console $ curl localhost:8080/ping pong ``` ## [[fastify-websocket]]を使う ```ts:index.ts import fastify, { FastifyRequest } from "fastify"; import { SocketStream } from "fastify-websocket"; const server = fastify(); server.register(require("fastify-websocket")); server.get("/ping", async (request, reply) => { return "pong\n"; }); server.get( "/subscribe", { websocket: true }, (connection: SocketStream, req: FastifyRequest) => { connection.socket.on("message", (message: string) => { connection.socket.send(`I got your message: ${message}`); }); } ); server.listen(8080, (err, address) => { if (err) { console.error(err); process.exit(1); } console.log(`Server listening at ${address}`); }); ``` `ws:locahost:8080/subscribe`に接続してメッセージを送ると反応がある。 ## サーバーからクライアントにメッセージを送る 5秒おきに現在時刻のタイムスタンプを返却するAPIを作る。 ```ts:index.ts import fastify, { FastifyRequest } from "fastify"; import { SocketStream } from "fastify-websocket"; const server = fastify(); server.register(require("fastify-websocket")); server.get("/ping", async (request, reply) => { return "pong\n"; }); server.get( "/timer", { websocket: true }, (connection: SocketStream, req: FastifyRequest) => { setInterval(() => { connection.socket.send(Date.now()); }, 5000); connection.socket.on("message", (message: string) => { connection.socket.send(`I am alive.`); }); } ); server.listen(8080, (err, address) => { if (err) { console.error(err); process.exit(1); } console.log(`Server listening at ${address}`); }); ``` `ws:locahost:8080/timer`に接続すると5分おきにメッセージを受信する。 ## ファイルの変更があったら知らせる サーバーでファイルが変更されたらクライアントに通知するAPIをつくる。 ```console:chokidarのインストール npm i chokidar ``` ```ts:index.ts import chokidar from "chokidar"; import fastify from "fastify"; import { SocketStream } from "fastify-websocket"; const server = fastify(); server.register(require("fastify-websocket")); server.get("/ping", async (request, reply) => { return "pong\n"; }); server.get<{ Querystring: { path: string }; }>("/watch", { websocket: true }, (connection: SocketStream, req) => { const watcher = chokidar.watch(req.query.path, { ignoreInitial: true, ignored: "node_modules/*", }); watcher .on("add", (path) => { connection.socket.send(`Added ${path}`); }) .on("change", (path) => { connection.socket.send(`Updated ${path}`); }) .on("unlink", (path) => { connection.socket.send(`Deleted ${path}`); }); connection.socket.on("message", (message: string) => { connection.socket.send(`I am alive.`); }); connection.socket.on("close", () => { console.log("disconnect watcher"); watcher.close(); }); }); server.listen(8080, (err, address) => { if (err) { console.error(err); process.exit(1); } console.log(`Server listening at ${address}`); }); ``` `ws://localhost:8080/watch?path=*`ですべてのエントリを監視。`path`に指定することで細かく監視対象を制御できる。