今回はNodejsのwsライブラリを使ってシンプルなチャットアプリを作ってみました。
作るものの詳細
・クライアントから受信したメッセージを全クライアントに配信(Websocketを使用)
・WebサーバーにはExpressを使用する
私の環境
・Node.js: v15.6.0
・ライブラリ: Express, WS
・OS: Windows11
プロジェクトを作成
./project_root
npm init
Enter連打で大丈夫です。
Webサーバーを構築する。
index.js
//ここからexpress
//expressの設定
var express = require('express');
var app = express();
//expressのルーターを設定
app.get('/', (req, res) => {
//index.htmlを返す
res.sendFile(__dirname + '/index.html');
});
//expressのエラー処理
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).send('Something broke!');
});
//expressのサーバー起動
app.listen(80, () => {
console.log('Example app listening on port 80!');
});
expressサーバーの最小構成です。expressについて詳しく知りたい方はこちらを参考にしてください。
今回は、index.htmlを返すようにしています。index.htmlの作成に付いては別のセクションで解説します。
Websocketサーバーを構築する。
まだwsライブラリをインストールしていない場合は以下のコマンドを使用してインストールしてください。
./project_root
npm install ws
先程のindex.jsの下に、以下のコードを追加してください。
index.js
//ここからws
// WebSocketのサーバの生成
let ws = require('ws')
var server = new ws.Server({port:5001});
// 接続時に呼ばれる
server.on('connection', ws => {
//クライアンの数をカウントする
console.log(server.clients.size + ' clients connected');
//全クライアントに送信
server.clients.forEach(client => {
//入室メッセージを送信
client.send('一人入室しました。');
//何人オンラインかを送信
client.send(server.clients.size + '人がオンラインです。');
});
// クライアントからのデータ受信時に呼ばれる
ws.on('message', message => {
//メッセージの内容を表示
console.log(message.toString());
//message.tostring()がからの場合は何もしない
if(message.toString() == ''){
//コンソールに表示
console.log('メッセージが空です');
return;
}else{
//メッセージを全クライアントに送信
server.clients.forEach(client => {
client.send(message.toString());
});
}
});
// 切断時に呼ばれる
ws.on('close', () => {
console.log('close');
//クライアントの数をカウントする
console.log(server.clients.size + ' clients connected');
//全クライアントに送信
server.clients.forEach(client => {
//退室メッセージを送信
client.send('一人退室しました。');
//何人オンラインかを送信
client.send(server.clients.size + '人がオンラインです。');
});
});
// エラー時に呼ばれる
ws.on('error', err => {
console.log('error: %s', err);
});
});
コメント通りなので、解説は省かさせていただきます。
クライアントの作成
同フォルダーにindex.htmlを作成してください。
index.js
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>チャットテスト</title>
<!---cssライブラリをインストール-->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
</head>
<body>
<!--メッセージ-->
<div class="form-group">
<!-- 送信ボタン -->
<input type="text" name="message" id="message" class="form-control">
<input type="button" id="send_button" value="送信" class="btn btn-primary">
<ul id="messages" class="list-group"></ul>
</div>
<script>
// WebSocketのクライアントの生成
let ws = new WebSocket('ws://192.168.2.100:5001');
// 接続時に呼ばれる
ws.addEventListener('open', e => {
console.log('接続しました。')
})
//エラー時に呼ばれる
ws.addEventListener('error', e => {
console.log('エラーが発生しました。')
})
// Listen for messages
ws.addEventListener('message', function (event) {
console.log('Message from server ', event.data);
//ulにメッセージを追加
let messages = document.getElementById('messages')
let li = document.createElement('li')
li.innerText = event.data
//liにクラスを追加
li.className = 'list-group-item'
messages.prepend(li)
});
// ボタンクリック時に呼ばれる
document.getElementById('send_button').addEventListener('click', e => {
//ボックスが空だったら警告を出す
if(document.getElementById('message').value == ''){
alert('メッセージを入力してください')
return
}else{
//メッセージを送信
ws.send(document.getElementById('message').value)
//テキストボックスを空にする
document.getElementById('message').value = ''
}
})
</script>
受信したメッセージをulの一番上に追加しています。
完成品
参考にした記事
・https://developer.mozilla.org/ja/docs/Web/API/WebSockets_API
・https://github.com/websockets/ws