
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で指定している雑さは大目に見てください
太字で囲った箇所が追加分で、各所でタイピングの開始と終了のイベントを追加し、
表示中の表記の箇所も追加している。
このコードを実行すると、

このように入力中の表示が追加されるようになった。





