Node.jsでリアルタイムWebアプリケーションを開発!Socket.IOでメッセージング機能を実装

2024-05-14

Node.jsとSocket.IOで特定のクライアントにメッセージを送信する方法

このチュートリアルでは、Node.jsSocket.IOを使用して、特定のクライアントにメッセージを送信する方法を説明します。

Socket.IOは、リアルタイムの双方向通信を可能にするJavaScriptライブラリです。 Webサーバーとクライアント間で双方向にデータを送受信できるため、チャットアプリケーションやリアルタイムなゲームなどに最適です。

必要なもの

  • Node.js (インストール済み)

手順

  1. プロジェクトを作成する
npm init -y
  1. 必要なパッケージをインストールする
npm install socket.io
  1. サーバーファイルを作成する
const io = require('socket.io')(3000);

io.on('connection', (socket) => {
  console.log('Client connected:', socket.id);

  socket.on('message', (message) => {
    console.log('Received message:', message);

    // 特定のクライアント (ID: 'specific-client-id') にメッセージを送信
    socket.to('specific-client-id').emit('message', message);
  });
});
  1. クライアントファイルを作成する
const io = require('socket.io')( 'http://localhost:3000');

io.on('connect', () => {
  console.log('Connected to server');

  // メッセージを送信
  io.emit('message', 'Hello from client!');

  // 'specific-client-id' にのみメッセージをリッスン
  io.on('message', (message) => {
    console.log('Received message from server:', message);
  });
});
  1. サーバーとクライアントを実行する
  • サーバーファイルを node server.js コマンドで実行
  • ブラウザでクライアントファイルを開く

説明

  • サーバーファイル:
    • io.on('connection', ...): クライアントが接続したときに呼び出されるイベントリスナー
      • socket: 接続されたクライアントを表すオブジェクト
  • クライアントファイル:
    • io.on('connect', ...): サーバーに接続したときに呼び出されるイベントリスナー
    • io.emit('message', 'Hello from client!');: サーバーに message イベントを送信
    • io.on('message', ...): サーバーから message イベントを受信したときに呼び出されるイベントリスナー

補足

  • 上記のコードはあくまで基本的な例です。 実際のアプリケーションでは、エラー処理や認証などの機能を追加する必要があります。
  • 特定のクライアントにメッセージを送信するには、そのクライアントに固有のIDを割り当てる必要があります。 例えば、データベースを使用したり、ランダムなIDを生成したりして、クライアントIDを管理できます。



Node.jsとSocket.IOで特定のクライアントにメッセージを送信するサンプルコード

const io = require('socket.io')(3000);

let clients = {}; // クライアントIDとsocketオブジェクトのマップ

io.on('connection', (socket) => {
  console.log('Client connected:', socket.id);

  // クライアントIDとsocketオブジェクトをマップに追加
  clients[socket.id] = socket;

  socket.on('disconnect', () => {
    console.log('Client disconnected:', socket.id);

    // マップから削除
    delete clients[socket.id];
  });

  socket.on('message', (message) => {
    console.log('Received message:', message);

    // 送信者以外のクライアント全員にメッセージを送信
    socket.broadcast.emit('message', message);

    // 特定のクライアント (ID: 'specific-client-id') にメッセージを送信
    if (clients['specific-client-id']) {
      clients['specific-client-id'].emit('private-message', message);
    }
  });
});

クライアント側

const io = require('socket.io')( 'http://localhost:3000');

io.on('connect', () => {
  console.log('Connected to server');

  // メッセージを送信
  io.emit('message', 'Hello from client!');

  // 全員からのメッセージをリッスン
  io.on('message', (message) => {
    console.log('Received message from server:', message);
  });

  // 特定のクライアントからのプライベートメッセージをリッスン
  io.on('private-message', (message) => {
    console.log('Received private message:', message);
  });
});

サーバー側

  • clients オブジェクト: クライアントIDとsocketオブジェクトを紐付けるマップ
  • socket.on('disconnect', ...): クライアントが切断されたときに呼び出されるイベントリスナー
    • マップからクライアントIDとsocketオブジェクトを削除
  • socket.on('message', ...): クライアントから message イベントを受信したときに呼び出されるイベントリスナー
    • socket.broadcast.emit('message', message);: 送信者以外のクライアント全員に message イベントを発行
    • clients['specific-client-id']: 'specific-client-id' を持つクライアントのsocketオブジェクトを取得
  • io.on('connect', ...): サーバーに接続したときに呼び出されるイベントリスナー

