From 1cc127ff9b36865c89982a829af743c07073a6bb Mon Sep 17 00:00:00 2001 From: joewulf Date: Sat, 25 Oct 2025 15:43:41 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=94=AF=E6=8C=81=E8=B0=83?= =?UTF-8?q?=E8=AF=95=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../starter/MagicAPIAutoConfiguration.java | 2 + .../core/handler/MagicDebugHandler.java | 61 +++++++++++++++++-- .../service/FunctionMagicDynamicRegistry.java | 6 ++ 3 files changed, 63 insertions(+), 6 deletions(-) diff --git a/magic-api-spring-boot-starter/src/main/java/org/ssssssss/magicapi/spring/boot/starter/MagicAPIAutoConfiguration.java b/magic-api-spring-boot-starter/src/main/java/org/ssssssss/magicapi/spring/boot/starter/MagicAPIAutoConfiguration.java index fb9681c0..811fb1ab 100644 --- a/magic-api-spring-boot-starter/src/main/java/org/ssssssss/magicapi/spring/boot/starter/MagicAPIAutoConfiguration.java +++ b/magic-api-spring-boot-starter/src/main/java/org/ssssssss/magicapi/spring/boot/starter/MagicAPIAutoConfiguration.java @@ -325,6 +325,8 @@ public class MagicAPIAutoConfiguration implements WebMvcConfigurer, WebSocketCon configuration.setEditorConfig(properties.getEditorConfig()); configuration.setWorkspace(magicResource); configuration.setAuthorizationInterceptor(authorizationInterceptorProvider.getObject()); + // 调试超时 + MagicDebugHandler.setDebugTimeout(configuration.getDebugTimeout()); // 注册函数 this.magicFunctionsProvider.getIfAvailable(Collections::emptyList).forEach(JavaReflection::registerFunction); // 向页面传递配置信息时不传递用户名密码,增强安全性 diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/core/handler/MagicDebugHandler.java b/magic-api/src/main/java/org/ssssssss/magicapi/core/handler/MagicDebugHandler.java index 0bcff062..ac57e3f4 100644 --- a/magic-api/src/main/java/org/ssssssss/magicapi/core/handler/MagicDebugHandler.java +++ b/magic-api/src/main/java/org/ssssssss/magicapi/core/handler/MagicDebugHandler.java @@ -5,12 +5,16 @@ import org.ssssssss.magicapi.core.annotation.Message; import org.ssssssss.magicapi.core.config.MessageType; import org.ssssssss.magicapi.core.config.WebSocketSessionManager; import org.ssssssss.magicapi.core.context.MagicConsoleSession; +import org.ssssssss.magicapi.utils.JsonUtils; import org.ssssssss.script.MagicScriptDebugContext; -import java.util.Collections; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; import java.util.stream.Stream; +import static org.ssssssss.magicapi.core.config.MessageType.BREAKPOINT; + /** * WebSocket Debug 处理器 @@ -18,33 +22,78 @@ import java.util.stream.Stream; * @author mxd */ public class MagicDebugHandler { + public static final Map DEBUG_CONTEXTS = new ConcurrentHashMap<>(); + + private static Integer debugTimeout = 60; + + public static void setDebugTimeout(int timeout) { + debugTimeout = timeout; + } + + public static MagicScriptDebugContext getDebugContext(String scriptId) { + return DEBUG_CONTEXTS.get(scriptId); + } + private List getBreakpoints(String breakpoints) { + List intBreakpoints = new LinkedList<>(); + if (StringUtils.isNotBlank(breakpoints)) { + intBreakpoints = Stream.of(breakpoints.split("\\|")).map(Integer::valueOf).collect(Collectors.toList()); + } + return intBreakpoints; + } - /** + + /** * 设置断点 * 当本机没有该Session时,通知其他机器处理 */ @Message(MessageType.SET_BREAKPOINT) public boolean setBreakPoint(MagicConsoleSession session, String scriptId, String breakpoints) { MagicScriptDebugContext context = WebSocketSessionManager.findMagicScriptContext(session.getClientId() + scriptId); + List intBreakpoints = getBreakpoints(breakpoints); if (context != null) { - context.setBreakpoints(Stream.of(breakpoints.split(",")).map(Integer::valueOf).collect(Collectors.toList())); + context.setBreakpoints(intBreakpoints); return true; - } + } else { + setDebugBreakPoints(session, scriptId, intBreakpoints); + } return false; } - /** + private void setDebugBreakPoints(MagicConsoleSession session, String scriptId, List intBreakpoints) { + MagicScriptDebugContext magicScriptDebugContext = DEBUG_CONTEXTS.computeIfAbsent(scriptId, ($scriptId) -> { + MagicScriptDebugContext debugContext = new MagicScriptDebugContext(new LinkedList<>()); + + String clientId = session.getClientId(); + debugContext.setTimeout(debugTimeout); + debugContext.setId($scriptId); + debugContext.setCallback(variables -> { + List> varList = (List>) variables.get("variables"); + varList.stream().filter(it -> it.containsKey("value")).forEach(variable -> { + variable.put("value", JsonUtils.toJsonStringWithoutLog(variable.get("value"))); + }); + WebSocketSessionManager.sendByClientId(clientId, BREAKPOINT, $scriptId, variables); + }); + return debugContext; + }); + magicScriptDebugContext.setBreakpoints(intBreakpoints); + } + + /** * 恢复断点 * 当本机没有该Session时,通知其他机器处理 */ @Message(MessageType.RESUME_BREAKPOINT) public boolean resumeBreakpoint(MagicConsoleSession session, String scriptId, String stepInto, String breakpoints) { MagicScriptDebugContext context = WebSocketSessionManager.findMagicScriptContext(session.getClientId() + scriptId); + List intBreakpoints = getBreakpoints(breakpoints); + if (context == null) { + context = DEBUG_CONTEXTS.get(scriptId); + } if (context != null) { context.setStepInto("1".equals(stepInto)); if (StringUtils.isNotBlank(breakpoints)) { - context.setBreakpoints(Stream.of(breakpoints.split("\\|")).map(Integer::valueOf).collect(Collectors.toList())); + context.setBreakpoints(intBreakpoints); } else { context.setBreakpoints(Collections.emptyList()); } diff --git a/magic-api/src/main/java/org/ssssssss/magicapi/function/service/FunctionMagicDynamicRegistry.java b/magic-api/src/main/java/org/ssssssss/magicapi/function/service/FunctionMagicDynamicRegistry.java index ffec89b0..a7e7a32f 100644 --- a/magic-api/src/main/java/org/ssssssss/magicapi/function/service/FunctionMagicDynamicRegistry.java +++ b/magic-api/src/main/java/org/ssssssss/magicapi/function/service/FunctionMagicDynamicRegistry.java @@ -6,6 +6,7 @@ import org.springframework.context.event.EventListener; import org.ssssssss.magicapi.core.config.MagicConfiguration; import org.ssssssss.magicapi.core.event.FileEvent; import org.ssssssss.magicapi.core.event.GroupEvent; +import org.ssssssss.magicapi.core.handler.MagicDebugHandler; import org.ssssssss.magicapi.function.model.FunctionInfo; import org.ssssssss.magicapi.core.model.Parameter; import org.ssssssss.magicapi.core.service.MagicResourceStorage; @@ -13,6 +14,7 @@ import org.ssssssss.magicapi.utils.ScriptManager; import org.ssssssss.magicapi.core.service.AbstractMagicDynamicRegistry; import org.ssssssss.script.MagicResourceLoader; import org.ssssssss.script.MagicScriptContext; +import org.ssssssss.script.MagicScriptDebugContext; import org.ssssssss.script.exception.MagicExitException; import org.ssssssss.script.runtime.ExitValue; @@ -35,6 +37,10 @@ public class FunctionMagicDynamicRegistry extends AbstractMagicDynamicRegistry parameters = functionInfo.getParameters(); return (Function) objects -> { MagicScriptContext functionContext = new MagicScriptContext(context.getRootVariables()); + MagicScriptDebugContext functionDebugContext = MagicDebugHandler.getDebugContext(functionInfo.getId()); + if (functionDebugContext != null) { + functionContext = functionDebugContext; + } functionContext.setScriptName(scriptName); if (objects != null) { for (int i = 0, len = objects.length, size = parameters.size(); i < len && i < size; i++) { -- Gitee