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

.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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 06:53:17