You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 16:03:15