Node.jsとSocket.IOでリアルタイムのチャットアプリを作ってみる
前回、Node.jsとSocket.IOでリアルタイムでやりとりができるチャットアプリを作ってみた。
Socket.IOのおかげで少ないコードでチャットアプリを作ることが出来たけれども、
これだと世間で見られるチャットアプリとは程遠い。
というわけで、
前回の簡易版に追加でカスタマイズしていく形で、
Socket.IOにより触れていくことにする。
チャットアプリで欲しい機能といえば、
今接続している方で誰が入力中なのか?は欲しいところ。
というわけで、入力中の表示の追加を試してみる。
ファイルの構成は前回同様
workspace ├── index.html └── server.js
こんな感じ。
それでは、各ファイルに入力中のイベントを追加してみる。
server.js
/** サーバの構築とプロトコルをWebSocketにUpgradeするところまでは省略 //2.イベントの定義 io.on("connection", function(socket){ // 接続開始のカスタムイベント(接続元ユーザを保存し、他ユーザへ通知) socket.on("connected", function(name){ /** 省略 **/ }); // メッセージ送信カスタムイベント socket.on("publish", function(data){ /** 省略 **/ }); // タイピング開始 let nowTyping = 0; socket.on("start typing", function(){ if (nowTyping <= 0) { socket.broadcast.emit("start typing", userHash[socket.id]); } nowTyping++; setTimeout(function(){ nowTyping--; if (nowTyping <= 0) { socket.broadcast.emit("stop typing"); } }, 3000); }); // タイピング終了 socket.on("stop typing", function(){ nowTyping = 0; socket.broadcast.emit("stop typing"); }); // 接続終了組み込みイベント(接続元ユーザを削除し、他ユーザへ通知) socket.on("disconnect", function(){ /** 省略 **/ }); });
server.jsでは、start typingとstop typingいうイベントを追加している。
socket.on("start typing", 処理);の処理内で、socket.broadcast.emit(イベント);というコードがあるが、socketとemitの間にbroadcastというオブジェクトをかますことで、自身以外のすべてのソケット(ブラウザ)に対してイベントを実行するということができる。
続いて、index.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>web socket</title> </head> <body> <input type="text" id="msg_input" style="width:200px;"> <button onclick="publishMessage();">語る</button> <div id="msg"></div> <div id="system_text"></div> <script src="//cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.3/socket.io.js"></script> <script> var systemText = document.querySelector("#system_text"); //イベントとコールバックの定義 var socket = io.connect("http://localhost:8080"); socket.on("connected", function(name){}); socket.on("publish", function(data){ addMessage(data.value);}); socket.on("disconnect", function(){}); socket.on("start typing", function(typinguser){ systemText.innerHTML += typinguser + 'が入力中'; }); socket.on("stop typing", function(){ systemText.innerHTML = ""; }); var msgArea = document.querySelector("#msg"); var myName = Math.floor(Math.random()*100) + "さん"; addMessage("貴方は" + myName + "として入室しました"); start(myName);
// 入力開始と同時にタイピンスタートを伝える document.querySelector("#msg_input").addEventListener("keyup", function(){ socket.emit("start typing"); }); function start(name){ /** 省略 **/ } function publishMessage(){ var textInput = document.querySelector("#msg_input"); var msg = "[" + myName + "] " + textInput.value; socket.emit("publish", {value: msg}); textInput.value = ""; // 投稿と同時にタイピング終了を伝える **/ socket.emit("stop typing"); } function addMessage(msg){ /** 省略 **/ } </script> </body> </html>
※buttonタグはonclickでmsg_inputはDOMで指定している雑さは大目に見てください
太字で囲った箇所が追加分で、各所でタイピングの開始と終了のイベントを追加し、
表示中の表記の箇所も追加している。
このコードを実行すると、
このように入力中の表示が追加されるようになった。