Use Cases

WebSocket dengan Claude Code

Pelajari tentang websocket menggunakan Claude Code. Dilengkapi tips praktis dan contoh kode.

WebSocketチャットaplikasi dengan Claude Code: 作る

リアルタイムチャットaplikasi WebSocket 代表的なユースケース.Claude Code 使えば、認証付き チャットルーム、pesan履歴、オンラインステータスま 含めた本格的なチャットaplikasi efisien pembangunan bisa dilakukan.

初期セットアップ proyek

> WebSocketチャットaplikasi 作りたい。
> Node.js + Express + Socket.IO dengan server 、
> React + TypeScript dengan frontend bangun.
> ルーム機能 dan pesan履歴 implementasikan.

Claude Code こ プロンプト dari 、server dan client 両方 一貫 arsitektur generate くれ.

implementasi serverサイド

// 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' },
});

// pesan履歴 メモリ 保持(本番 DB penggunaan)
const messageHistory = new Map<string, Message[]>();

io.use((socket, next) => {
  const token = socket.handshake.auth.token;
  if (!token) return next(new Error('認証 diperlukan す'));
  // tokenverifikasiロジック
  next();
});

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

  socket.on('join-room', (roomId: string) => {
    socket.join(roomId);
    // 過去 pesan pengiriman
    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'));

implementasi clientサイド

// 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 };
}

pesankomponen

// 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 ? 'koneksi中' : '切断'}
        </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>
  );
}

hal yang perlu diperhatikan environment produksi

Claude Code berikut 点 penambahan 依頼 dan 、本番品質 近づけられ.

  • pesan persistensi: RedisやPostgreSQL pesan penyimpanan
  • レート制限: スパム防止 untuk pesanpengiriman制限
  • XSS対策: penggunainput サニタイズpemrosesan
  • 再koneksiロジック: 切断時 自動再koneksi dan pesan再pengambilan

Resource Terkait

Mengenai WebSocketの基礎的なimplementasipola, 詳しくpenjelasanしています。また、チャットボットとのintegrasiを考えている場合はチャットボットpengembanganもご覧ください。 di WebSocket/リアルタイム通信の実装ガイドも参考にしてください。認証周りの実装は認証機能の実装.

Socket.IO 公式dokumen(socket.io/docs) juga 併せてkonfirmasi dan よい.

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