WebController.cs 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. using System.Linq;
  6. using Newtonsoft.Json;
  7. using UnityEngine;
  8. using UnityEngine.Networking;
  9. using UnityEngine.SceneManagement;
  10. /* 本文件二次封装Web request
  11. * 不需要客户端确认是否需要提交accss_token,access_token白名单在EnviromentSetting里面
  12. * PostRequest 需要提交url, wwwForm, 上传附件path, 回调函数
  13. */
  14. public class WebController : MonoBehaviour
  15. {
  16. // Start is called before the first frame update
  17. //void Start()
  18. //{
  19. //}
  20. // Update is called once per frame
  21. //void Update()
  22. //{
  23. //}
  24. public static IEnumerator PostRequest(string url, WWWForm wwwForm, string filePath = null, System.Action<string> callback = null)
  25. {
  26. while (string.IsNullOrEmpty(EnviromentSetting.serverIP))
  27. {
  28. // 等待服务器IP被设置
  29. yield return new WaitForSeconds(0.1f);
  30. }
  31. // 检测是否需要添加access_token
  32. bool accessTokenReq = true;
  33. if (EnviromentSetting.accessTokenWhiteList.Contains<string>(url))
  34. {
  35. accessTokenReq = false;
  36. }
  37. // 添加access token
  38. if (accessTokenReq)
  39. {
  40. // 如果access token过期,跳转登录场景
  41. TimeSpan ts = DateTime.Now - EnviromentSetting.accessTokenReceivedTime;
  42. if (ts.TotalHours >= 24)
  43. {
  44. GameData.subScene = null;
  45. SceneManager.LoadScene("Login");
  46. }
  47. else
  48. {
  49. wwwForm.AddField("access_token", EnviromentSetting.accessToken);
  50. }
  51. }
  52. // 添加文件
  53. if (filePath != null)
  54. {
  55. byte[] fileData = System.IO.File.ReadAllBytes(filePath);
  56. wwwForm.AddBinaryData(Path.GetFileNameWithoutExtension(filePath), fileData);
  57. }
  58. wwwForm.AddField("date_time", DateTime.Now.ToString()); // 可选项,以服务器时间为准
  59. // 创建 UnityWebRequest 对象
  60. url = EnviromentSetting.serverIP + url;
  61. using (UnityWebRequest request = UnityWebRequest.Post(url, wwwForm))
  62. {
  63. // 发送请求并等待响应
  64. yield return request.SendWebRequest();
  65. // 检查是否有错误
  66. if (request.result == UnityWebRequest.Result.ConnectionError || request.result == UnityWebRequest.Result.ProtocolError)
  67. {
  68. Debug.Log("上传失败: " + request.error);
  69. if (request.error == "Cannot connect to destination host")
  70. {
  71. string msg = GameTool.GetValueAtPath(EnviromentSetting.languageData, new string[] { "game_message", "network_error", EnviromentSetting.languageCode });
  72. MessageBoxController.ShowMessage(msg, () => Application.Quit());
  73. }
  74. Debug.Log("上传失败信息: " + request.downloadHandler.text);
  75. }
  76. else
  77. {
  78. string responseText = request.downloadHandler.text;
  79. // 检测是否存在error code
  80. var data = JsonConvert.DeserializeObject<Dictionary<string, object>>(responseText);
  81. if (data != null && data.ContainsKey("code") && data.ContainsKey("status"))
  82. {
  83. if (data["status"].ToString() == "error")
  84. {
  85. int errorCode = Convert.ToInt32(data["code"]);
  86. if (errorCode == 400)
  87. {
  88. // 如果是400错误,跳转登录场景
  89. Debug.Log("Access token expired or invalid, redirecting to login scene.");
  90. GameData.subScene = null;
  91. SceneManager.LoadScene("Login");
  92. yield break; // 退出协程
  93. }
  94. }
  95. }
  96. // 上传成功,获取服务器响应
  97. callback?.Invoke(responseText);
  98. Debug.Log("上传成功!服务器响应: " + responseText);
  99. }
  100. }
  101. }
  102. public static IEnumerator ServerAliveCheck()
  103. {
  104. string url = "/api/server/alive/";
  105. // 尝试从 PlayerPrefs 中获取上次使用的服务器IP
  106. if (PlayerPrefs.HasKey("last_serverIP"))
  107. {
  108. EnviromentSetting.serverIP = PlayerPrefs.GetString("last_serverIP");
  109. Debug.Log("使用上次的服务器IP: " + EnviromentSetting.serverIP);
  110. }
  111. // 检测上次使用的服务器IP是否可用
  112. if (!string.IsNullOrEmpty(EnviromentSetting.serverIP))
  113. {
  114. string fullUrl = EnviromentSetting.serverIP + url;
  115. using (UnityWebRequest request = UnityWebRequest.Get(fullUrl))
  116. {
  117. yield return request.SendWebRequest();
  118. if (request.result == UnityWebRequest.Result.ConnectionError || request.result == UnityWebRequest.Result.ProtocolError)
  119. {
  120. Debug.Log("上次使用的服务器不可用: " + fullUrl + ": " + request.error);
  121. }
  122. else
  123. {
  124. Debug.Log("上次使用的服务器可用: " + fullUrl);
  125. yield break; // 如果上次使用的服务器可用,直接返回
  126. }
  127. }
  128. }
  129. int serverIPIndex = 0;
  130. foreach (string serverIP in EnviromentSetting.serverIPs)
  131. {
  132. string fullUrl = serverIP + url;
  133. using (UnityWebRequest request = UnityWebRequest.Get(fullUrl))
  134. {
  135. yield return request.SendWebRequest();
  136. if (request.result == UnityWebRequest.Result.ConnectionError || request.result == UnityWebRequest.Result.ProtocolError)
  137. {
  138. Debug.Log("服务器不可用: " + fullUrl + ": " + request.error);
  139. serverIPIndex++;
  140. }
  141. else
  142. {
  143. Debug.Log("服务器可用: " + fullUrl);
  144. EnviromentSetting.serverIP = serverIP; // 更新当前使用的服务器IP
  145. PlayerPrefs.SetString("last_serverIP", serverIP); // 保存到PlayerPrefs
  146. yield break; // 如果有一个服务器可用,直接返回
  147. }
  148. }
  149. }
  150. if (serverIPIndex >= EnviromentSetting.serverIPs.Length)
  151. {
  152. PlayerPrefs.DeleteKey("last_serverIP"); // 清除上次使用的服务器IP
  153. string msg = GameTool.GetValueAtPath(EnviromentSetting.languageData, new string[] { "game_message", "network_error", EnviromentSetting.languageCode });
  154. MessageBoxController.ShowMessage(msg, () => Application.Quit());
  155. Application.Quit();
  156. Debug.LogError("所有服务器都不可用,退出游戏");
  157. }
  158. }
  159. }