126 lines
4.8 KiB
C#
126 lines
4.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using System.IO;
|
|
using System.Net.Http;
|
|
using System.Net.Http.Headers;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using LinkToolAddin.host.llm.entity;
|
|
using LinkToolAddin.host.llm.entity.stream;
|
|
using Newtonsoft.Json;
|
|
|
|
namespace LinkToolAddin.common;
|
|
|
|
public class HttpRequest
|
|
{
|
|
public static async Task<string> SendPostRequestAsync(string url, string jsonContent, string apiKey)
|
|
{
|
|
using var httpClient = new HttpClient();
|
|
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);
|
|
var response = await httpClient.PostAsync(url, new StringContent(jsonContent, Encoding.UTF8, "application/json"));
|
|
response.EnsureSuccessStatusCode();
|
|
var responseBody = await response.Content.ReadAsStringAsync();
|
|
return responseBody;
|
|
}
|
|
|
|
public static async IAsyncEnumerable<string> SendStreamPostRequestAsync(string url, string jsonContent, string apiKey)
|
|
{
|
|
using var client = new HttpClient();
|
|
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);
|
|
|
|
// 发送 POST 请求并获取响应流
|
|
var response = await client.PostAsync(url,new StringContent(jsonContent, Encoding.UTF8, "application/json"));
|
|
|
|
// 验证响应状态
|
|
response.EnsureSuccessStatusCode();
|
|
|
|
// 获取响应流
|
|
using var stream = await response.Content.ReadAsStreamAsync();
|
|
using var reader = new StreamReader(stream);
|
|
|
|
// 流式读取
|
|
string line;
|
|
while ((line = await reader.ReadLineAsync()) != null)
|
|
{
|
|
string content = ProcessPartialResponse(line);
|
|
yield return content;
|
|
}
|
|
}
|
|
|
|
private static string ProcessPartialResponse(string rawData)
|
|
{
|
|
try
|
|
{
|
|
var lines = rawData.Split(new[] { "data: " }, StringSplitOptions.RemoveEmptyEntries);
|
|
foreach (var line in lines)
|
|
{
|
|
var trimmedLine = line.Trim();
|
|
if (!string.IsNullOrEmpty(trimmedLine))
|
|
{
|
|
var result = JsonConvert.DeserializeObject<LlmStreamChat>(trimmedLine);
|
|
return result.Choices[0].Delta.Content;
|
|
}
|
|
}
|
|
}
|
|
catch { /* 处理解析异常 */ }
|
|
return null;
|
|
}
|
|
|
|
public static async IAsyncEnumerable<string> PostWithStreamingResponseAsync(
|
|
string url,
|
|
string body,
|
|
string apiKey,
|
|
string contentType = "application/json",
|
|
Action<HttpRequestMessage> configureHeaders = null)
|
|
{
|
|
using (var client = new HttpClient())
|
|
{
|
|
// 设置超时时间为30分钟
|
|
client.Timeout = TimeSpan.FromMinutes(30);
|
|
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);
|
|
using (var request = new HttpRequestMessage(HttpMethod.Post, url))
|
|
{
|
|
// 设置请求头和Body
|
|
Console.WriteLine("开始请求...");
|
|
configureHeaders?.Invoke(request);
|
|
request.Content = new StringContent(body, Encoding.UTF8, contentType);
|
|
|
|
// 发送请求并立即开始读取响应流
|
|
using (var response = await client.SendAsync(
|
|
request,
|
|
HttpCompletionOption.ResponseHeadersRead))
|
|
{
|
|
response.EnsureSuccessStatusCode();
|
|
|
|
// 获取响应流
|
|
using (var stream = await response.Content.ReadAsStreamAsync())
|
|
using (var reader = new StreamReader(stream))
|
|
{
|
|
string line;
|
|
|
|
StringBuilder incompleteJsonBuffer = new StringBuilder();
|
|
|
|
// 流式读取并输出到控制台
|
|
while ((line = await reader.ReadLineAsync()) != null)
|
|
{
|
|
foreach (var chunk in line.Split(new[] { "data: " }, StringSplitOptions.RemoveEmptyEntries))
|
|
{
|
|
LlmStreamChat dataObj = null;
|
|
try
|
|
{
|
|
dataObj = JsonConvert.DeserializeObject<LlmStreamChat>(chunk);
|
|
}catch{/*process exception*/}
|
|
|
|
if (dataObj is not null)
|
|
{
|
|
yield return dataObj.Choices[0].Delta.Content;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |