fix:调整httpserver

This commit is contained in:
bzx
2026-02-09 16:41:50 +08:00
parent 6fb9ebf00a
commit 108bf8b194
6 changed files with 240 additions and 475 deletions

View File

@@ -4,18 +4,43 @@ using System.IO;
using System.Net;
using System.Text;
using System.Threading;
using System.Collections.Concurrent;
using System.Threading.Tasks;
using UnityEngine;
using Valheim;
[Serializable]
public class IntentMessage
{
public string intent;
}
[Serializable]
public class PlayingStatusResponse
{
public int code;
public ServerData data;
public string message;
}
[Serializable]
public class ServerData
{
public string gameName;
public int gameTotalTime;
public int currentPlayTime;
}
public class HttpServer : MonoBehaviour
{
private HttpListener listener;
private Thread listenThread;
private Thread serverThread;
private volatile bool isRunning;
// ❗不要用 +
private const string SERVER_URL = "http://127.0.0.1:12345/";
private const string SERVER_URL = "http://+:12345/";
// 子线程 → 主线程
private static ConcurrentQueue<NetMessage> messageQueue = new ConcurrentQueue<NetMessage>();
void Awake()
{
@@ -30,9 +55,10 @@ public class HttpServer : MonoBehaviour
// ✅ 后台启动
Task.Run(StartServer);
Debug.Log("Http,开始请求");
}
#region HTTP Server
private void StartServer()
{
try
@@ -42,12 +68,11 @@ public class HttpServer : MonoBehaviour
listener.Start();
isRunning = true;
listenThread = new Thread(ListenLoop)
serverThread = new Thread(ListenLoop)
{
IsBackground = true
};
listenThread.Start();
serverThread.Start();
Debug.Log($"✅ HTTP Server 启动成功:{SERVER_URL}");
}
@@ -59,37 +84,96 @@ public class HttpServer : MonoBehaviour
private void ListenLoop()
{
while (isRunning)
while (isRunning && listener.IsListening)
{
try
{
var context = listener.GetContext();
ProcessRequest(context);
ThreadPool.QueueUserWorkItem(ProcessRequest, context);
}
catch
catch (HttpListenerException)
{
break;
}
catch (Exception e)
{
Debug.LogError(e);
}
}
}
private void ProcessRequest(HttpListenerContext context)
private void ProcessRequest(object state)
{
var context = (HttpListenerContext)state;
var request = context.Request;
var response = context.Response;
response.AddHeader("Access-Control-Allow-Origin", "*");
response.AddHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
response.AddHeader("Access-Control-Allow-Headers", "Content-Type");
response.ContentType = "application/json; charset=utf-8";
try
{
string json =
$"{{\"code\":200,\"data\":{{\"gameName\":\"{GetGameName()}\"," +
$"\"gameTotalTime\":{GetTotalTime()},\"currentPlayTime\":{GetPlayTime()}}}}}";
if (request.HttpMethod == "POST")
{
string raw;
using (var reader = new StreamReader(
request.InputStream,
request.ContentEncoding ?? Encoding.UTF8))
{
raw = reader.ReadToEnd();
}
byte[] data = Encoding.UTF8.GetBytes(json);
response.OutputStream.Write(data, 0, data.Length);
Debug.Log($"📩 收到原始 JSON{raw}");
// 解析 intent
IntentMessage intentMsg = null;
try
{
intentMsg = JsonUtility.FromJson<IntentMessage>(raw);
}
catch (Exception e)
{
Debug.LogError("JSON 解析失败:" + e);
}
// 只处理 is_playing
if (intentMsg != null && intentMsg.intent == "is_playing")
{
var resp = new PlayingStatusResponse
{
code = 200,
data = new ServerData()
{
gameName = GetCurrentGameName(),
gameTotalTime = GetGameTotalTime(),
currentPlayTime = GetCurrentPlayTime()
},
message = "请求成功"
};
string json = JsonUtility.ToJson(resp);
Debug.LogError("数据:"+json);
byte[] data = Encoding.UTF8.GetBytes(json);
response.OutputStream.Write(data, 0, data.Length);
}
else
{
// 未知 intent
string err = "{\"code\":400,\"msg\":\"unknown intent\"}";
byte[] data = Encoding.UTF8.GetBytes(err);
response.OutputStream.Write(data, 0, data.Length);
}
response.Close();
return;
}
}
catch (Exception e)
{
Debug.LogError(e);
WriteResponse(response, 500, "error");
}
finally
{
@@ -97,24 +181,133 @@ public class HttpServer : MonoBehaviour
}
}
private string GetGameName()
private void WriteResponse(HttpListenerResponse response, int code, string msg)
{
return GameInit.Ins != null ? GameInit.Ins.gameId.ToString() : "unknown";
string json = $"{{\"code\":{code},\"msg\":\"{msg}\"}}";
byte[] data = Encoding.UTF8.GetBytes(json);
response.OutputStream.Write(data, 0, data.Length);
}
private int GetTotalTime()
#endregion
#region Unity Main Thread
void Update()
{
return GameInit.Ins != null ? Mathf.FloorToInt(GameManager .Ins.vistAllTime) : 0;
while (messageQueue.TryDequeue(out var msg))
{
Debug.Log($"📩 来自 [{msg.sender}] 指令 [{msg.command}]");
HandleMessage(msg);
}
}
private int GetPlayTime()
#endregion
#region Message Logic
[Serializable]
public class NetMessage
{
return GameInit.Ins != null ? GameManager.Ins.GetNowTime() : 0;
public string sender;
public string command;
}
private NetMessage ParseMessage(string raw)
{
if (string.IsNullOrEmpty(raw))
return null;
try
{
raw = raw.Replace("\"", "").Trim();
var parts = raw.Split(':');
if (parts.Length != 2)
{
Debug.LogWarning($"消息格式错误:{raw}");
return null;
}
return new NetMessage
{
sender = parts[0].Trim(),
command = parts[1].Trim()
};
}
catch (Exception e)
{
Debug.LogError($"解析失败:{raw}\n{e}");
return null;
}
}
private void HandleMessage(NetMessage msg)
{
switch (msg.command)
{
case "isStart":
OnStartCommand(msg.sender);
break;
default:
Debug.LogWarning($"未知指令:{msg.command}");
break;
}
}
private void OnStartCommand(string sender)
{
Debug.Log($"🚀 Start 指令来自:{sender}");
// ✅ 在这里安全调用 Unity API
// GameManager.Ins.QuitGame();
}
private string GetCurrentGameName()
{
return GameInit.Ins.gameId.ToString(); // 或你自己的 GameManager
}
private int GetGameTotalTime()
{
return Mathf.FloorToInt(GameInit.Ins.vistAllTime); // 举例1 小时(秒)
}
private int GetCurrentPlayTime()
{
return GameInit.Ins.GetNowTime();
}
#endregion
#region Shutdown
void OnDestroy()
{
isRunning = false;
listener?.Close();
StopServer();
}
private void StopServer()
{
isRunning = false;
try
{
listener?.Stop();
listener?.Close();
}
catch { }
try
{
if (serverThread != null && serverThread.IsAlive)
serverThread.Join(300);
}
catch { }
Debug.Log("🛑 HTTP Server 已关闭");
}
#endregion
}