変更点

  • サーバー側:
    • クライアントIDとsocketオブジェクトをマップに追加する処理を追加
    • 送信者以外のクライアント全員にメッセージを送信する処理を追加

このサンプルコードによって、特定のクライアントにメッセージを送信する方法がより明確になったと思います。




Node.jsとSocket.IOで特定のクライアントにメッセージを送信するその他の方法

ネームスペースを使用すると、異なるチャンネルでメッセージをブロードキャストできます。 特定のクライアントにのみメッセージを送信するには、そのクライアントが参加しているネームスペースでメッセージを発行できます。

const io = require('socket.io')(3000);

io.on('connection', (socket) => {
  console.log('Client connected:', socket.id);

  socket.on('join-room', (room) => {
    socket.join(room);
    console.log('Client joined room:', room);
  });

  socket.on('message', (message) => {
    console.log('Received message:', message);

    // 特定の部屋にいるクライアント全員にメッセージを送信
    io.to('specific-room').emit('message', message);
  });
});
const io = require('socket.io')( 'http://localhost:3000');

io.on('connect', () => {
  console.log('Connected to server');

  // 特定の部屋に参加
  io.emit('join-room', 'specific-room');

  // メッセージを送信
  io.emit('message', 'Hello from client!');

  // メッセージをリッスン
  io.on('message', (message) => {
    console.log('Received message from server:', message);
  });
});
  • クライアント側:
    • io.emit('join-room', 'specific-room');: サーバーに 'join-room' イベントを送信し、'specific-room' に参加

利点

  • ネームスペースを使用すると、メッセージをより整理して管理できます。
  • 異なるチャンネル間でメッセージを簡単にルーティングできます。

欠点

  • クライアントがどのネームスペースに参加しているのかを把握する必要があります。
const io = require('socket.io')(3000);

io.on('connection', (socket) => {
  console.log('Client connected:', socket.id);

  socket.on('message', (message) => {
    console.log('Received message:', message);

    // 特定のクライアントにのみメッセージを送信
    socket.to('specific-client-id').emit('custom-message', message);
  });
});
const io = require('socket.io')( 'http://localhost:3000');

io.on('connect', () => {
  console.log('Connected to server');

  // メッセージを送信
  io.emit('message', 'Hello from client!');

  // カスタムメッセージをリッスン
  io.on('custom-message', (message) => {
    console.log('Received custom message:', message);
  });
});

javascript node.js websocket


ウィンドウサイズに追従するWebサイト!JavaScriptとjQueryで実現するクロスブラウザ対応リサイズイベント処理

そこで、今回はJavaScriptとjQueryを用いた、クロスブラウザウィンドウリサイズイベント処理について、分かりやすく解説します。JavaScriptでウィンドウリサイズイベントを処理するには、windowオブジェクトのresizeイベントにイベントハンドラを設定します。以下のコードは、ウィンドウリサイズ時にコンソールのログに現在のウィンドウ幅を出力する例です。...


【完全版】JavaScript と jQuery で input 要素の readonly 属性を設定する方法

以下のコードは、JavaScript を使って input 要素に readonly 属性を追加する方法です。jQuery を使っても、input 要素に readonly 属性を追加することができます。jQuery を既にプロジェクトで使用している場合は、jQuery の方法を使う方が簡潔に記述できます。...


Reactイベントオブジェクトのカスタム属性:詳細解説とサンプルコード

これは、HTML要素にdata-属性を使用してカスタム属性を設定し、イベントオブジェクトのtargetプロパティからアクセスする方法です。例:これは、イベントが発生した要素ではなく、イベントリスナーが登録された要素からカスタム属性にアクセスする方法です。...


画像アップロード時に発生する「Unexpected Field」エラーを撃退!Multerでスマートな解決策

このエラーは、リクエストされたデータの中に、Multer で定義されていないフィールドが含まれている場合に発生します。具体的には、以下の状況で発生する可能性があります。フォームデータに定義されていないフィールドが存在するMulter で処理するフィールドを誤って設定している...