refactor(transport): Replace SseEmitter with queue-based SSE implementation in WebMvc transport
Replaces Spring's SseEmitter with a custom BlockingQueue-based SSE implementation in WebMvcSseServerTransport for improved event delivery control and connection management. The new implementation: - Uses BlockingQueue for reliable event queuing and delivery - Adds proper session management with dedicated SSEEvent record - Improves error handling and timeout management - Adds comprehensive integration tests Resolves #57
This commit is contained in:
parent
5058b08406
commit
edbd78465c
5 changed files with 726 additions and 104 deletions
|
|
@ -27,6 +27,13 @@
|
|||
<artifactId>mcp-webmvc-sse-transport</artifactId>
|
||||
<version>${spring-ai-mcp.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Used only for the client webflux transport -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.experimental</groupId>
|
||||
<artifactId>mcp-webflux-sse-transport</artifactId>
|
||||
<version>${spring-ai-mcp.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.experimental</groupId>
|
||||
<artifactId>spring-ai-mcp</artifactId>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright 2024 - 2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.ai.mcp.sample.webmvc.client;
|
||||
|
||||
import org.springframework.ai.mcp.client.transport.WebFluxSseClientTransport;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
/**
|
||||
* @author Christian Tzolov
|
||||
*/
|
||||
public class ClientWebFluxSse {
|
||||
|
||||
public static void main(String[] args) {
|
||||
var transport = new WebFluxSseClientTransport(WebClient.builder().baseUrl("http://localhost:8080"));
|
||||
|
||||
new SampleClient(transport).run();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package org.springframework.ai.mcp.sample.webmvc.server;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class McpMvcServerApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(McpMvcServerApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -31,8 +31,6 @@ import org.springframework.context.annotation.Configuration;
|
|||
import org.springframework.web.client.RestClient;
|
||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
||||
import org.springframework.web.servlet.function.RouterFunction;
|
||||
import org.springframework.web.servlet.function.ServerResponse;
|
||||
|
||||
|
|
@ -40,14 +38,6 @@ import org.springframework.web.servlet.function.ServerResponse;
|
|||
@EnableWebMvc
|
||||
public class McpServerConfig implements WebMvcConfigurer {
|
||||
|
||||
@Override
|
||||
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
|
||||
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
|
||||
converter.setSupportedMediaTypes(List.of(org.springframework.http.MediaType.APPLICATION_JSON,
|
||||
org.springframework.http.MediaType.TEXT_EVENT_STREAM));
|
||||
converters.add(converter);
|
||||
}
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(McpServerConfig.class);
|
||||
|
||||
@Bean
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
# spring.main.web-application-type=none
|
||||
spring.main.web-application-type=SERVLET
|
||||
|
||||
# NOTE: You must disable the banner and the console logging
|
||||
# to allow the STDIO transport to work !!!
|
||||
spring.main.banner-mode=off
|
||||
# logging.pattern.console=
|
||||
logging.pattern.console=
|
||||
|
||||
transport.mode=sse
|
||||
Loading…
Reference in a new issue