@@ -807,11 +807,57 @@ export class FeishuMcpServer {
807
807
808
808
async startHttpServer ( port : number ) : Promise < void > {
809
809
const app = express ( ) ;
810
+ const transports : { [ sessionId : string ] : SSEServerTransport } = { } ;
811
+ const sseConnections = new Map < string , { res : Response , intervalId : NodeJS . Timeout } > ( ) ;
812
+ const KEEP_ALIVE_INTERVAL_MS = 25000 ; // Send keep-alive every 25 seconds
813
+
810
814
811
815
app . get ( '/sse' , async ( _req : Request , res : Response ) => {
812
816
console . log ( 'New SSE connection established' ) ;
813
817
this . sseTransport = new SSEServerTransport ( '/messages' , res as unknown as ServerResponse < IncomingMessage > ) ;
814
- await this . server . connect ( this . sseTransport ) ;
818
+
819
+ const sessionId = this . sseTransport . sessionId ; // Get session ID from transport
820
+ transports [ sessionId ] = this . sseTransport ;
821
+ // Start keep-alive ping
822
+ const intervalId = setInterval ( ( ) => {
823
+ if ( sseConnections . has ( sessionId ) && ! res . writableEnded ) {
824
+ res . write ( ': keepalive\n\n' ) ;
825
+ } else {
826
+ // Should not happen if close handler is working, but clear just in case
827
+ clearInterval ( intervalId ) ;
828
+ sseConnections . delete ( sessionId ) ;
829
+ }
830
+ } , KEEP_ALIVE_INTERVAL_MS ) ;
831
+ // Store connection details
832
+ sseConnections . set ( sessionId , { res, intervalId } ) ;
833
+ console . log ( `[SSE Connection] Client connected: ${ sessionId } , starting keep-alive.` ) ;
834
+ res . on ( "close" , ( ) => {
835
+ console . log ( `[SSE Connection] Client disconnected: ${ sessionId } , stopping keep-alive.` ) ;
836
+ // Clean up transport
837
+ delete transports [ sessionId ] ;
838
+ // Clean up keep-alive interval
839
+ const connection = sseConnections . get ( sessionId ) ;
840
+ if ( connection ) {
841
+ clearInterval ( connection . intervalId ) ;
842
+ sseConnections . delete ( sessionId ) ;
843
+ }
844
+ } ) ;
845
+ // Connect server to transport *after* setting up handlers
846
+ try {
847
+ await this . server . connect ( this . sseTransport )
848
+ } catch ( error ) {
849
+ console . error ( `[SSE Connection] Error connecting server to transport for ${ sessionId } :` , error ) ;
850
+ // Ensure cleanup happens even if connect fails
851
+ clearInterval ( intervalId ) ;
852
+ sseConnections . delete ( sessionId ) ;
853
+ delete transports [ sessionId ] ;
854
+ if ( ! res . writableEnded ) {
855
+ res . status ( 500 ) . end ( 'Failed to connect MCP server to transport' ) ;
856
+ }
857
+ }
858
+
859
+
860
+ // await this.server.connect(this.sseTransport);
815
861
} ) ;
816
862
817
863
app . post ( '/messages' , async ( req : Request , res : Response ) => {
0 commit comments