Use Cases

WebSocket:Claude Code 实战指南

了解websocket:Claude Code 实战. 包含实用技巧和代码示例。

WebSocketチャット应用を通过 Claude Code作る

实时チャット应用はWebSocketの代表的なユースケースです。借助 Claude Code,认证付きのチャットルーム、メッセージ履歴、オンラインステータスまで含めた本格的なチャット应用を高效地构建可以。

项目の初期セットアップ

> WebSocketチャット应用を作りたい。
> Node.js + Express + Socket.IO で服务器を、
> React + TypeScript で前端を构建して。
> ルーム機能とメッセージ履歴实现。

Claude Code 这个プロンプトから、服务器と客户端の両方を一貫した架构で生成してくれます。

服务器サイドの实现

// server/src/chat-server.ts
import { Server, Socket } from 'socket.io';
import { createServer } from 'http';
import express from 'express';

interface Message {
  id: string;
  roomId: string;
  sender: string;
  content: string;
  timestamp: number;
}

const app = express();
const httpServer = createServer(app);
const io = new Server(httpServer, {
  cors: { origin: process.env.CLIENT_URL || 'http://localhost:3000' },
});

// メッセージ履歴を内存に保持(本番ではDBを使用)
const messageHistory = new Map<string, Message[]>();

io.use((socket, next) => {
  const token = socket.handshake.auth.token;
  if (!token) return next(new Error('認証が必要です'));
  // Token验证ロジック
  next();
});

io.on('connection', (socket: Socket) => {
  const username = socket.handshake.auth.username;

  socket.on('join-room', (roomId: string) => {
    socket.join(roomId);
    // 過去のメッセージを发送
    const history = messageHistory.get(roomId) || [];
    socket.emit('message-history', history.slice(-50));
    io.to(roomId).emit('user-status', { username, status: 'online' });
  });

  socket.on('send-message', (data: { roomId: string; content: string }) => {
    const message: Message = {
      id: crypto.randomUUID(),
      roomId: data.roomId,
      sender: username,
      content: data.content,
      timestamp: Date.now(),
    };
    if (!messageHistory.has(data.roomId)) {
      messageHistory.set(data.roomId, []);
    }
    messageHistory.get(data.roomId)!.push(message);
    io.to(data.roomId).emit('new-message', message);
  });

  socket.on('disconnect', () => {
    io.emit('user-status', { username, status: 'offline' });
  });
});

httpServer.listen(4000, () => console.log('Chat server running on :4000'));

客户端サイドの实现

// client/src/hooks/useChat.ts
import { useEffect, useState, useCallback } from 'react';
import { io, Socket } from 'socket.io-client';

interface Message {
  id: string;
  roomId: string;
  sender: string;
  content: string;
  timestamp: number;
}

export function useChat(roomId: string, token: string, username: string) {
  const [messages, setMessages] = useState<Message[]>([]);
  const [socket, setSocket] = useState<Socket | null>(null);
  const [isConnected, setIsConnected] = useState(false);

  useEffect(() => {
    const s = io('http://localhost:4000', {
      auth: { token, username },
    });

    s.on('connect', () => {
      setIsConnected(true);
      s.emit('join-room', roomId);
    });

    s.on('message-history', (history: Message[]) => {
      setMessages(history);
    });

    s.on('new-message', (message: Message) => {
      setMessages((prev) => [...prev, message]);
    });

    s.on('disconnect', () => setIsConnected(false));

    setSocket(s);
    return () => { s.disconnect(); };
  }, [roomId, token, username]);

  const sendMessage = useCallback((content: string) => {
    socket?.emit('send-message', { roomId, content });
  }, [socket, roomId]);

  return { messages, sendMessage, isConnected };
}

メッセージ组件

// client/src/components/ChatRoom.tsx
import { useChat } from '../hooks/useChat';
import { useState } from 'react';

export function ChatRoom({ roomId, token, username }: {
  roomId: string;
  token: string;
  username: string;
}) {
  const { messages, sendMessage, isConnected } = useChat(roomId, token, username);
  const [input, setInput] = useState('');

  const handleSend = () => {
    if (!input.trim()) return;
    sendMessage(input);
    setInput('');
  };

  return (
    <div className="flex flex-col h-screen">
      <div className="p-4 border-b flex justify-between">
        <h2>Room: {roomId}</h2>
        <span className={isConnected ? 'text-green-500' : 'text-red-500'}>
          {isConnected ? '接続中' : '切断'}
        </span>
      </div>
      <div className="flex-1 overflow-y-auto p-4 space-y-2">
        {messages.map((msg) => (
          <div key={msg.id} className={msg.sender === username ? 'text-right' : ''}>
            <span className="text-sm text-gray-500">{msg.sender}</span>
            <p className="bg-gray-100 rounded-lg p-2 inline-block">{msg.content}</p>
          </div>
        ))}
      </div>
      <div className="p-4 border-t flex gap-2">
        <input
          value={input}
          onChange={(e) => setInput(e.target.value)}
          onKeyDown={(e) => e.key === 'Enter' && handleSend()}
          className="flex-1 border rounded px-3 py-2"
          placeholder="Type a message..."
        />
        <button onClick={handleSend} className="bg-blue-500 text-white px-4 rounded">
          送信
        </button>
      </div>
    </div>
  );
}

生产环境での注意点

让 Claude Code以下点を添加で依頼すると、本番品質に近づけられます。

  • メッセージの永続化: RedisやPostgreSQLにメッセージを保存する
  • レート制限: スパム防止のためのメッセージ发送制限
  • XSS対策: 用户输入のサニタイズ処理
  • 再接続ロジック: 切断時の自動再接続とメッセージ再获取

関連リソース

WebSocketの基礎的な实现パターン相关内容请参阅WebSocket/实时通信の实现指南也可以参考。认证周りの实现は认证機能の实现で詳しく解説しています。此外、チャットボットとの集成を考えている場合はチャットボット开发也请查看。

Socket.IO的官方文档(socket.io/docs)も併せて确认するとよいでしょう。

#Claude Code #WebSocket #チャット #real-time #Node.js