LoginSignup
3
3

More than 1 year has passed since last update.

<Nodejs>Websocketでシンプルなチャットアプリを作るチュートリアル

Posted at

今回は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

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3