Comunicacion en tiempo real con WebSocket y Claude Code
Aprenda sobre comunicacion en tiempo real con WebSocket usando Claude Code. Incluye ejemplos practicos de codigo.
リアルタイム通信開発でClaude Codeを活用する
チャット、通知、共同Editなど、リアルタイム通信が必要なアプリケーションは増えています。Claude Codeはサーバーサイドとクライアントサイドの両方を理解した上で、一貫した実装を支援します。
Socket.IOによるチャット機能の実装
> Socket.IOを使ったリアルタイムチャットのサーバーを作成して。
> ルーム機能、タイピングインジケーター、既読機能を実装して。
サーバーサイド
import express from 'express';
import { createServer } from 'http';
import { Server, Socket } from 'socket.io';
const app = express();
const server = createServer(app);
const io = new Server(server, {
cors: { origin: 'http://localhost:5173' },
});
interface ChatMessage {
id: string;
roomId: string;
userId: string;
content: string;
timestamp: Date;
}
const rooms = new Map<string, Set<string>>();
io.on('connection', (socket: Socket) => {
const userId = socket.handshake.auth.userId;
console.log(`User connected: ${userId}`);
socket.on('join-room', (roomId: string) => {
socket.join(roomId);
if (!rooms.has(roomId)) rooms.set(roomId, new Set());
rooms.get(roomId)!.add(userId);
socket.to(roomId).emit('user-joined', {
userId,
members: Array.from(rooms.get(roomId)!),
});
});
socket.on('send-message', async (data: { roomId: string; content: string }) => {
const message: ChatMessage = {
id: crypto.randomUUID(),
roomId: data.roomId,
userId,
content: data.content,
timestamp: new Date(),
};
// Save to DB
await saveMessage(message);
io.to(data.roomId).emit('new-message', message);
});
socket.on('typing-start', (roomId: string) => {
socket.to(roomId).emit('user-typing', { userId, isTyping: true });
});
socket.on('typing-stop', (roomId: string) => {
socket.to(roomId).emit('user-typing', { userId, isTyping: false });
});
socket.on('mark-read', (data: { roomId: string; messageId: string }) => {
socket.to(data.roomId).emit('message-read', {
userId,
messageId: data.messageId,
});
});
socket.on('disconnect', () => {
rooms.forEach((members, roomId) => {
if (members.delete(userId)) {
io.to(roomId).emit('user-left', { userId });
}
});
});
});
server.listen(3000, () => console.log('Server running on port 3000'));
クライアントサイド(React)
import { useEffect, useState, useCallback } from 'react';
import { io, Socket } from 'socket.io-client';
let socket: Socket;
export function useChat(roomId: string, userId: string) {
const [messages, setMessages] = useState<ChatMessage[]>([]);
const [typingUsers, setTypingUsers] = useState<Set<string>>(new Set());
useEffect(() => {
socket = io('http://localhost:3000', { auth: { userId } });
socket.emit('join-room', roomId);
socket.on('new-message', (message: ChatMessage) => {
setMessages(prev => [...prev, message]);
});
socket.on('user-typing', ({ userId: uid, isTyping }) => {
setTypingUsers(prev => {
const next = new Set(prev);
isTyping ? next.add(uid) : next.delete(uid);
return next;
});
});
return () => { socket.disconnect(); };
}, [roomId, userId]);
const sendMessage = useCallback((content: string) => {
socket.emit('send-message', { roomId, content });
}, [roomId]);
const startTyping = useCallback(() => {
socket.emit('typing-start', roomId);
}, [roomId]);
const stopTyping = useCallback(() => {
socket.emit('typing-stop', roomId);
}, [roomId]);
return { messages, typingUsers, sendMessage, startTyping, stopTyping };
}
Server-Sent Events(SSE)による通知
WebSocketほどの双方向性が不要な場合、SSEが軽量な選択肢です。
// server
app.get('/api/notifications/stream', (req, res) => {
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
Connection: 'keep-alive',
});
const userId = req.query.userId as string;
const sendEvent = (data: object) => {
res.write(`data: ${JSON.stringify(data)}\n\n`);
};
// 新しい通知があれば送信
const unsubscribe = notificationBus.subscribe(userId, sendEvent);
req.on('close', () => {
unsubscribe();
res.end();
});
});
// client
function useNotifications(userId: string) {
const [notifications, setNotifications] = useState<Notification[]>([]);
useEffect(() => {
const eventSource = new EventSource(
`/api/notifications/stream?userId=${userId}`
);
eventSource.onmessage = (event) => {
const data = JSON.parse(event.data);
setNotifications(prev => [data, ...prev]);
};
return () => eventSource.close();
}, [userId]);
return notifications;
}
接続の安定性を高める
本番環境では、再接続ロジックやハートビートの実装が重要です。
const socket = io('http://localhost:3000', {
auth: { userId },
reconnection: true,
reconnectionAttempts: 10,
reconnectionDelay: 1000,
reconnectionDelayMax: 5000,
timeout: 20000,
});
socket.on('connect_error', (err) => {
console.error('Connection error:', err.message);
});
socket.on('reconnect', (attempt) => {
console.log(`Reconnected after ${attempt} attempts`);
// Reconnect後にルームに再参加
socket.emit('join-room', currentRoomId);
});
Summary
Claude Codeを活用すれば、WebSocketやSSEを使ったリアルタイム通信機能をサーバー・クライアント両方一貫して実装できます。プロンプトの書き方次第でコードの質が大きく変わるため、プロンプトテクニックを身につけておくことが重要です。個人開発でチャット機能を実装する際は個人開発を爆速にする方法も参考にしてください。
詳しくはAnthropic公式ドキュメントやSocket.IO公式ドキュメントをご覧ください。
Related Posts
Cómo potenciar tus proyectos personales con Claude Code [Con ejemplos]
Aprende a acelerar drásticamente tus proyectos personales de desarrollo usando Claude Code. Incluye ejemplos reales y un flujo de trabajo práctico desde la idea hasta el despliegue.
Cómo automatizar la refactorización con Claude Code
Aprende a automatizar eficientemente la refactorización de código usando Claude Code. Incluye prompts prácticos y patrones concretos de refactorización para proyectos reales.
Guia completa de configuracion CORS con Claude Code
Aprende sobre la configuracion completa de CORS usando Claude Code. Incluye consejos practicos y ejemplos de codigo.