加入http

This commit is contained in:
2025-10-11 13:48:01 +08:00
parent ad7409fd6e
commit febc0a6991
7 changed files with 216 additions and 85 deletions

View File

@@ -31,13 +31,18 @@ import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import com.unity3d.player.UnityPlayer;
public class Main extends Service {
private static final String TAG = "PineappleService";
private Handler handler = new Handler(Looper.getMainLooper());
// ================= 可靠UDP参数 =================
// ================= 可靠UDP 服务 =================
private static final int MAX_RETRIES = 3;
private static final int RETRY_INTERVAL = 200; // 重传间隔(ms)
private static final int ACK_TIMEOUT = 300; // ACK超时(ms)
@@ -60,6 +65,9 @@ public class Main extends Service {
// 本地监听端口
private int localPort = 8888;
private DatagramSocket udpSocket;
private boolean isRunning = false;
// 线程池
private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
private final ExecutorService networkExecutor = Executors.newFixedThreadPool(2);
@@ -122,6 +130,12 @@ public class Main extends Service {
}
}
// ================= Http 服务 =================
private ServerSocket httpServerSocket;
private ExecutorService httpExecutor = Executors.newFixedThreadPool(4);
private volatile boolean httpServerRunning = false;
private static final int HTTP_PORT = 6666;
// ================= 服务生命周期 =================
@Override
public IBinder onBind(Intent intent) {
@@ -168,6 +182,9 @@ public class Main extends Service {
scheduler.scheduleAtFixedRate(this::cleanupExpiredSessions,
5, 5, TimeUnit.MINUTES);
// 启动Http服务
startHttpReceiver();
// 启动应用包检测
getInstalledPackages();
@@ -446,17 +463,7 @@ public class Main extends Service {
String data = jsonMsg.optString("data");
Log.i(TAG, "intent-" + intent + " data-" + data);
if ("play".equals(intent)) {
org.json.JSONObject playMsg = new org.json.JSONObject(data);
String packageName = playMsg.optString("packageName");
Log.i(TAG, "执行播放指令,包名: " + packageName);
callUnity("AppManager", "LaunchApp", packageName);
} else if ("getPackageInfos".equals(intent)) {
Log.i(TAG, "执行获取所有包信息");
getInstalledPackages();
String escapedPackageNames = packageNames.replace("\"", "\\\""); // 转义引号
send2ControllerReliable("packageInfos", escapedPackageNames);
} else if ("playing".equals(intent)) {
if ("playing".equals(intent)) {
String name = jsonMsg.optString("name");
Log.i(TAG, "开始游玩" + name);
deviceInfo.status = 2;
@@ -589,10 +596,6 @@ public class Main extends Service {
}
}
// ================= UDP接收线程 =================
private DatagramSocket udpSocket;
private boolean isRunning = false;
private void startUdpReceiver() {
Log.i(TAG, "启动UDP接收器");
isRunning = true;
@@ -633,6 +636,124 @@ public class Main extends Service {
});
}
private void startHttpReceiver() {
Log.i(TAG, "启动HTTP接收器");
httpExecutor.execute(() -> {
try {
httpServerSocket = new ServerSocket(HTTP_PORT);
httpServerRunning = true;
Log.i(TAG, "HTTP服务器启动端口: " + HTTP_PORT);
while (httpServerRunning) {
try {
Socket clientSocket = httpServerSocket.accept();
httpExecutor.execute(() -> handleHttpRequest(clientSocket));
} catch (IOException e) {
if (httpServerRunning) {
Log.e(TAG, "处理HTTP请求时出错: " + e.getMessage());
}
}
}
} catch (IOException e) {
Log.e(TAG, "无法启动HTTP服务器: " + e.getMessage());
}
});
}
private void handleHttpRequest(Socket clientSocket) {
try {
java.io.BufferedReader in = new java.io.BufferedReader(
new java.io.InputStreamReader(clientSocket.getInputStream()));
// 解析请求行
String requestLine = in.readLine();
if (requestLine == null || requestLine.isEmpty()) {
clientSocket.close();
return;
}
Log.i(TAG, "收到HTTP请求: " + requestLine);
// 解析请求头
Map<String, String> headers = new HashMap<>();
String headerLine;
int contentLength = 0;
while ((headerLine = in.readLine()) != null && !headerLine.isEmpty()) {
String[] parts = headerLine.split(":", 2);
if (parts.length == 2) {
headers.put(parts[0].trim(), parts[1].trim());
if ("Content-Length".equalsIgnoreCase(parts[0].trim())) {
contentLength = Integer.parseInt(parts[1].trim());
}
}
}
// 读取请求体(如果有)
StringBuilder body = new StringBuilder();
if (contentLength > 0) {
char[] buffer = new char[contentLength];
int totalRead = 0;
while (totalRead < contentLength) {
int read = in.read(buffer, totalRead, contentLength - totalRead);
if (read == -1)
break;
totalRead += read;
}
body.append(buffer, 0, totalRead);
}
Log.i(TAG, "请求体: " + body.toString());
// 根据请求路径和方法处理请求
String responseContent = "";
int responseCode = 200;
// 解析请求体中的JSON数据
try {
org.json.JSONObject jsonBody = new org.json.JSONObject(body.toString());
String intent = jsonBody.optString("intent");
if ("getPackageInfos".equals(intent)) {
Log.i(TAG, "执行获取所有包信息");
getInstalledPackages(); // 更新包信息
responseContent = packageNames; // 使用最新的包信息作为响应内容
} else if ("playFilm".equals(intent)) {
String packageName = jsonBody.optString("packageName");
Log.i(TAG, "执行播放: " + packageName);
callUnity("AppManager", "LaunchApp", packageName);
responseContent = "{\"status\":\"success\",\"message\":\"执行播放\"}";
} else {
responseContent = "{\"status\":\"fail\",\"message\":\"未知意图\"}";
}
} catch (org.json.JSONException e) {
Log.e(TAG, "解析请求体JSON失败: " + e.getMessage());
responseContent = "{\"status\":\"fail\",\"message\":\"解析失败\"}";
responseCode = 400;
}
// 发送响应
OutputStream out = clientSocket.getOutputStream();
String httpResponse = "HTTP/1.1 " + responseCode + " OK\r\n" +
"Content-Type: application/json\r\n" +
"Access-Control-Allow-Origin: *\r\n" +
"Content-Length: " + responseContent.getBytes().length + "\r\n" +
"\r\n" +
responseContent;
out.write(httpResponse.getBytes());
out.flush();
out.close();
clientSocket.close();
} catch (IOException e) {
Log.e(TAG, "处理HTTP客户端连接时出错: " + e.getMessage());
try {
clientSocket.close();
} catch (IOException ioException) {
Log.e(TAG, "关闭客户端连接时出错: " + ioException.getMessage());
}
}
}
// ================= Unity通信方法 =================
public void callUnity(String gameObjectName, String methodName, String message) {
try {