使用hamibot 如果要用websocket🔗后台 完整的代码该怎么写
使用方案3的话 完整的步骤 我该怎么做 如何导包呢
if(!safeImportokHttp()){toastLog('此设备不支持 websocket 功能');
return null;
let client = new okHttpclient();
别人实现方式 为什么可以用
回答
文档地址 https://docs.hamibot.com/
Hamibot 当前运行环境基于 Rhino 1.7.15,不支持原生 WebSocket API。JavaScript 引擎本身没有提供 WebSocket 全局对象,因此无法直接使用浏览器或 Node.js 中的 WebSocket 写法。
但你可以通过 HTTP 长轮询 或 Socket.IO(基于 Java 插件) 实现类似后台通信功能。若你确实需要 WebSocket 功能,可以通过以下方式实现:
✅ 方案一:使用 Java Socket(推荐用于长连接通信)
虽然 Hamibot 不支持 WebSocket,但可以使用 Java 的 java.net.Socket 来建立 TCP 连接,自行实现协议逻辑。
// 文档地址 https://docs.hamibot.com/
// 示例:使用 Java Socket 实现与 WebSocket 服务端类似的连接(需服务端兼容)
threads.start(function () {
try {
// 创建 Socket 连接(替换为你的服务器地址和端口)
var InetAddress = java.net.InetAddress;
var Socket = java.net.Socket;
var socket = new Socket(InetAddress.getByName('your-websocket-server.com'), 8080);
// 获取输入输出流
var BufferedReader = java.io.BufferedReader;
var InputStreamReader = java.io.InputStreamReader;
var PrintWriter = java.io.PrintWriter;
var reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), 'UTF-8'));
var writer = new PrintWriter(socket.getOutputStream(), true);
// 发送握手请求(模拟 WebSocket 升级头,根据实际服务端要求调整)
writer.println('GET /chat HTTP/1.1');
writer.println('Host: your-websocket-server.com');
writer.println('Upgrade: websocket');
writer.println('Connection: Upgrade');
writer.println('Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==');
writer.println('Sec-WebSocket-Version: 13');
writer.println('');
// 接收消息循环
while (socket.isConnected() && !socket.isClosed()) {
var line = reader.readLine();
if (line !== null) {
log('收到消息: ' + line);
// 在这里处理收到的数据
hamibot.postMessage('data: ' + line);
} else {
break;
}
}
reader.close();
writer.close();
socket.close();
} catch (e) {
log('Socket 错误: ' + e.message);
}
});
⚠️ 注意:这只是一个原始 TCP 连接示例,如需真正对接 WebSocket 协议,你需要自己实现 RFC6455 握手和帧解析,复杂度较高。
✅ 方案二:使用 HTTP 轮询(简单可靠)
如果你只是想从远程服务器接收指令或发送状态,建议用 http.request 做短轮询。
// 文档地址 https://docs.hamibot.com/
// 每隔 3 秒向服务器查询是否有新任务
setInterval(function () {
http.request({
method: 'GET',
url: 'https://your-api.com/api/polling?device_id=' + hamibot.deviceId,
headers: {
'Content-Type': 'application/json'
}
}, function (res, err) {
if (err) {
log('请求失败: ' + err);
return;
}
if (res.statusCode === 200) {
var body = res.body.string();
var data = JSON.parse(body);
log('收到指令: ' + JSON.stringify(data));
// 执行相应操作
if (data.action === 'click') {
click(data.x, data.y);
}
}
});
}, 3000);
✅ 方案三:使用第三方库(高级,需打包 Jar)
你可以将一个支持 WebSocket 的 Java 库(如 Tyrus 或 OkHttp)打包成 .jar 文件,导入 Hamibot 脚本中使用。
例如使用 OkHttp(需预先导入 jar):
// 导入 OkHttp(仅当已添加对应 jar 包时可用)
var OkHttpClient = Packages.okhttp3.OkHttpClient;
var Request = Packages.okhttp3.Request;
var WebSocket = Packages.okhttp3.WebSocket;
var WebSocketListener = Packages.okhttp3.WebSocketListener;
var client = new OkHttpClient();
var listener = new WebSocketListener({
onOpen: function(webSocket, response) {
log('WebSocket 已连接');
webSocket.send('Hello Server
***
# 补充回答 1
文档地址 https://docs.hamibot.com/
Hamibot **不支持直接导入外部 JAR 包** 或使用第三方 Java 库(如 OkHttp、Tyrus 等),因此你无法像在标准 Android 开发环境中那样通过添加 `.jar` 文件来扩展功能。
### ❌ 为什么方案三(导包 + WebSocket)不可行?
1. **无自定义类加载机制**:Hamibot 的脚本运行环境基于 Rhino,并封装在固定 APK 中,不允许动态加载外部 `.jar` 或 `.dex` 文件。
2. **无法引入第三方库**:即使你有 `okhttp.jar`,也无法通过 `require()`、`import` 或任何方式将其注入脚本上下文。
3. **Java 包限制**:脚本中只能访问 Hamibot 主程序已包含的 Java 类(即 Android SDK 和少量内置库),不能扩展新的依赖。
这意味着:
> 即使你想使用 OkHttp 的 `WebSocket` 功能,只要 Hamibot 安装包本身没自带这个库,你就**完全无法使用它**。
---
### ✅ 正确做法:改用 HTTP 长轮询或服务端适配
既然无法导入外部包,你应该选择兼容 Hamibot 现有能力的通信方式。以下是推荐替代方案:
---
#### ✅ 方案 A:使用 `http.request` 实现轻量级后台通信(最稳定)
适用于从远程服务器接收指令、上报状态等场景。
```javascript
// 文档地址 https://docs.hamibot.com/
// 每 5 秒轮询一次服务器
setInterval(function () {
http.request({
method: 'GET',
url: 'https://your-server.com/api/task?device=' + encodeURIComponent(hamibot.deviceId),
headers: {
'Authorization': 'Bearer your-token'
}
}, function (res, err) {
if (err) {
log('请求失败: ' + err);
return;
}
if (res.statusCode === 200) {
var body = res.body.string();
try {
var task = JSON.parse(body);
log('执行任务: ' + task.action);
if (task.action === 'click') {
click(task.x, task.y);
} else if (task.action === 'toast') {
toast(task.text);
}
} catch (e) {
log('解析失败: ' + e.message);
}
}
});
}, 5000);
🔧 服务端示例(Node.js + Express):
app.get('/api/task', (req, res) => { // 根据 deviceId 返回对应指令 res.json({ action: 'click', x: 500, y: 800 }); });
✅ 方案 B:使用 Server-Sent Events(SSE)模拟推送(进阶)
如果你希望“近实时”获取消息,可以用 SSE 协议,它是基于 HTTP 流的单向推送技术,比轮询更高效。
// 文档地址 https://docs.hamibot.com/
http.request({
method: 'GET',
url: 'https://your-server.com/sse/events',
headers: {
'Accept': 'text/event-stream'
}
}, function (res, err) {
if (err) {
log('连接失败: ' + err);
return;
}
var reader = new java.io.BufferedReader(new java.io.InputStreamReader(res.body.inputStream));
var line;
while ((line = reader.readLine()) != null) {
if (line.startsWith('data:')) {
var data = line.substring(5).trim();
log('收到事件: ' + data);
try {
var task = JSON.parse(data);
// 执行任务逻辑
if (task.type === 'swipe') {
swipe(task.x1, task.y1, task.x2, task.y2, 500);
}
} catch (e) {
log('处理失败: ' + e.message);
}
}
}
reader.close();
});
⚠️ 注意:SSE 是单向通信,仅服务端 → 客户端,适合通知类场景。
🛠 总结:你该怎么做?
| 目标 | 推荐方案 |
|---|---|
| 发送设备状态、日志 | 使用 http.post(url, data) 主动上传 |
| 接收远程指令 | 使用 setInterval + http.request 轮询 |
| 实时性要求高 | 使用 SSE(Server-Sent Events)流式拉取 |
| 双向通信 / |
补充回答 2
文档地址 https://docs.hamibot.com/
你提到的代码:
if (!safeImportOkHttp()) {
toastLog('此设备不支持 websocket 功能');
return null;
}
let client = new OkHttpClient();
这种写法在标准 Hamibot 环境中是无法正常运行的,除非满足以下特殊条件之一:
✅ 原因分析:别人“能用”是因为他们使用了 定制版 Hamibot 或插件化环境
1. 使用的是修改版(魔改版)Hamibot
- 某些第三方分发的 Hamibot 安装包(非官方 hamibot.com 发布)可能已被开发者植入额外的 Java 库(如 OkHttp、WebSocket 支持等)。
- 这些版本在底层预加载了
okhttp.jar、okio.jar等依赖,并暴露OkHttpClient到脚本上下文中。 - 因此
new OkHttpClient()才能成功实例化。
2. safeImportOkHttp() 是自定义函数,用于检测类是否存在
function safeImportOkHttp() {
try {
Packages.okhttp3.OkHttpClient;
return true;
} catch (e) {
return false;
}
}
- 如果
Packages.okhttp3.OkHttpClient存在,说明当前环境已包含该库。 - 这个类默认在官方 Hamibot 中不存在,所以这个函数通常会返回
false。
3. 可能是企业定制部署或本地打包集成
- 极少数情况下,企业用户与 Hamibot 团队合作进行私有化部署,将特定 JAR 包嵌入到 APK 内部。
- 此时可以在脚本中直接调用高级网络功能。
❌ 官方 Hamibot 不支持的原因
| 原因 | 说明 |
|---|---|
| 安全限制 | 动态导入外部库可能导致代码注入、权限越权等风险。 |
| 兼容性问题 | 不同设备 Android 版本差异大,引入复杂库易导致崩溃。 |
| 维护成本高 | 脚本依赖外部 JAR 后难以统一调试和更新。 |
🔴 所以:官方发布的 Hamibot 版本(从 hamibot.com 下载)默认不包含 OkHttp 或任何 WebSocket 实现。
✅ 你可以怎么做?(合法且稳定的方式)
✔️ 推荐方案:使用 http.request + HTTP 轮询(兼容所有设备)
// 文档地址 https://docs.hamibot.com/
setInterval(function () {
http.request({
method: 'GET',
url: 'https://your-api.com/v1/command?device=' + hamibot.deviceId,
headers: {
'Authorization': 'Bearer xxx'
}
}, function (res, err) {
if (err) {
log('请求失败: ' + err);
return;
}
if (res.statusCode === 200) {
let data = JSON.parse(res.body.string());
if (data.action === 'click') {
click(data.x, data.y);
} else if (data.action === 'swipe') {
swipe(data.x1, data.y1, data.x2, data.y2, 500);
}
}
});
}, 3000); // 每3秒查一次
✔️ 高级替代:通过 PC 中转实现 WebSocket 双向通信
你可以写一个 Node.js 服务作为中间层:
- 设备通过
http.request上报状态并拉取指令。 - PC 侧用真正的 WebSocket 连接云端。
- 中间服务做协议转换。
这样既利用了 Hamibot 的稳定性,又实现了“伪实时”控制。
🛑 结论
别人能用
OkHttpClient,是因为他们用了非官方、定制化或魔改过的 Hamibot 环境。
而在你使用的官方标准版 Hamibot 上,这类代码会报错,因为 Packages.okhttp3.OkHttpClient 根本不存在。
✅ 最佳实践建议
- 不要依赖未公开支持的 Java 第三方库。
- 使用
http.request实现远程通信是最可靠、跨设备兼容的方式。 - 如需更高实时性,可结合 SSE(Server-Sent Events)流式拉取。
- 若你有特殊需求(如内网 WebSocket 集成),建议联系 Hamib