今回は、Webブラウザに備わっているWebSocketの機能を利用してリアルタイムチャットを作ってみましょう。チャットの仕組みを学ぶことで、基本的なネットワークの仕組みである、サーバーとクライアントの役割についても理解を深めることができるでしょう。
リアルチャットを作るのに必要な知識
チャットを作るのにあたって、必要な知識をまとめてみましょう。チャット(英語: chat)とは、コンピューターのネットワーク上で、リアルタイムに複数の人が文字を入力して会話をするシステムのことです。
チャットのプログラムを作る際に必要なのは、ユーザーが手元の端末で動かすチャットのクライアントに加えて、各ユーザーのチャットをまとめて送受信するチャットサーバーです。というのは、クライアントアプリがあるだけでは、各ユーザー動詞はつながっておらず、メッセージをやりとりすることができません。そのため、チャットのシステムを作るには、チャットサーバーとチャットクライアントの二つを作ることが必要なのです。
上記の図では、サーバーが中央にあり、複数のクライアントが中央のサーバーに接続してデータの交換を行うというシステムを表しています。このようなシステムは『クライアントサーバシステム』と呼ばれるのですが、インターネットをはじめ多くのネットワークで広く利用されている形態となっています。
WebSocketを使おう
今回、リアルタイムチャットを作るのに当たって、WebSocketという技術を利用します。これは、最近のWebブラウザに搭載されている技術です。ブラウザを通じてサーバーとの双方向通信を行うための技術です。なでしこ3でも、WebSocketに対応しています。
WebSocketサーバー
WebSocketでサーバーを作成するには、PC版のなでしこ3とWebSocketプラグインをダウンロードする必要があります。筆者が開発者であるという特権で、本稿執筆時の最新版であるv3.0.74(Windows版)ではWebSocketプラグインを最初から同梱させました。
Windows版はこちらからダウンロードしてみてください。
なお、macOSやLinuxで利用する場合には、最初にNode.jsをインストールした上で、ターミナルを起動します。そして、以下のコマンドを実行して、なでしこ3およびWebSocketプラグインをインストールしてください。
# --- macOSやLinuxの場合 ---
# なでしこ3のインストール
npm install nadesiko3
# プラグインをインストール
npm install nadesiko3-websocket
# なでしこ3エディタを起動する
npm run nako3edit
それから、なでしこ3で、WebSocketを使ったチャットサーバーを作ってみましょう。Windowsでは、nakopad.vbsをダブルクリックして、以下のプログラムを入力して「echo-server.nako3」という名前で保存しましょう。
!「nadesiko3-websocket」を取り込む。
#--- 設定 ---
PORT=5001
#--- イベントの指定 ---
WSサーバ起動成功した時には
「● WebSocketサーバ(ECHOサーバ)を起動しました」と表示。
自分IPアドレス取得して反復
「- ws://{対象}:{PORT}」を表示。
ここまで
ここまで
WSサーバ起動失敗した時には
「WebSocketサーバの起動に失敗しました」と表示。
ここまで
WSサーバ接続した時には
IP=対象["connection"]["remoteAddress"]
「クライアント{IP}が接続しました」と表示。
ここまで
WSサーバ受信時には
「受信:{対象}」と表示。
対象をWSサーバ全送信。
ここまで
#--- WebSocketを起動 ---
PORTでWSサーバ起動。
プログラムを実行すると、以下のようにWebSocketサーバーが起動します。macOS/Linuxでは「cnako3 echo-server.nako3」とターミナルでコマンドを実行します。
このプログラムは、ポート5001でWebSocketサーバーを起動します。このプログラムでは、クライアントが接続してきて、メッセージを受信すると、接続済みのクライアント全てにメッセージを受信したメッセージをそのまま送信するというものになっています。
このような受信した内容をそのまま接続中のクライアントに送信するサーバーをエコーサーバーと呼びます。
クライアント側のプログラム
次に、上記のエコーサーバーに接続して、メッセージをやりとりするクライアント側のプログラムを作ってみましょう。次はWebブラウザ上で実行するプログラムを作ります。
テキストエディタに以下のコードを記述して、「chat-client.html」という名前で保存しましょう。
<!DOCTYPE html><html><meta charset="UTF-8"><body>
<h1>チャットクライアント</h1>
<div>
以下にメッセージを記入:<br>
名前: <input type="text" id="name" value="クジラ"><br>
内容: <input type="text" id="msg" value="テスト。"><br>
<button id="sendButton">送信</button><br>
</div>
<div><h2>会話ログ</h2>
<textarea id="logs" rows="10" cols="40"></textarea>
</div>
<script type="text/javascript"
src="https://cdn.jsdelivr.net/npm/nadesiko3@3.0.75/release/wnako3.js?run"></script>
<script type="なでしこ">
「チャットをはじめます。
サーバーのアドレスを入力してください。」と尋ねるて、WSアドレスに代入。
WS受信時には
「#logs」のテキスト取得して、Lに代入。
L=対象&改行&L。
「#logs」へLをテキスト設定。
ここまで
WSアドレスへWS接続。
「#sendButton」をクリックした時には
F名前=「#name」のテキスト取得。
F内容=「#msg」のテキスト取得。
「{今}> {F名前}: {F内容}」をWS送信。
ここまで。
</script>
</body></html>
そして、上記のプログラムをWebブラウザにドラッグするとプログラムが実行されます。実行すると、サーバーのアドレスを尋ねられます。そこで「ws://127.0.0.1:5001」と入力してください。
内容の部分にメッセージを入力して「送信」ボタンをクリックしましょう。うまくエコーサーバーと接続できれば、会話ログに送信した内容が表示されます。次に、複数のブラウザウィンドウを立ち上げて実行してみましょう。一カ所で送信したメッセージが他のクライアントにリアルタイムに反映されれば、正しくチャットが実行されています。
プログラムを確認してみましょう。プログラムの前半ではHTMLで入力フォームを定義します。ここでは名前と内容の二つのテキストボックスと送信ボタン、ログを表示するテキストエリアを定義しました。
後半では、WebSocketで作成したサーバーに接続して、メッセージを受信した会話ログに表示するようにします。「WS接続」や「WS送信」のようにWSから始まっている命令がWebSocketに関連する命令です。
チャットを改造してみよう
HTMLに精通している方であれば、CSSなどを記述してもっと見た目の良いチャットツールを作ることができるでしょう。
また、ここでは一つのコンピューターの中だけで遊べるチャットクライアントを作りましたが、サーバーのアドレスを変更することで、LAN内の別のコンピューターで実行しているWebSocketサーバーに接続することもできます。
サーバーを起動したとき、以下のように複数のサーバーのアドレス一覧を表示するようにしています。この中でIPアドレスが「ws://127.0.0.1:5001」のものは、そのコンピューターそのものを表しています。そして、「ws://192.168.xxx.xxx:5001」のように表示されるものがあれば、それはLAN内のコンピューターから参照できることを表しています。(xxxの部分が変化します。)
そこで、クライアントアプリの方で「ws://192.168.0.14:5001」のように入力すると、LAN内のそのサーバーに接続されます。
このように書き換えると、LAN内の異なる端末でもチャットを実行できます。なでしこ3はスマートフォンやタブレットにも対応しているので、Webサーバーを起動し、クライアントのHTMLファイルを表示すると、スマートフォンでもチャットを楽しむことができます。
例えば、上記のWebSocketサーバーに、Webサーバーの機能も加えてみましょう。以下のようにプログラムを書き換えて実行してみましょう。すると、WebサーバーとWebSocketサーバーの二つのサーバーを起動します。
!「nadesiko3-websocket」を取り込む。
!「plugin_express」を取り込む。
#--- 設定 ---
WEB_PORT=8080
WS_PORT=5001
#--- WebSocketの指定 ---
WSサーバ起動成功した時には
「● WebSocketサーバ(ECHOサーバ)を起動しました」と表示。
自分IPアドレス取得して反復
「- ws://{対象}:{WS_PORT}」を表示。
ここまで
ここまで
WSサーバ起動失敗した時には
「WebSocketサーバの起動に失敗しました」と表示。
ここまで
WSサーバ接続した時には
IP=対象["connection"]["remoteAddress"]
「クライアント{IP}が接続しました」と表示。
ここまで
WSサーバ受信時には
「受信:{対象}」と表示。
対象をWSサーバ全送信。
ここまで
WS_PORTでWSサーバ起動。
#--- Webサーバーの指定 ---
WEB_PORTでWEBサーバ起動した時には
「下記のアドレスにWEBブラウザでアクセスしてください。」と表示。
自分IPアドレス取得して反復
「- http://{対象}:{WEB_PORT}」を表示。
ここまで
「/」へWEBサーバGETした時には
「chat-client.html」を開いて、Sに代入。
SをWEBサーバ出力。
ここまで。
ここまで。
試しに、上記のプログラムを実行して、表示されたアドレスにスマートフォンで表示すると、以下のように表示されます。
まとめ
以上、少し駆け足でしたが、リアルタイムチャットを「なでしこ3」で開発してみました。LAN内であれば様々な端末で手軽に実行できるので、改良するといろいろな用途で使えて楽しいことでしょう。改良して遊んでみてください。
自由型プログラマー。くじらはんどにて、プログラミングの楽しさを伝える活動をしている。代表作に、日本語プログラミング言語「なでしこ」 、テキスト音楽「サクラ」など。2001年オンラインソフト大賞入賞、2004年度未踏ユース スーパークリエータ認定、2010年 OSS貢献者章受賞。技術書も多く執筆している。