using System.Net.Http; using System.Text; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; namespace ConsoleApp9 { internal class Program { private static readonly JsonSerializerSettings serializerSettings = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver(), NullValueHandling = NullValueHandling.Ignore // 堆代码 duidaima.com }; private static readonly HttpClient httpClient = new HttpClient(); // 复用HttpClient实例 private static readonly SemaphoreSlim semaphore = new SemaphoreSlim(100); // 限制并发请求数量为100 static async Task Main(string[] args) { List<Task> tasks = new List<Task>(); int taskNoCounter = 1; // 用于跟踪 taskno // 只使用一个HttpClient对象(全局共享) for (int i = 0; i < 50; i++) { tasks.Add(Task.Run(async () => { // 等待信号量,控制最大并发数 await semaphore.WaitAsync(); try { var postData = new { taskno = taskNoCounter++, content = "等待翻译的内容" }; var json = JsonConvert.SerializeObject(postData, serializerSettings); var reqdata = new StringContent(json, Encoding.UTF8, "application/json"); // 设置请求头语言 httpClient.DefaultRequestHeaders.Add("Accept-Language", "en-US"); // 发送请求 var result = await httpClient.PostAsync("http://localhost:5000/translate", reqdata); // 读取并反序列化 JSON 数据 var content = await result.Content.ReadAsStringAsync(); var jsonResponse = JsonConvert.DeserializeObject<Response>(content); var response = jsonResponse.Data.Content; // 反序列化后,直接输出解码后的文本 Console.WriteLine($"结果为:{response}"); } catch (Exception ex) { Console.WriteLine($"请求失败: {ex.Message}"); } finally { // 释放信号量 semaphore.Release(); } })); } await Task.WhenAll(tasks); } } // 定义与响应结构匹配的类 public class Response { public int Code { get; set; } public ResponseData Data { get; set; } public string Msg { get; set; } } public class ResponseData { public string Content { get; set; } public string Lang { get; set; } public int Taskno { get; set; } } }接收代码如下:
from flask import Flask, request, jsonify from google.cloud import translate_v2 as translate app = Flask(__name__) # 初始化 Google Cloud Translate 客户端 translator = translate.Client() @app.route('/translate', methods=['POST']) def translate_text(): try: # 从请求中获取 JSON 数据 data = request.get_json() # 获取请求的文本内容 text = data.get('content') taskno = data.get('taskno', 1) # 获取请求头中的 Accept-Language 信息,默认为 'zh-CN' accept_language = request.headers.get('Accept-Language', 'zh-CN') # 调用 Google Translate API 进行翻译 result = translator.translate(text, target_language=accept_language) # 构造响应数据 response_data = { "code": 200, "msg": "OK", "data": { "taskno": taskno, "content": result['translatedText'], "lang": accept_language } } # 返回 JSON 响应 return jsonify(response_data), 200 except Exception as e: return jsonify({"code": 500, "msg": str(e)}), 500 if __name__ == "__main__": app.run(debug=True, host="0.0.0.0", port=5000)Accept-Language 请求头是通过 httpClient.DefaultRequestHeaders.Add("Accept-Language", language) 来设置的。这是一个常见的做法,目的是为每个请求指定特定的语言。然而,在实际应用中,尤其是当 HttpClient 被复用并发发送多个请求时,这种方法可能会引发请求头丢失或错误的情况。
using System.Net.Http; using System.Text; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; namespace ConsoleApp9 { internal class Program { private static readonly JsonSerializerSettings serializerSettings = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver(), NullValueHandling = NullValueHandling.Ignore }; private static readonly HttpClient httpClient = new HttpClient(); // 复用HttpClient实例 private static readonly SemaphoreSlim semaphore = new SemaphoreSlim(100); // 限制并发请求数量为100 static async Task Main(string[] args) { List<Task> tasks = new List<Task>(); int taskNoCounter = 1; // 用于跟踪 taskno // 只使用一个HttpClient对象(全局共享) for (int i = 0; i < 50; i++) { tasks.Add(Task.Run(async () => { // 等待信号量,控制最大并发数 await semaphore.WaitAsync(); try { var postData = new { taskno = taskNoCounter++, content = "等待翻译的内容" }; var json = JsonConvert.SerializeObject(postData, serializerSettings); var reqdata = new StringContent(json, Encoding.UTF8, "application/json"); // 使用HttpRequestMessage确保每个请求都可以单独设置头 var requestMessage = new HttpRequestMessage(HttpMethod.Post, "http://localhost:5000/translate") { Content = reqdata }; // 设置请求头 requestMessage.Headers.Add("Accept-Language", "en-US"); // 发起POST请求 var result = await httpClient.SendAsync(requestMessage); // 读取并反序列化 JSON 数据 var content = await result.Content.ReadAsStringAsync(); var jsonResponse = JsonConvert.DeserializeObject<Response>(content); var response = jsonResponse.Data.Content; // 反序列化后,直接输出解码后的文本 Console.WriteLine($"结果为:{response}"); } catch (Exception ex) { Console.WriteLine($"请求失败: {ex.Message}"); } finally { // 释放信号量 semaphore.Release(); } })); } await Task.WhenAll(tasks); } } // 定义与响应结构匹配的类 public class Response { public int Code { get; set; } public ResponseData Data { get; set; } public string Msg { get; set; } } public class ResponseData { public string Content { get; set; } public string Lang { get; set; } public int Taskno { get; set; } } }五. 解析解决方案:为何 HttpRequestMessage 更加可靠
请求灵活性:HttpRequestMessage 不仅可以设置请求头,还可以设置请求方法、请求体、请求的 URI 等,这使得它比直接使用 DefaultRequestHeaders 更加灵活和可控。