【Node.js】Socket.IO サンプルコード(2)~簡易チャットアプリ~(roomを使う)

  • このエントリーをはてなブックマークに追加

Socket.IO サンプルコード(2)~簡易チャットアプリ~
このコードはroomを使う例である。
Socket.IOを使用する場合には、HTTPサーバーを立ててSocket.IOを統合する必要がある。



index.html


<!DOCTYPE html>
<html lang="ja">

<head>
  <title>Socket.IO サンプルコード(2)~簡易チャットアプリ~</title>
</head>

<body>
  <h1>Socket.IO サンプルコード(2)~簡易チャットアプリ~</h1>

  http://192.168.2.100:3000/?code=100a
  <br>
  code=100aのようにクエリを付けてアクセスすること
  クエリは重複しないものとする。

  <div>
    <input type="text" id="handlename" placeholder="名前">
  </div>

  <div>
    <input type="text" id="roomInput" placeholder="ルーム名">
    <button onclick="joinRoom()">ルームに参加</button>
  </div>

  <div>
    <input type="text" id="messageInput" placeholder="メッセージ">
    <button onclick="sendMessage()">送信</button>
  </div>

  <ul id="messageList"></ul>

  <script src="/socket.io/socket.io.js"></script>
  <script>
  <!DOCTYPE html>
<html lang="ja">

<head>
  <title>Socket.IO サンプルコード(2)~超簡易チャットアプリ~</title>
</head>

<body>
  <h1>Socket.IO サンプルコード(2)~超簡易チャットアプリ~</h1>

  http://192.168.2.100:3000/?code=100a
  <br>
  code=100aのようにクエリを付けてアクセスすること
  クエリは重複しないものとする。

  <div>
    <input type="text" id="handlename" placeholder="名前">
  </div>

  <div>
    <input type="text" id="roomInput" placeholder="ルーム名">
    <button onclick="joinRoom()">ルームに参加</button>
  </div>

  <div>
    <input type="text" id="messageInput" placeholder="メッセージ">
    <button onclick="sendMessage()">送信</button>
  </div>

  <ul id="messageList"></ul>

  <script src="/socket.io/socket.io.js"></script>
  <script>

    // keyがsocketID,値がcode
    let socketID_code_c = new Map();
    // keyがcode,値がroom
    let code_room_c = new Map();
    // keyがcode,値がhandlename
    let code_handlename_c = new Map();

    const socket = io();

    // ルームに参加
    function joinRoom() {

      let handlename = document.getElementById('handlename').value;
      handlename = handlename === '' ? '名無しさん' : handlename;

      let room = document.getElementById('roomInput').value;

      const searchParams = new URLSearchParams(location.search);

      const code = searchParams.get("code");

      if (searchParams !== null && code !== null && room !== '') {

        // サーチ情報のそれぞれのキーに対応する値を、
        // URLSearchParamsオブジェクトのget()メソッドを使用して取得可能である。
        console.log("code = " + searchParams.get("code")); // URLUtils.searchParams

        socket.emit('joinRoom', {
          room,
          code,
          handlename
        });

      }

    }

    // メッセージを送信
    function sendMessage() {

      const room = document.getElementById('roomInput').value;

      const searchParams = new URLSearchParams(location.search);

      let code = searchParams.get("code");

      if (searchParams !== null && code !== null) {
        const room = document.getElementById('roomInput').value;
        const message = document.getElementById('messageInput').value;
        socket.emit('sendMessage', {
          room,
          message,
          code
        });
      }

    }

    // メッセージを受信
    socket.on('receiveMessage', (data) => {

      const messageList = document.getElementById('messageList');
      // 新しいli要素を作成する。li要素はメッセージをリストアイテムとして表示するために使用される。
      const li = document.createElement('li');

      const {
        message,
        code,
        socketID
      } = data
      console.log(message + " " + code);

      console.log("socketID_code_c.get(" + socketID + ") = " + socketID_code_c.get(socketID));
      console.log("code_room_c.get(" + code + ") = " + code_room_c.get(code));
      console.log("code_handlename_c.get(" + code + ") = " + code_handlename_c.get(code));

      li.innerHTML = code_handlename_c.get(code) + "@chat\n<br>" + message;
      messageList.appendChild(li);

    });

    // socketID等を受信
    socket.on('receive_socketID', (data) => {

      console.log(data);

      const {
        socketID,
        room,
        code,
        handlename,
        socketID_codeObject,
        code_roomObject,
        code_handlenameObject
      } = data;

      console.log("socketID = " + socketID);
      console.log("code = " + code);
      console.log("room = " + room);

      code_handlename_c = new Map(Object.entries(code_handlenameObject));
      code_room_c = new Map(Object.entries(code_roomObject));
      socketID_code_c = new Map(Object.entries(socketID_codeObject));

      console.log("code_handlename_c = " + code_handlename_c.get(code));
      console.log("code_room_c = " + code_room_c.get(code));
      console.log("socketID_code_c = " + socketID_code_c.get(socketID));

    });
  </script>
