【Node.js】WebSocketを使ったリアルタイム通信|socket.ioで双方向のイベント設計

https://a.r10.to/hkZoRT Node.js

Webアプリケーションにおいて、リアルタイム通信のニーズは年々高まっています。チャット、通知、オンライン同期など、ユーザー同士の即時反応が求められる場面では、従来のHTTPリクエストでは対応が難しいケースも多くなります。

この記事では、Node.jsでWebSocket通信を実現するライブラリとして代表的なsocket.ioを用いた、リアルタイムかつ双方向な通信の実装方法について解説します。

WebSocketとは?

WebSocketは、HTTPのようなリクエスト/レスポンスモデルではなく、クライアントとサーバーが双方向かつ常時接続で通信できるプロトコルです。主な特徴は以下の通りです:

  • 接続は一度確立されれば持続され、サーバーからクライアントへのプッシュ通信が可能
  • 双方向通信により、リアルタイムなやり取りが実現
  • ヘッダーが最小限なため、通信コストが小さい

socket.ioの特徴

socket.ioはWebSocketの仕組みをラップし、フォールバック対応(WebSocket非対応環境ではXHRなどに切り替え)や部屋・名前空間の管理などを提供するライブラリです。

導入が簡単で、クライアントとサーバーの両方のAPIが統一されているのも魅力です。

基本構成のセットアップ

まずは必要なモジュールをインストールします。

npm install express socket.io

次に、サーバー側のコードを作成します。

サーバー側:リアルタイムイベントの定義

// server.js
const express = require('express');
const http = require('http');
const { Server } = require('socket.io');

const app = express();
const server = http.createServer(app);
const io = new Server(server);

app.get('/', (req, res) => {
  res.sendFile(__dirname + '/index.html');
});

io.on('connection', (socket) => {
  console.log('クライアントが接続しました');

  socket.on('chat message', (msg) => {
    console.log('受信メッセージ:', msg);
    io.emit('chat message', msg); // 全クライアントにブロードキャスト
  });

  socket.on('disconnect', () => {
    console.log('クライアントが切断しました');
  });
});

server.listen(3000, () => {
  console.log('http://localhost:3000 でサーバー起動中');
});

クライアント側:リアルタイムでの送受信

index.htmlを以下のように作成します。

<!doctype html>
<html>
  <head>
    <title>Chat Example</title>
  </head>
  <body>
    <ul id="messages"></ul>
    <form id="form">
      <input id="input" autocomplete="off" /><button>送信</button>
    </form>

    <script src="/socket.io/socket.io.js"></script>
    <script>
      const socket = io();

      const form = document.getElementById('form');
      const input = document.getElementById('input');

      form.addEventListener('submit', function (e) {
        e.preventDefault();
        if (input.value) {
          socket.emit('chat message', input.value);
          input.value = '';
        }
      });

      socket.on('chat message', function (msg) {
        const item = document.createElement('li');
        item.textContent = msg;
        document.getElementById('messages').appendChild(item);
      });
    </script>
  </body>
</html>

名前空間とルームの活用

名前空間(namespace)ルーム(room)を使えば、通信のスコープを細かく制御できます。

// 特定のルームに参加
socket.join('room1');

// ルーム内のみにメッセージを送信
io.to('room1').emit('chat message', 'room1向けのメッセージ');

セキュリティと実運用時の注意点

  • 認証トークンをWebSocket接続時に送信し、サーバー側で検証
  • イベント名の一意性と予期せぬ通信へのフィルタリング
  • メッセージサイズの制限
  • Redis Pub/Subと連携してスケーラブルに構築可能

まとめ|リアルタイムWebはsocket.ioで一気に加速

socket.ioはNode.jsにおいてリアルタイム通信を簡単に構築できる強力なライブラリです。シンプルなチャットから、複雑なオンライン同期処理まで、幅広く対応できます。

ルーム管理や接続状態監視、セキュリティ設計まで整えれば、スケーラブルなリアルタイムアプリの基盤として活躍します。

次のステップとして、Redisとの連携やロードバランサ環境でのスケーリングにも挑戦してみてください。