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

如何在C#中实现POST请求并接收Server-Sent Event流?

解决C#中POST请求+SSE流式状态更新的问题

你的思路核心问题在于WebClient的设计不支持同时发送POST请求体并流式读取SSE响应——它的异步操作基于单个连接,同时调用UploadStringAsync和OpenReadAsync必然触发冲突;而UploadString会等待整个响应完成才返回,完全违背了SSE流式推送的初衷。

正确的做法是改用HttpClient,它天生支持流式响应处理,能完美适配这种"POST提交任务+实时接收状态更新"的场景。下面是具体实现步骤:

1. 基础实现代码

using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;

public async Task ListenToTaskStatusAsync(string endpoint, string token, object model)
{
    using var httpClient = new HttpClient();
    // 设置请求头
    httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/event-stream"));
    httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);

    // 构建POST请求体
    var jsonContent = new StringContent(
        JsonSerializer.Serialize(model),
        Encoding.UTF8,
        "application/json");

    // 发送请求,指定拿到响应头后就开始处理流(不等待全响应)
    using var response = await httpClient.SendAsync(
        new HttpRequestMessage(HttpMethod.Post, endpoint) { Content = jsonContent },
        HttpCompletionOption.ResponseHeadersRead);

    response.EnsureSuccessStatusCode(); // 确保请求成功

    // 读取响应流
    using var stream = await response.Content.ReadAsStreamAsync();
    using var reader = new StreamReader(stream);

    string line;
    while ((line = await reader.ReadLineAsync()) != null)
    {
        // 解析SSE格式的行
        if (line.StartsWith("data:"))
        {
            var statusData = line.Substring(5).Trim();
            // 这里替换成你的状态处理逻辑
            ServerEventOccurs(statusData);
        }
        // 如需处理事件类型,可扩展此处逻辑
        else if (line.StartsWith("event:"))
        {
            var eventType = line.Substring(6).Trim();
            // 根据事件类型做对应处理
        }
    }
}

// 模拟你的状态处理方法
private void ServerEventOccurs(string statusData)
{
    Console.WriteLine($"收到状态更新:{statusData}");
}

2. 关键细节说明

  • HttpCompletionOption.ResponseHeadersRead:这个选项让HttpClient不需要等待整个响应体下载完成,拿到响应头就开始返回,是实现流式读取的核心。
  • SSE格式解析:SSE消息通常以data:开头,多行数据用换行分隔、空行结束。上面的代码处理了基础的单行data事件,复杂场景可扩展解析逻辑。
  • HttpClient生命周期:实际项目中建议复用HttpClient实例(比如单例或依赖注入),示例中用using是为了简洁展示。

为什么WebClient不行?

WebClient是封装程度很高的旧类,异步操作基于单个连接串行执行,无法同时处理"发送POST体"和"读取流"两个操作。而HttpClient是为现代HTTP场景设计的,支持底层流操作和异步模式,完全适配SSE长连接流式响应的需求。

内容的提问来源于stack exchange,提问作者Philipp

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 17:23:36