'use client'; import { useEffect, useState } from 'react'; import { io } from 'socket.io-client'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { ScrollArea } from '@/components/ui/scroll-area'; type User = { id: string; username: string; } type Message = { id: string; username: string; content: string; timestamp: Date | string; type: 'user' | 'system'; } export default function SocketDemo() { const [messages, setMessages] = useState([]); const [inputMessage, setInputMessage] = useState(''); const [username, setUsername] = useState(''); const [isUsernameSet, setIsUsernameSet] = useState(false); const [socket, setSocket] = useState(null); const [isConnected, setIsConnected] = useState(false); const [users, setUsers] = useState([]); useEffect(() => { // Connect to websocket server // Never use PORT in the URL, alyways use XTransformPort // DO NOT change the path, it is used by Caddy to forward the request to the correct port const socketInstance = io('/?XTransformPort=3003', { transports: ['websocket', 'polling'], forceNew: true, reconnection: true, reconnectionAttempts: 5, reconnectionDelay: 1000, timeout: 10000 }) setSocket(socketInstance); socketInstance.on('connect', () => { setIsConnected(true); }); socketInstance.on('disconnect', () => { setIsConnected(false); }); socketInstance.on('message', (msg: Message) => { setMessages(prev => [...prev, msg]); }); socketInstance.on('user-joined', (data: { user: User; message: Message }) => { setMessages(prev => [...prev, data.message]); setUsers(prev => { if (!prev.find(u => u.id === data.user.id)) { return [...prev, data.user]; } return prev; }); }); socketInstance.on('user-left', (data: { user: User; message: Message }) => { setMessages(prev => [...prev, data.message]); setUsers(prev => prev.filter(u => u.id !== data.user.id)); }); socketInstance.on('users-list', (data: { users: User[] }) => { setUsers(data.users); }); return () => { socketInstance.disconnect(); }; }, []); const handleJoin = () => { if (socket && username.trim() && isConnected) { socket.emit('join', { username: username.trim() }); setIsUsernameSet(true); } }; const sendMessage = () => { if (socket && inputMessage.trim() && username.trim()) { socket.emit('message', { content: inputMessage.trim(), username: username.trim() }); setInputMessage(''); } }; const handleKeyPress = (e: React.KeyboardEvent) => { if (e.key === 'Enter') { sendMessage(); } }; return (
WebSocket Demo {isConnected ? 'Connected' : 'Disconnected'} {!isUsernameSet ? (
setUsername(e.target.value)} onKeyPress={(e) => { if (e.key === 'Enter') { handleJoin(); } }} placeholder="Enter your username..." disabled={!isConnected} className="flex-1" />
) : ( <>
{messages.length === 0 ? (

No messages yet

) : ( messages.map((msg) => (

{msg.username}

{msg.content}

{new Date(msg.timestamp).toLocaleTimeString()}
)) )}
setInputMessage(e.target.value)} onKeyPress={handleKeyPress} placeholder="Type a message..." disabled={!isConnected} className="flex-1" />
)}
); }