Skip to main content Skills Marketplace コミュニティが作成したAIスキルを発見・探索
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
直接コマンドでは確認用 Prompt が省略されます。実行前にソースを確認してください。
npx skills add https://github.com/fabioc-aloha/ChessCoach --skill sse-streamingコマンドは1行のまま表示されます。コピー前に横へスクロールして全体を確認してください。
ローカルで確認しますか?SkillsMP が現在取得できるファイルをダウンロードできます。
Zipをダウンロード ダウンロード中... type skill lifecycle stable inheritance inheritable 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":[]} currency 2026-04-22T00:00:00.000Z
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' ,
: ,
: ( : , : ): < > => {
payload = req. ();
stream = ({
( ) {
{
aiStream = (payload);
( chunk aiStream) {
sseData = ;
controller. ( (). (sseData));
}
controller. (
(). ( )
);
} (error) {
controller. (
(). ( )
);
} {
controller. ();
}
},
});
{
: ,
: {
: ,
: ,
: ,
: ,
},
: stream,
};
},
});
route
'stream'
handler
async
req
HttpRequest
context
InvocationContext
Promise
HttpResponseInit
const
await
json
const
new
ReadableStream
async
start
controller
try
const
await
getAIStream
for
await
const
of
const
`data: ${JSON .stringify({ text: chunk, done: false })} \n\n`
enqueue
new
TextEncoder
encode
enqueue
new
TextEncoder
encode
`data: ${JSON .stringify({ done: true })} \n\n`
catch
enqueue
new
TextEncoder
encode
`data: ${JSON .stringify({ error: 'Stream failed' , done: true })} \n\n`
finally
close
return
status
200
headers
'Content-Type'
'text/event-stream'
'Cache-Control'
'no-cache'
'Connection'
'keep-alive'
'X-Accel-Buffering'
'no'
body
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