まずはサーバー側。クライアント届くデータを await getで受け取り適当に処理してsendで返すテストをプログラムを作って、test-sync.js として保存します。(この例では500msec無駄に待って、倍返し)
import { ServerSync } from "https://code4sabae.github.io/js/ServerSync.js"; import { sleep } from "https://code4sabae.github.io/js/sleep.js"; new ServerSync(8881, async (ws) => { for (;;) { const data = await ws.get(); await sleep(500); ws.send({ testsync: data, n: data.ab * 2 }); } });
続いて、クライアント側。HTMLで作ったボタンが押されるたびに、カウントしてサーバーへ送信し、返答を待って表示するプログラム。staticというフォルダを作り、index.html として保存します。
<!DOCTYPE html><html><script type="module"> import { ClientSync } from "https://code4sabae.github.io/js/ClientSync.js"; import { waitClick } from "https://code4sabae.github.io/js/waitClick.js"; window.onload = async () => { const ws = await new ClientSync().connect("/ws/"); let cnt = 0; for (;;) { await waitClick(btn); ws.send({ ab: ++cnt }); const res = await ws.get(); console.log(res); divn.textContent = res.n; } }; </script><body> <button id="btn">click me!</button><br> <div id="divn"></div> <body></html>
JavaScriptのランタイム、Denoを使って動かしましょう。コンソールで test-sync.js があるフォルダに移動し、下記コマンドで実行。
$ deno run -A test-sync.js
ブラウザで http://localhost:8881/ を開くと、動かせます!
サーバーとクライアントをつないだプログラムができました!簡単!
反応が遅い?サーバーで時間がかかる処理をやっている風を演出しているだけです。test-sync.jsの await sleep をコメントアウトしたり、数値を変えてみましょう。
簡単さの肝は、WebSocketClientと WebSocketServerクラス。await getとsendを使ってサーバーもクライアントも同じように使えるように、WebSocketを同期処理でカプセル化しています。(src on GitHub)
同期型通信の利点は、APIを一つ一つ設計しなくても、サーバーとクライアントのやり取りをそれぞれ順序立てて作るだけなので分かりやすいことです。福井高専の卒業研究や、卒業後エージェント指向が流行った頃の仕事は、同じようなコードをJavaで実装してたことを思い出しました。
HTML/CSS/JavaScriptでいろんなUIを作って、サーバー通信を経由すれば、手軽にいろんなことができますね。 強力な処理を作った時は、接続元をローカルIPに限定する、鍵を付けるなど、セキュリティ対策も忘れずに!