Skip to main content
sse-streaming POST-based Server-Sent Events streaming for Azure Functions — HTTP streaming, chunked response parsing, reconnection
Zur Installation springen Skills Marktplatz Entdecken und erkunden Sie KI-Skills, die von der Community erstellt wurden.
Mit Codex oder Claude installieren Kopieren Sie diesen Prompt, fügen Sie ihn in Codex, Claude oder einen anderen Assistant ein und lassen Sie die Skill-Seite prüfen und installieren.
Prompt kopierenPrompt-Details anzeigen Ein direkter Befehl überspringt den Prüf-Prompt. Prüfen Sie die Quelle, bevor Sie ihn ausführen.
npx skills add https://github.com/fabioc-aloha/Alex_Plug_In --skill sse-streamingDer Befehl bleibt in einer Zeile. Scrollen Sie horizontal, um ihn vor dem Kopieren vollständig zu prüfen.
Sie bevorzugen eine lokale Kopie? Laden Sie die Dateien herunter, die SkillsMP derzeit vorliegen.
ZIP herunterladen Herunterladen... Mehr aus diesem Repository SOC
Basierend auf der SOC-Berufsklassifikation
name sse-streaming description POST-based Server-Sent Events streaming for Azure Functions — HTTP streaming, chunked response parsing, reconnection tier extended applyTo **/*sse*,**/*streaming*,**/*server-sent*,**/*real-time* metadata {"version":"1.0.0","category":"web-development","tags":["sse","streaming","azure-functions","http-streaming","readablestream","real-time"],"activation":{"triggers":["SSE","streaming","server-sent events","HTTP streaming","ReadableStream","chunked response","real-time"],"context":"Working on real-time streaming from Azure Functions to client"},"prerequisites":[]}
SSE Streaming
POST-based Server-Sent Events pattern for Azure Functions. Solves the gap where native EventSource (GET-only) can't send request bodies, and Azure Static Web Apps don't proxy WebSocket to the API layer.
Why POST-Based SSE
Option SWA API Support? POST body? Limitation WebSocket No N/A SWA doesn't proxy WebSocket to Functions EventSource Yes GET only Can't send context in request body
POST + ReadableStream Yes Yes Recommended pattern
Azure Functions Setup
Enable HTTP Streaming
{
"version" : "2.0" ,
"extensions" : {
"http" : {
"enableHttpStream" : true
}
}
}
Streaming Function Pattern import { app, HttpRequest , HttpResponseInit , InvocationContext } from '@azure/functions' ;
app.http ('stream-response' , {
methods : ['POST' ],
authLevel : 'anonymous' ,
route : 'stream' ,
handler : async (req : HttpRequest , context : InvocationContext ): Promise <HttpResponseInit > => {
const payload = await req.json ();
const stream = new ReadableStream ({
async start (controller ) {
try {
const aiStream = await getAIStream (payload);
for await (const chunk of aiStream) {
const sseData = `data: ${JSON .stringify({ text: chunk, done: false })} \n\n` ;
controller.enqueue (new TextEncoder ().encode (sseData));
}
controller.enqueue (
new TextEncoder ().encode (`data: ${JSON .stringify({ done: true })} \n\n` )
);
} catch (error) {
controller.enqueue (
new TextEncoder ().encode (`data: ${JSON .stringify({ error: 'Stream failed' , done: true })} \n\n` )
);
} finally {
controller.close ();
}
},
});
return {
status : 200 ,
headers : {
'Content-Type' : 'text/event-stream' ,
'Cache-Control' : 'no-cache' ,
'Connection' : 'keep-alive' ,
'X-Accel-Buffering' : 'no' ,
},
body : stream,
};
},
});
Client Consumption
POST + ReadableStream Pattern interface SSEMessage {
text ?: string ;
done : boolean ;
error ?: string ;
}
async function streamResponse (
payload : unknown ,
onChunk : (text: string ) => void ,
onComplete : () => void ,
onError : (error: string ) => void ,
): Promise <void > {
const response = await fetch ('/api/stream' , {
method : 'POST' ,
headers : { 'Content-Type' : 'application/json' },
body : JSON .stringify (payload),
});
if (!response.ok ) {
onError (`HTTP ${response.status} : ${response.statusText} ` );
return ;
}
const reader = response.body !.getReader ();
const decoder = new TextDecoder ();
let buffer = '' ;
while (true ) {
const { done, value } = await reader.read ();
if (done) break ;
buffer += decoder.decode (value, { stream : true });
const messages = buffer.split ('\n\n' );
buffer = messages.pop () || '' ;
for (const msg of messages) {
if (!msg.startsWith ('data: ' )) continue ;
const json = msg.slice (6 );
try {
const parsed : SSEMessage = JSON .parse (json);
if (parsed.error ) { onError (parsed.error ); return ; }
if (parsed.text ) { onChunk (parsed.text ); }
if (parsed.done ) { onComplete (); return ; }
} catch {
}
}
}
onComplete ();
}
React Hook function useStreamedResponse ( ) {
const [text, setText] = useState ('' );
const [isStreaming, setIsStreaming] = useState (false );
const [error, setError] = useState<string | null >(null );
const stream = useCallback (async (payload : unknown ) => {
setText ('' );
setIsStreaming (true );
setError (null );
await streamResponse (
payload,
(chunk ) => setText (prev => prev + chunk),
() => setIsStreaming (false ),
(err ) => { setError (err); setIsStreaming (false ); },
);
}, []);
return { text, isStreaming, error, stream };
}
Cancellation with AbortController async function streamWithAbort (
payload : unknown ,
signal : AbortSignal ,
onChunk : (text: string ) => void ,
): Promise <void > {
const response = await fetch ('/api/stream' , {
method : 'POST' ,
headers : { 'Content-Type' : 'application/json' },
body : JSON .stringify (payload),
signal,
});
const reader = response.body !.getReader ();
signal.addEventListener ('abort' , () => reader.cancel ());
}
const controller = new AbortController ();
streamWithAbort (payload, controller.signal , onChunk);
controller.abort ();
SWA Timeout Handling Azure Static Web Apps has a 45-second API timeout . For long operations, use multi-phase streaming:
app.http ('long-operation' , {
methods : ['POST' ],
handler : async (req, context) => {
const stream = new ReadableStream ({
async start (controller ) {
const send = (data : object ) =>
controller.enqueue (new TextEncoder ().encode (`data: ${JSON .stringify(data)} \n\n` ));
send ({ phase : 'step-1' , progress : 0.1 });
const result1 = await doStep1 ();
send ({ phase : 'step-2' , progress : 0.5 });
const result2 = await doStep2 (result1);
send ({ phase : 'complete' , progress : 1.0 , result : result2 });
controller.close ();
},
});
return { body : stream, headers : { 'Content-Type' : 'text/event-stream' } };
},
});
Error Recovery
Retry Strategy async function streamWithRetry (
payload : unknown ,
onChunk : (text: string ) => void ,
maxRetries : number = 2 ,
): Promise <void > {
let lastError : string | undefined ;
for (let attempt = 0 ; attempt <= maxRetries; attempt++) {
try {
await streamResponse (payload, onChunk, () => {}, (err ) => { throw new Error (err); });
return ;
} catch (error) {
lastError = error instanceof Error ? error.message : 'Unknown error' ;
if (attempt < maxRetries) {
await new Promise (resolve => setTimeout (resolve, 1000 * (attempt + 1 )));
}
}
}
throw new Error (`Stream failed after ${maxRetries + 1 } attempts: ${lastError} ` );
}
Activation Patterns Trigger Response "SSE", "streaming", "server-sent events" Full skill activation "Azure Functions stream", "HTTP streaming" Azure Functions Setup section "ReadableStream", "chunked response" Client Consumption section "abort", "cancel stream" Cancellation section "SWA timeout", "45 second" SWA Timeout Handling section