WebSocket入門 - リアルタイム通信

intermediate | 55分 で読める | 2024.12.31

このチュートリアルで学ぶこと

✓ WebSocketの基本概念
✓ サーバー実装
✓ クライアント実装
✓ ブロードキャスト
✓ ルーム機能

Step 1: サーバー実装

npm install ws express
// server.js
const WebSocket = require('ws');
const http = require('http');
const express = require('express');

const app = express();
const server = http.createServer(app);
const wss = new WebSocket.Server({ server });

const clients = new Set();

wss.on('connection', (ws) => {
  clients.add(ws);
  console.log('Client connected');

  ws.on('message', (data) => {
    const message = JSON.parse(data);
    // 全クライアントにブロードキャスト
    clients.forEach(client => {
      if (client.readyState === WebSocket.OPEN) {
        client.send(JSON.stringify(message));
      }
    });
  });

  ws.on('close', () => {
    clients.delete(ws);
    console.log('Client disconnected');
  });
});

server.listen(3000, () => {
  console.log('Server running on http://localhost:3000');
});

Step 2: クライアント実装

<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
  <title>Chat</title>
</head>
<body>
  <div id="messages"></div>
  <input id="input" type="text" />
  <button onclick="sendMessage()">Send</button>

  <script>
    const ws = new WebSocket('ws://localhost:3000');

    ws.onopen = () => console.log('Connected');

    ws.onmessage = (event) => {
      const message = JSON.parse(event.data);
      const div = document.createElement('div');
      div.textContent = `${message.user}: ${message.text}`;
      document.getElementById('messages').appendChild(div);
    };

    function sendMessage() {
      const input = document.getElementById('input');
      ws.send(JSON.stringify({
        user: 'User',
        text: input.value
      }));
      input.value = '';
    }
  </script>
</body>
</html>

Step 3: Socket.io版

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

const server = http.createServer();
const io = new Server(server, {
  cors: { origin: '*' }
});

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

  socket.on('join', (room) => {
    socket.join(room);
  });

  socket.on('message', (data) => {
    io.to(data.room).emit('message', data);
  });

  socket.on('disconnect', () => {
    console.log('User disconnected');
  });
});

server.listen(3000);

Step 4: Reactクライアント

// useSocket.ts
import { useEffect, useState } from 'react';
import { io, Socket } from 'socket.io-client';

export function useSocket(url: string) {
  const [socket, setSocket] = useState<Socket | null>(null);
  const [messages, setMessages] = useState<string[]>([]);

  useEffect(() => {
    const newSocket = io(url);
    setSocket(newSocket);

    newSocket.on('message', (msg) => {
      setMessages(prev => [...prev, msg]);
    });

    return () => { newSocket.close(); };
  }, [url]);

  const sendMessage = (msg: string) => {
    socket?.emit('message', msg);
  };

  return { messages, sendMessage };
}

まとめ

WebSocketで双方向リアルタイム通信を実現できます。Socket.ioを使えばフォールバックや再接続も自動処理されます。

← 一覧に戻る