</body>
</html>

server_http.js


const hostname = '192.168.2.100';
const port = 3000;

const http = require('http');
const socketIO = require('socket.io');
const fs = require('fs');

const server = http.createServer((req, res) => {
  fs.readFile('./index.html', 'utf-8', (error, data) => {
    res.writeHead(200, {
      'Content-Type': 'text/html;charset=utf-8'
    });
    res.write(data);
    res.end();
  })
});

const io = require('socket.io')(server, {});

// サーバーの起動
server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

// keyがsocketID,valueがcode
let socketID_code = new Map();
// keyがcode,valueがroom
let code_room = new Map();
// keyがcode,valueがhandlename
let code_handlename = new Map();

// 接続時の処理
io.on('connection', (socket) => {
  console.log(`クライアントのID: ${socket.id} が接続しました。`);

  // ルームへの参加
  socket.on('joinRoom', (data) => {
    const {
      room,
      code,
      handlename
    } = data;
    socket.join(room);
    console.log(`クライアントのID: ${socket.id}, code = ${code}, クライアントがルーム ${room} に参加しました。`);
    const socketID = socket.id;

    socketID_code.set(socketID, code);
    code_room.set(code, room);
    code_handlename.set(code, handlename);

    const socketID_codeObject = Object.fromEntries(socketID_code.entries());
    const code_roomObject = Object.fromEntries(code_room.entries());
    const code_handlenameObject = Object.fromEntries(code_handlename.entries());

    io.to(room).emit('receive_socketID', {
      socketID,
      room,
      code,
      handlename,
      socketID_codeObject,
      code_roomObject,
      code_handlenameObject
    }); // 同じルームのクライアントにメッセージを送信

  });

  // メッセージの送信
  socket.on('sendMessage', (data) => {
    const {
      room,
      message,
      code
    } = data;
    const socketID = socket.id;
    console.log(`code = ${code}, クライアントからのメッセージ(ルーム ${room}): ${message}`);

    // 同じルームのクライアントにメッセージを送信 方法(1)
    //io.to(room).emit('receiveMessage', message); 

    // 同じルームのクライアントにメッセージを送信 方法(2) ここから
    // ルーム内のクライアントのIDリストを取得
    // clientsはmapオブジェクト風のオブジェクト
    const clients = io.sockets.adapter.rooms.get(room);

    console.log(`room = ${room}, clients.size = ${clients.size}`);

    if (clients) {
      clients.forEach(clientId => {
        console.log(`${room} クライアントのID: clientId = ${clientId}, code = ${socketID_code.get(clientId)}`)
        // 各クライアントに個別にメッセージを送信
        io.to(clientId).emit('receiveMessage', {
          message,
          code,
          socketID
        });
      });
    }

    // 同じルームのクライアントにメッセージを送信 方法(2) ここまで

  });

  // 切断時の処理
  socket.on('disconnect', () => {
    console.log(`クライアントが切断しました。${socket.id}`);
  });

});
  • このエントリーをはてなブックマークに追加

SNSでもご購読できます。

コメントを残す

*