Skip to content

Commit 1563246

Browse files
committed
add cdpclient
1 parent 24e93c7 commit 1563246

File tree

3 files changed

+136
-6
lines changed

3 files changed

+136
-6
lines changed
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
package org.m2sec.core.outer;
2+
3+
import com.google.gson.reflect.TypeToken;
4+
import lombok.extern.slf4j.Slf4j;
5+
import org.java_websocket.client.WebSocketClient;
6+
import org.java_websocket.handshake.ServerHandshake;
7+
import org.m2sec.core.utils.FactorUtil;
8+
import org.m2sec.core.utils.HttpUtil;
9+
import org.m2sec.core.utils.JsonUtil;
10+
11+
import java.lang.reflect.Type;
12+
import java.util.HashMap;
13+
import java.util.Map;
14+
import java.util.concurrent.*;
15+
16+
/**
17+
* @author: outlaws-bai
18+
* @date: 2024/10/7 14:52
19+
* @description:
20+
*/
21+
@Slf4j
22+
public class CdpClient {
23+
private final WebSocketClient webSocketClient;
24+
// 用于存储请求UUID和对应的CompletableFuture,以便并发请求处理
25+
private final Map<Integer, CompletableFuture<Object>> requestMap = new ConcurrentHashMap<>();
26+
27+
// 构造函数,接收WebSocket URL并连接
28+
public CdpClient(String websocketUrl){
29+
this.webSocketClient = new WebSocketClient(HttpUtil.parseUri(websocketUrl)) {
30+
@Override
31+
public void onOpen(ServerHandshake handshakeData) {
32+
log.info("WebSocket connect success.");
33+
}
34+
35+
@Override
36+
public void onMessage(String message) {
37+
log.info("WebSocket receive message: " + message);
38+
handleMessage(message);
39+
}
40+
41+
@Override
42+
public void onClose(int code, String reason, boolean remote) {
43+
log.info("WebSocket connect close: " + reason);
44+
}
45+
46+
@Override
47+
public void onError(Exception ex) {
48+
log.error("WebSocket error: " + ex.getMessage(), ex);
49+
}
50+
};
51+
// 连接 WebSocket
52+
try {
53+
this.webSocketClient.connectBlocking();
54+
} catch (InterruptedException e) {
55+
throw new RuntimeException(e);
56+
}
57+
}
58+
59+
// 处理接收到的消息
60+
private void handleMessage(String message) {
61+
// 解析消息,获取对应的请求ID
62+
Type mapType = new TypeToken<Map<String, Object>>() {}.getType();
63+
Map<String, Object> response = JsonUtil.fromJsonStr(message, mapType);
64+
Integer idStr = ((Double)response.get("id")).intValue();
65+
66+
CompletableFuture<Object> future = requestMap.get(idStr);
67+
68+
// 如果找到对应的Future,完成它并从map中移除
69+
if (future != null) {
70+
future.complete(message);
71+
requestMap.remove(idStr);
72+
}
73+
}
74+
75+
// 发送CDP指令,执行JavaScript代码并返回结果 (异步)
76+
public CompletableFuture<Object> executeCommand(String jsCode) {
77+
Integer requestId = FactorUtil.randomInteger(8);
78+
79+
// 构造请求参数
80+
Map<String, Object> params = new HashMap<>();
81+
params.put("expression", jsCode);
82+
83+
Map<String, Object> command = new HashMap<>();
84+
command.put("id", requestId); // 使用UUID作为请求ID
85+
command.put("method", "Runtime.evaluate");
86+
command.put("params", params);
87+
88+
// 创建一个CompletableFuture并放入map中
89+
CompletableFuture<Object> resultFuture = new CompletableFuture<>();
90+
requestMap.put(requestId, resultFuture);
91+
92+
// 发送消息
93+
webSocketClient.send(JsonUtil.toJsonStr(command));
94+
95+
// 返回 future,调用方可以等待结果
96+
return resultFuture;
97+
}
98+
99+
public Object aexec(String jsCode){
100+
return aexec(jsCode, 5);
101+
}
102+
103+
// 同步执行CDP指令,等待执行完成并返回结果
104+
public Object aexec(String jsCode, int timeout) {
105+
// 调用异步的 executeCommand 函数,等待并返回结果
106+
CompletableFuture<Object> future = executeCommand(jsCode);
107+
try {
108+
return future.get(timeout, TimeUnit.SECONDS); // 等待执行完成
109+
} catch (InterruptedException | ExecutionException | TimeoutException e) {
110+
throw new RuntimeException(e);
111+
}
112+
}
113+
114+
// 关闭WebSocket连接
115+
public void close() {
116+
webSocketClient.close();
117+
}
118+
}

src/main/java/org/m2sec/core/utils/FactorUtil.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,15 @@ public class FactorUtil {
1515

1616
public static String randomString(int length) {
1717
@SuppressWarnings("SpellCheckingInspection") String CHARACTERS = "abcdefghijklmnopqrstuvwxyz0123456789";
18+
return random(length, CHARACTERS);
19+
}
20+
21+
public static Integer randomInteger(int length) {
22+
String CHARACTERS = "0123456789";
23+
return Integer.valueOf(random(length, CHARACTERS));
24+
}
25+
26+
private static String random(int length, String CHARACTERS) {
1827
SecureRandom RANDOM = new SecureRandom();
1928
if (length <= 0) {
2029
throw new IllegalArgumentException("Length must be greater than 0");

src/main/java/org/m2sec/core/utils/HttpUtil.java

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,10 @@
1212
import org.m2sec.core.enums.Method;
1313
import org.m2sec.core.enums.Protocol;
1414
import org.m2sec.core.models.*;
15-
import org.python.jline.internal.Log;
16-
1715
import javax.annotation.Nullable;
1816
import java.io.*;
1917
import java.lang.reflect.InvocationTargetException;
20-
import java.net.MalformedURLException;
21-
import java.net.URL;
22-
import java.net.URLDecoder;
23-
import java.net.URLEncoder;
18+
import java.net.*;
2419
import java.nio.charset.StandardCharsets;
2520
import java.util.*;
2621

@@ -40,6 +35,14 @@ public static URL parseUrl(String urlStr) {
4035
}
4136
}
4237

38+
public static URI parseUri(String urlStr) {
39+
try {
40+
return new URI(urlStr);
41+
} catch (URISyntaxException e) {
42+
throw new RuntimeException(e);
43+
}
44+
}
45+
4346
public static boolean urlIsSecure(URL url) {
4447
return url.getProtocol().equals(Protocol.HTTPS.toRaw());
4548
}

0 commit comments

Comments
 (0)