.NET 4.5 ASP.NET WebApi如何转发Spring服务的Server-Sent-Events
ASP.NET WebAPI转发Spring SSE流失败问题
我有一个基于.NET 4.5的ASP.NET WebApi应用,需要在控制器中创建两个端点调用基于Spring Web的Java服务。其中一个端点需要实时转发Spring服务发送的Server-Sent-Events(SSE),但尝试了两种C#实现方式均失败。
需求说明:Spring服务在执行操作时会流式输出文本,需要将这些文本实时转发给前端展示操作进度,希望避免通过轮询获取状态的方式。
尝试的两种C#实现
第一种实现(返回HttpResponseMessage)
[HttpPost] [Route("api/myApp/myEndpoint")] public async Task<HttpResponseMessage> myEndpoint([FromBody] MyEndpointParams params) { try { using (var client = new HttpClient(new HttpClientHandler { AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate })) { string uri = "https://theServer/theSpringApp/api/theServerEventsSendingEndpoint"; StringContent content = new StringContent(JsonConvert.SerializeObject(params), Encoding.UTF8, "application/json"); HttpRequestMessage request = new HttpRequestMessage() { Method = HttpMethod.Post, RequestUri = new Uri(uri), Content = content }; return await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead); } } catch (Exception ex) { log.Error("[myEndpoint] Error", ex); return new HttpResponseMessage(HttpStatusCode.InternalServerError); } }
第二种实现(返回IDisposable)
[HttpPost] [Route("api/myApp/myEndpoint")] public async Task<IDisposable> myEndpoint([FromBody] MyEndpointParams params) { try { using (var client = new HttpClient(new HttpClientHandler { AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate })) { string uri = "https://theServer/theSpringApp/api/theServerEventsSendingEndpoint"; StringContent content = new StringContent(JsonConvert.SerializeObject(params), Encoding.UTF8, "application/json"); HttpRequestMessage request = new HttpRequestMessage() { Method = HttpMethod.Post, RequestUri = new Uri(uri), Content = content }; var response = client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead); return await response.Result.Content.ReadAsStreamAsync(); } } catch (Exception ex) { log.Error("[myEndpoint] Error", ex); return new HttpResponseMessage(HttpStatusCode.InternalServerError); } }
Spring服务端点核心代码
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; ... private ExecutorService executorService = Executors.newCachedThreadPool(); ... @PostMapping(path = "/api/theServerEventsSendingEndpoint", produces = MediaType.TEXT_PLAIN_VALUE) public SseEmitter sendTheServerEvents(@RequestBody(required = true) MyEndpointParams params) { SseEmitter emitter = new SseEmitter(); executorService.execute(() -> { // 循环执行操作,每次循环执行: emitter.send("some text that depends on the operation it's doing"); // 操作结束后: emitter.complete(); // 省略了错误处理代码 }); return emitter; }
内容的提问来源于stack exchange,提问作者nonzaprej
相关产品推荐
相关产品推荐

