.NET 6.x Blazor Server如何处理流式/分块REST API响应?
Blazor Server 处理SSE流式API响应方案(适配Mixtral LLM)
这种流式响应属于Server-Sent Events (SSE) 格式,每个数据块以data:前缀开头,需逐行读取解析有效JSON内容,再实时更新Blazor前端。以下是具体实现方案:
核心实现步骤
1. 发起SSE请求并解析流式数据
通过HttpClient发起请求时指定text/event-stream类型,逐行读取响应流,过滤无效行后提取JSON内容:
private async Task StreamMixtralResponse(string prompt) { var request = new HttpRequestMessage(HttpMethod.Post, "你的Mixtral端点地址"); request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("text/event-stream")); request.Content = new StringContent(JsonSerializer.Serialize(new { prompt = prompt }), Encoding.UTF8, "application/json"); using var response = await _httpClient.SendAsync(request, 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) { // 过滤空行和非data开头的行 if (string.IsNullOrWhiteSpace(line) || !line.StartsWith("data:")) continue; // 提取data前缀后的JSON内容 var jsonContent = line.Substring(5).Trim(); if (string.IsNullOrWhiteSpace(jsonContent)) continue; // 反序列化JSON块 var chunk = JsonSerializer.Deserialize<MixtralChunk>(jsonContent); if (chunk == null) continue; // 线程安全更新前端UI await InvokeAsync(() => { CurrentResponse += chunk.Content; // 替换为实际返回的字段名 StateHasChanged(); }); // 检测流式传输结束标记 if (chunk.DataCompleteToken) break; } } // 定义响应块模型(根据实际字段调整) public class MixtralChunk { [JsonPropertyName("content")] public string Content { get; set; } [JsonPropertyName("data_complete_token")] public bool DataCompleteToken { get; set; } }
2. 前端组件调用与实时展示
在Razor组件中添加交互元素和响应展示区域:
<div> <input @bind="UserPrompt" placeholder="输入提问内容" /> <button @onclick="StartStreaming">发送请求</button> </div> <div class="stream-response"> @CurrentResponse </div> @code { [Inject] private HttpClient HttpClient { get; set; } private string UserPrompt { get; set; } private string CurrentResponse { get; set; } = string.Empty; private async Task StartStreaming() { CurrentResponse = string.Empty; // 清空历史响应 await StreamMixtralResponse(UserPrompt); } }
3. 关键注意事项
- 线程安全:Blazor Server中必须通过
InvokeAsync更新UI,避免跨线程操作异常。 - 资源释放:用
using语句自动释放Stream、StreamReader等资源,防止内存泄漏。 - 错误处理:可添加
try-catch块捕获请求超时、连接中断等异常,支持用户主动取消操作。 - 性能优化:若响应频率过高,可合并多次UI更新,减少
StateHasChanged调用次数,避免UI卡顿。
内容的提问来源于stack exchange,提问作者Brian
相关产品推荐
相关产品推荐

