socket.io で初めてチャット機能を作ってみる

3 min読了の目安(約3000字TECH技術記事

このエントリーでは React と Node.js と socket.io を使って初めてチャット機能を作ってみます。

構成

  • サーバーサイド
    • Node.js
      • socket.io
      • express
      • http
  • クライアントサイド
    • React
      • socket.io-client

サーバーサイド(./index.js)

モジュール読み込み

まずは、必要なモジュールを読み込みます。

index.js
var app = require('express')();
var http = require('http').createServer(app);
var io = require('socket.io')(http, {
  cors: {
    origin: '*',
    methods: ["GET", "POST"]
  }
});

expressでURLをハンドリングする

index.js
app.get('/', (req, res) => { 
  res.send({response:"good response"}).status(200);
});

http.listen(3001, () => {
  console.log('listening on http://localhost:3001');
});

socket.ioでソケットを使う

socket.ioのドキュメントは以下のリンクを参照してください。
https://socket.io/
https://socket.io/docs/v3/rooms/ (Rooms)

index.js
io.on('connection', (socket) => {
  //ユーザーのソケット接続時のイベント
  console.log('a user connected ' + socket.id);
  
  //ユーザーの名前設定時のイベント
  socket.on('set_nickname', (nickname) => {

    console.log(nickname + ' set his nickname');

    //クライアントサイドがメッセージを送信時のイベント
    socket.on("chat message c2s", (msg) =>{
      var nameAndMsgAndRoom = nickname + ": " + msg + " : in " + clientRoom;
      console.log(nameAndMsgAndRoom);
      //サーバーに接続しているすべてのユーザーにメッセージを送信
      socket.broadcast.emit("broadcast", nameAndMsgAndRoom);

    });
  });

  //ソケット切断時のイベント
  socket.on('disconnect', () => {
    console.log('user disconnected');
  });
});

クライアントサイド(React)

モジュール読み込み

App.js
import React, { useState } from 'react';
import socketIOClient from "socket.io-client";
const ENDPOINT = "http://localhost:3001";

ユーザーの名前の設定

App.js
    const [socket, setSocket] = useState();
    const [nickname, setNickname] = useState("");

    function socketSetNickname(){
      const socket = socketIOClient(ENDPOINT);
      if (socket !== undefined){
        //ソケットを通してset_nicknameイベントを発火する
        socket.emit('set_nickname', nickname);
      }
      //ソケットオブジェクトはReactのStateで管理する
      setSocket(socket);
    };

クライアントサイドからメッセージを送信する

App.js
    const [inputMessage, setInputMessage] = useState("");

    function addMessage() {
      if (socket !== undefined){
        //inputMessageはReactのStateで管理する
        console.log(inputMessage)
        socket.emit('chat message c2s', inputMessage);
      }
    };

ユーザーからのインプットを受け取るHTMLの記述

App.js
    return (
        <div>
            <div>
                <input id="m1" autoComplete="off" placeholder="nickname" onChange={event => setNickname(event.target.value)}/>
                <button onClick={socketSetNickname}>submit</button>

                <input id="m2" autoComplete="off" placeholder="message" onChange={(event) => setInputMessage(event.target.value) }/>
                <button onClick={addMessage}>submit</button>
		    
                <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
            </div>
        </div>
    )

以上のコードを適当なところに書いて実行すれば、超シンプルなリアルタイムチャット機能が作れます。(part2ではバックエンドとフロントエンド間のデータの送信を工夫してみたいと思います。)
というわけでこのエントリーは以上です。