如何在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
相关产品推荐
相关产品推荐

