mcpField
S
socket-io

socket-io

github.com/claude-dev-suite開発46102 回インストール2 日前に更新
リポジトリ

socket-io について

Socket.IOは、サーバーとクライアント間のリアルタイム通信を構築するライブラリです。型付きイベント、認証、再接続、Reactでのルーム処理の例があり、Redis Adapterによる複数サーバー構成も紹介しています。

主な機能

  1. 01サーバーとクライアントの接続例
  2. 02型付きイベント定義
  3. 03認証と再接続のオプション
  4. 04ルーム単位のメッセージ処理
  5. 05複数サーバー向けRedis Adapter
  6. 06React hookの例

活用シーン

  1. 01ルーム機能付きリアルタイムチャットの構築
  2. 02認証済みクライアント接続の処理
  3. 03Socket.IOを複数サーバーに拡張

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/claude-dev-suite/claude-dev-suite --skill socket-io

インストール後、Claude Code で/socket-ioを入力して読み込まれたか確認します。

詳細

Socket.IO

サーバーのセットアップ

import { Server } from 'socket.io';
import { createServer } from 'http';

const httpServer = createServer(app);

interface ServerToClientEvents {
  message: (data: { user: string; text: string; timestamp: number }) => void;
  userJoined: (user: string) => void;
}

interface ClientToServerEvents {
  sendMessage: (text: string, callback: (status: 'ok' | 'error') => void) => void;
  joinRoom: (room: string) => void;
}

const io = new Server<ClientToServerEvents, ServerToClientEvents>(httpServer, {
  cors: { origin: process.env.CLIENT_URL },
});

// Authentication middleware
io.use((socket, next) => {
  const token = socket.handshake.auth.token;
  try {
    socket.data.user = verifyToken(token);
    next();
  } catch {
    next(new Error('Authentication failed'));
  }
});

io.on('connection', (socket) => {
  console.log(`${socket.data.user.name} connected`);

  socket.on('joinRoom', (room) => {
    socket.join(room);
    socket.to(room).emit('userJoined', socket.data.user.name);
  });

  socket.on('sendMessage', (text, callback) => {
    const message = { user: socket.data.user.name, text, timestamp: Date.now() };
    io.to('general').emit('message', message);
    callback('ok');
  });

  socket.on('disconnect', () => {
    console.log(`${socket.data.user.name} disconnected`);
  });
});

クライアントのセットアップ

import { io, Socket } from 'socket.io-client';

const socket: Socket<ServerToClientEvents, ClientToServerEvents> = io(API_URL, {
  auth: { token: getAuthToken() },
  reconnection: true,
  reconnectionDelay: 1000,
});

socket.on('connect', () => console.log('Connected'));
socket.on('message', (data) => addMessage(data));
socket.on('connect_error', (err) => console.error(err.message));

// With acknowledgment
socket.emit('sendMessage', 'Hello!', (status) => {
  if (status === 'error') showError('Failed to send');
});

Redis アダプターによるスケーリング

import { createAdapter } from '@socket.io/redis-adapter';
import { createClient } from 'redis';

const pubClient = createClient({ url: process.env.REDIS_URL });
const subClient = pubClient.duplicate();
await Promise.all([pubClient.connect(), subClient.connect()]);

io.adapter(createAdapter(pubClient, subClient));

React フック

function useSocket(room: string) {
  const [messages, setMessages] = useState<Message[]>([]);

  useEffect(() => {
    socket.emit('joinRoom', room);
    socket.on('message', (msg) => setMessages((prev) => [...prev, msg]));
    return () => { socket.off('message'); };
  }, [room]);

  const send = (text: string) => socket.emit('sendMessage', text, () => {});
  return { messages, send };
}

アンチパターン

アンチパターン修正方法
認証がないJWT を使った io.use() ミドルウェアを使用します
ルームを使わず全員にブロードキャストするsocket.to(room).emit() を使用します
再接続への対応がない再接続を有効にし、UI インジケーターを表示します
アダプターなしの単一サーバー水平スケーリングには Redis アダプターを使用します
重要なイベントに確認応答がないコールバックパラメーターを使って配信を確認します

本番環境チェックリスト

  • 接続時の認証ミドルウェア
  • 複数サーバーへのデプロイ用 Redis アダプター
  • 指数バックオフによる再接続
  • ルームベースのメッセージ範囲設定
  • 接続状態を示す UI インジケーター
  • メッセージイベントのレート制限

コメント