Skip to content

Instantly share code, notes, and snippets.

@sommeeeer
Created May 31, 2025 12:37
Show Gist options
  • Select an option

  • Save sommeeeer/1333107fea803bf111d308c9f03f4662 to your computer and use it in GitHub Desktop.

Select an option

Save sommeeeer/1333107fea803bf111d308c9f03f4662 to your computer and use it in GitHub Desktop.
sse
// app/sse/page.tsx
'use client';
import { useState, useEffect, useRef } from 'react';
export default function SSEDemo() {
const [isConnected, setIsConnected] = useState(false);
const [messages, setMessages] = useState<string[]>([]);
const eventSourceRef = useRef<EventSource | null>(null);
const connect = () => {
if (eventSourceRef.current) return;
const es = new EventSource('/api/sample');
eventSourceRef.current = es;
es.onopen = () => {
console.log('Connection opened');
setIsConnected(true);
};
es.onmessage = (event) => {
console.log('Message received:', event.data);
setMessages((prev) => [...prev, event.data]);
};
es.onerror = (error) => {
console.error('EventSource error:', error);
disconnect();
};
};
const disconnect = () => {
if (eventSourceRef.current) {
console.log('Closing connection');
eventSourceRef.current.close();
eventSourceRef.current = null;
setIsConnected(false);
}
};
// Clean up on component unmount
useEffect(() => {
return () => {
disconnect();
};
}, []);
return (
<div className="p-6 max-w-4xl mx-auto">
<h1 className="text-2xl font-bold mb-4">Server-Sent Events Demo</h1>
<div className="flex gap-4 mb-6">
<button
onClick={connect}
disabled={isConnected}
className={`px-4 py-2 rounded ${
isConnected ? 'bg-gray-300' : 'bg-blue-500 text-white'
}`}
>
Connect
</button>
<button
onClick={disconnect}
disabled={!isConnected}
className={`px-4 py-2 rounded ${
!isConnected ? 'bg-gray-300' : 'bg-red-500 text-white'
}`}
>
Disconnect
</button>
<button
onClick={() => {
disconnect();
setTimeout(connect, 100); // Small delay to ensure clean disconnect
}}
className="px-4 py-2 bg-green-500 text-white rounded"
>
Reconnect
</button>
</div>
<div className="mb-4">
<strong>Status:</strong> {isConnected ? 'Connected' : 'Disconnected'}
</div>
<div className="border rounded p-4 bg-gray-50 h-80 overflow-y-auto">
<h2 className="text-lg font-semibold mb-2">Received Messages:</h2>
{messages.length === 0 ? (
<p className="text-gray-500">No messages received yet</p>
) : (
<div className="space-y-2">
{messages.map((msg, index) => (
<div key={index} className="border-b pb-2">
{msg}
</div>
))}
</div>
)}
</div>
<button
onClick={() => setMessages([])}
className="mt-4 px-4 py-2 bg-gray-500 text-white rounded"
>
Clear Messages
</button>
</div>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment