B2B网络软件
标题:
WebSocket调试okhttp版
[打印本页]
作者:
YYPOST群发软件
时间:
1 小时前
标题:
WebSocket调试okhttp版
WebSocket调试okhttp版
1.png
(1.46 MB, 下载次数: 7)
下载附件
1 小时前
上传
/**
* WebSocket 屏幕截图传输 - 本地调试版(okhttp3 版)
*
* 配套 WebSocket测试服务器.py 使用
*
* 使用方法:
*
* 确认下面 serverUrl 里的 IP 是 PC 的局域网 IP
* 手机和 PC 在同一 WiFi 局域网
* AIWROK 里运行本脚本
*
* 本次使用 okhttp3 的 WebSocketListener(非 AIWROK 原生 websocket 对象)
* 已在 AIWROK v3.7.81 实际跑通
*/
// ========== 导入 okhttp3(AIWROK 自带这些 Java 类) ==========
importClass(Packages.okhttp3.OkHttpClient);
importClass(Packages.okhttp3.Request);
importClass(Packages.okhttp3.WebSocketListener);
importClass(Packages.java.util.concurrent.TimeUnit);
print.log("===== WebSocket 屏幕截图传输(okhttp3 版)开始 =====");
// ========== 配置 ==========
var config = {
serverUrl: "192.168.10.107:8886", // ← 改成 PC 局域网 IP:端口
screenshotInterval: 5000, // 截图间隔(毫秒)
reconnectInterval: 2500, // 断线重试间隔(毫秒)
maxReconnectAttempts: 12, // 最多重试次数
connectTimeoutSec: 15, // 握手超时(秒)
readTimeoutSec: 30, // 读超时(秒)
runDuration: 30000 // 脚本总运行时长(毫秒)
};
// ========== 全局状态 ==========
var okHttpClient = null; // OkHttpClient
var webSocket = null; // 当前 WebSocket 对象
var timer = null; // 定时器
var state = {
connected: false, // 是否已连接
err: null, // 最近错误
closeReason: null, // 关闭原因
reconnectCount: 0, // 已重连次数
saveDir: "", // 由服务器 WELCOME 带出
saveUrlPrefix: "", // file:/// 前缀
totalSent: 0, // 已尝试发送的图片数
totalConfirmed: 0 // 服务器确认收到的图片数
};
// ========== 工具:解析服务器结构化消息 ==========
function parseServerMessage(rawStr) {
if (typeof rawStr !== "string") { try { rawStr = String(rawStr); } catch (e) { rawStr = "" + rawStr; } }
var result = { type: "UNKNOWN", raw: rawStr };
if (rawStr.indexOf("WELCOME|") === 0) {
result.type = "WELCOME";
var parts = rawStr.split("|");
result.id = parts[1] || "";
for (var i = 2; i < parts.length; i++) {
var idx = parts[i].indexOf("=");
if (idx > 0) result[parts[i].substring(0, idx)] = parts[i].substring(idx + 1);
}
} else if (rawStr.indexOf("IMG_SAVED|") === 0) {
result.type = "IMG_SAVED";
var p = rawStr.split("|");
result.seq = p[1] || "";
result.sizeTxt = p[2] || "";
result.absPath = p[3] || "";
result.fileUrl = p[4] || "";
} else if (rawStr.indexOf("IMG_FAIL|") === 0) {
result.type = "IMG_FAIL";
} else if (rawStr.indexOf("ECHO|") === 0) {
result.type = "ECHO";
result.text = rawStr.substring("ECHO|".length);
}
return result;
}
// ========== 释放资源(每次重连前清理旧 client) ==========
function shutdownClient() {
if (webSocket) {
try { webSocket.close(1000, "shutdown"); } catch (e) {}
webSocket = null;
}
if (okHttpClient) {
try { okHttpClient.dispatcher().executorService().shutdownNow(); } catch (e) {}
okHttpClient = null;
}
}
// ========== 建立连接(okhttp3 方案) ==========
function connect() {
// 先清旧资源
shutdownClient();
state.connected = false;
state.err = null;
// 构造新 OkHttpClient
okHttpClient = new OkHttpClient.Builder()
.pingInterval(10, TimeUnit.SECONDS)
.connectTimeout(config.connectTimeoutSec, TimeUnit.SECONDS)
.readTimeout(config.readTimeoutSec, TimeUnit.SECONDS)
.build();
// 构造 listener
var listener = new WebSocketListener({
onOpen: function (wsObj, response) {
state.connected = true;
state.err = null;
state.reconnectCount = 0;
print.log("WS: onOpen");
printl("✅ 连接成功(onOpen)");
startScreenshotLoop();
},
onMessage: function (wsObj, message) {
var raw;
try { raw = String(message); } catch (e) { raw = ""; }
print.log("WS: onMessage len=" + raw.length);
var parsed = parseServerMessage(raw);
if (parsed.type === "WELCOME") {
state.saveDir = parsed.save_dir || "";
state.saveUrlPrefix = parsed.save_file_url || "";
printl("📩 WELCOME 客户端" + parsed.id);
if (state.saveDir) {
printl("📁 保存目录: " + state.saveDir);
printl("🔗 目录URL: " + state.saveUrlPrefix);
}
} else if (parsed.type === "IMG_SAVED") {
state.totalConfirmed++;
printl("💾 服务器已保存图片 " + parsed.seq);
printl(" 大小: " + parsed.sizeTxt);
printl(" 路径: " + parsed.absPath);
printl(" 🔗 " + parsed.fileUrl);
} else if (parsed.type === "IMG_FAIL") {
printl("🔴 服务器保存图片失败: " + parsed.raw);
} else if (parsed.type === "ECHO") {
printl("📩 回显: " + parsed.text.substring(0, 150));
} else {
// 未知格式(旧版服务器返回)
printl("📩 收到: " + raw.substring(0, 200) + (raw.length > 200 ? "..." : ""));
}
},
onClosed: function (wsObj, code, reason) {
state.connected = false;
state.closeReason = reason || "closed";
print.log("WS: onClosed code=" + code + " reason=" + reason);
printl("🔌 连接关闭(onClosed code=" + code + ")");
stopScreenshotLoop();
scheduleReconnect();
},
onFailure: function (wsObj, throwable, response) {
state.connected = false;
state.err = (throwable ? String(throwable.getMessage()) : "unknown_failure");
print.log("WS: onFailure " + state.err);
printl("❌ 连接错误(onFailure): " + state.err);
stopScreenshotLoop();
scheduleReconnect();
}
});
// 发起连接
var url = "ws://" + config.serverUrl;
printl("正在连接: " + url + "(" + config.connectTimeoutSec + " 秒超时)");
try {
var request = new Request.Builder().url(url).build();
webSocket = okHttpClient.newWebSocket(request, listener);
} catch (e) {
state.err = String(e.message);
printl("❌ newWebSocket 抛异常: " + state.err);
scheduleReconnect();
}
// 同步等最多 connectTimeoutSec + 5 秒看事件
var waited = 0;
while (!state.connected && !state.err && waited < (config.connectTimeoutSec + 5) * 1000) {
sleep.millisecond(100);
waited += 100;
}
if (!state.connected && !state.err) {
state.err = "连接超时(" + (config.connectTimeoutSec + 5) + " 秒内无 onOpen/onFailure)";
printl("❌ " + state.err);
scheduleReconnect();
}
}
// ========== 重连调度 ==========
function scheduleReconnect() {
if (state.reconnectCount >= config.maxReconnectAttempts) {
printl("🛑 已达到最大重连次数 " + config.maxReconnectAttempts + ",停止");
return;
}
state.reconnectCount++;
printl("⏱️ 重连 " + state.reconnectCount + "/" + config.maxReconnectAttempts + "," + (config.reconnectInterval / 1000).toFixed(1) + " 秒后...");
shutdownClient();
setTimeout(function () {
connect();
}, config.reconnectInterval);
}
// ========== 截一张图并发送 ==========
function sendOne() {
if (!state.connected || !webSocket) {
print.log("跳过截图:未连接");
return;
}
try {
print.log("截取屏幕...");
printl("📸 截图中...");
var bitmap = screen.screenShotFull();
if (!bitmap) { printl("❌ 截图失败(返回 null)"); return; }
print.log("转 Base64...");
var base64 = "" + bitmap.toBase64(); // Java ByteString → JS 字符串,必须用 ""+
if (!base64) { printl("❌ Base64 为空"); return; }
var chars = base64.length;
var estKB = Math.round(chars * 0.75 / 1024);
printl("📦 图片大小: " + chars + " 字符(约 " + estKB + " KB)");
try { bitmap.recycle(); } catch (e) {}
state.totalSent++;
printl("📤 发送图片 #" + state.totalSent + " ...");
webSocket.send(base64);
printl("✅ 图片 #" + state.totalSent + " 已投递(" + estKB + " KB)");
} catch (e) {
printl("❌ sendOne 异常: " + e.message);
print.log("sendOne: " + e.message);
}
}
// ========== 定时截图循环 ==========
function startScreenshotLoop() {
if (timer) { try { clearInterval(timer); } catch (e) {} timer = null; }
print.log("定时截图循环启动, 间隔 " + config.screenshotInterval + "ms");
printl("⏰ 定时截图已启动(间隔 " + (config.screenshotInterval / 1000) + " 秒)");
// 首张立即来
setTimeout(function () { sendOne(); }, 300);
timer = setInterval(function () {
if (state.connected && webSocket) sendOne();
}, config.screenshotInterval);
}
function stopScreenshotLoop() {
if (timer) {
try { clearInterval(timer); } catch (e) {}
timer = null;
print.log("停止定时截图循环");
}
}
// ========== 关闭清理 ==========
function cleanup() {
stopScreenshotLoop();
shutdownClient();
state.connected = false;
printl("🔌 资源已清理");
}
// ========== 主程序 ==========
function main() {
try {
printl("========================================");
printl(" WebSocket 屏幕截图传输 - okhttp3 版");
printl(" 服务器: " + config.serverUrl);
printl(" 截图间隔: " + (config.screenshotInterval / 1000) + " 秒");
printl(" 总运行: " + (config.runDuration / 1000) + " 秒");
printl(" 最大重连: " + config.maxReconnectAttempts + " 次");
printl("========================================");
printl("ℹ️ 请确认 PC 已运行: python WebSocket测试服务器.py");
connect();
print.log("倒计时 " + (config.runDuration / 1000) + " 秒...");
printl("⏳ 运行 " + (config.runDuration / 1000) + " 秒后自动结束");
sleep.millisecond(config.runDuration);
cleanup();
printl("");
printl("===== 执行结束 =====");
printl(" 尝试发送: " + state.totalSent + " 张");
printl(" 服务器确认: " + state.totalConfirmed + " 张");
if (state.saveDir) printl(" PC 保存目录: " + state.saveDir);
print.log("===== 屏幕截图传输结束, 发送 " + state.totalSent + " 张 =====");
} catch (e) {
print.log("主程序异常: " + e.message);
printl("❌ 程序错误: " + e.message);
try { cleanup(); } catch (e2) {}
}
}
main();
复制代码
欢迎光临 B2B网络软件 (http://bbs.niubt.cn/)
Powered by Discuz! X3.2