From bf16ac11b1da6b006a23d0909fe4dfc2ab57e748 Mon Sep 17 00:00:00 2001 From: TianyiLi Date: Thu, 5 Jun 2025 02:09:05 +1000 Subject: [PATCH] Add flush method to StreamableHTTPServerTransport for immediate data transmission --- src/server/streamableHttp.ts | 39 ++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/server/streamableHttp.ts b/src/server/streamableHttp.ts index dc99c306..53a124e0 100644 --- a/src/server/streamableHttp.ts +++ b/src/server/streamableHttp.ts @@ -524,6 +524,45 @@ export class StreamableHTTPServerTransport implements Transport { return true; } + /** + * Flushes all active HTTP response streams to force immediate sending of buffered data. + * This is useful for progress notifications and other real-time updates that need + * to be sent immediately rather than being buffered by the HTTP layer. + */ + flush() { + // Flush all active response streams + this._streamMapping.forEach((response) => { + try { + // Force the response to be sent by accessing the underlying socket + const socket = response.socket; + if (socket && typeof socket.flush === 'function') { + // Some socket implementations have a flush method + socket.flush(); + } else if (socket && !socket.destroyed) { + // Force the socket to send any buffered data + // This is the most reliable way to force HTTP data to be sent + socket.uncork(); + socket.cork(); + socket.uncork(); + } + + // Alternative approach: Write an empty chunk to force transmission + // This works because writing data often triggers the HTTP layer to flush + if (response.chunkedEncoding && response.writable && !response.destroyed) { + // For chunked encoding, we can write an empty chunk + // This forces the HTTP layer to send any buffered data + response.write(''); + } + } catch (error) { + // Ignore errors from closed connections or invalid states + if (error instanceof Error) { + console.warn('Warning: Failed to flush response stream:', error.message); + } else { + console.warn('Warning: Failed to flush response stream:', String(error)); + } + } + }); + } async close(): Promise { // Close all SSE connections