diff --git a/spider-flow-api/src/main/java/org/spiderflow/context/SpiderContext.java b/spider-flow-api/src/main/java/org/spiderflow/context/SpiderContext.java index c412227..3d1b8b1 100644 --- a/spider-flow-api/src/main/java/org/spiderflow/context/SpiderContext.java +++ b/spider-flow-api/src/main/java/org/spiderflow/context/SpiderContext.java @@ -40,10 +40,21 @@ public class SpiderContext extends HashMap{ private SpiderNode rootNode; + private boolean running = true; + public List getOutputs() { return outputs; } + + public boolean isRunning() { + return running; + } + + public void setRunning(boolean running) { + this.running = running; + } + public void addDataSource(String id,DataSource datasource){ this.datasources.put(id, datasource); } diff --git a/spider-flow-core/src/main/java/org/spiderflow/core/Spider.java b/spider-flow-core/src/main/java/org/spiderflow/core/Spider.java index 63529e3..d9b3f00 100644 --- a/spider-flow-core/src/main/java/org/spiderflow/core/Spider.java +++ b/spider-flow-core/src/main/java/org/spiderflow/core/Spider.java @@ -123,25 +123,28 @@ public class Spider { for (ShapeExecutor executor : executors) { if(executor.supportShape().equals(shape)){ for (int i = 0; i < loopCount; i++) { - //存入下标变量 - Map nVariables = Maps.add(variables, loopVariableName, i); - Runnable runnable = ()->{ - try { - executor.execute(node, context,nVariables); - } catch (Exception e) { - context.error("执行节点[{}:{}]出错,异常信息:{}",node.getNodeName(),node.getNodeId(),e); - } finally{ - context.debug("执行节点[{}:{}]完毕",node.getNodeName(),node.getNodeId()); - //递归执行下一级 - executeaNextNodes(pool, node, context, nVariables); + if(context.isRunning()){ + //存入下标变量 + Map nVariables = Maps.add(variables, loopVariableName, i); + Runnable runnable = ()->{ + if(context.isRunning()){ + try { + executor.execute(node, context,nVariables); + } catch (Exception e) { + context.error("执行节点[{}:{}]出错,异常信息:{}",node.getNodeName(),node.getNodeId(),e); + } finally{ + context.debug("执行节点[{}:{}]完毕",node.getNodeName(),node.getNodeId()); + //递归执行下一级 + executeaNextNodes(pool, node, context, nVariables); + } + } + }; + if(executor.isThread()){ + pool.submit(runnable); + }else{ + runnable.run(); } - }; - if(executor.isThread()){ - pool.submit(runnable); - }else{ - runnable.run(); } - } } } diff --git a/spider-flow-web/src/main/java/org/spiderflow/model/SpiderWebSocketContext.java b/spider-flow-web/src/main/java/org/spiderflow/model/SpiderWebSocketContext.java index 30d498f..7771883 100644 --- a/spider-flow-web/src/main/java/org/spiderflow/model/SpiderWebSocketContext.java +++ b/spider-flow-web/src/main/java/org/spiderflow/model/SpiderWebSocketContext.java @@ -15,9 +15,7 @@ import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.serializer.JSONSerializer; import com.alibaba.fastjson.serializer.ObjectSerializer; import com.alibaba.fastjson.serializer.SerializeConfig; -import com.alibaba.fastjson.serializer.SerializeFilter; import com.alibaba.fastjson.serializer.SerializerFeature; -import com.alibaba.fastjson.serializer.ValueFilter; /** * WebSocket通讯中爬虫的上下文域 diff --git a/spider-flow-web/src/main/java/org/spiderflow/websocket/WebSocketEditorServer.java b/spider-flow-web/src/main/java/org/spiderflow/websocket/WebSocketEditorServer.java index 6b6892a..8db61d4 100644 --- a/spider-flow-web/src/main/java/org/spiderflow/websocket/WebSocketEditorServer.java +++ b/spider-flow-web/src/main/java/org/spiderflow/websocket/WebSocketEditorServer.java @@ -2,7 +2,10 @@ package org.spiderflow.websocket; import java.sql.Connection; import java.sql.DriverManager; +import java.util.HashMap; +import java.util.Map; +import javax.websocket.OnClose; import javax.websocket.OnMessage; import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; @@ -29,18 +32,32 @@ public class WebSocketEditorServer { public static Spider spider; + private static Map contextMap = new HashMap<>(); + @OnMessage public void onMessage(String message,Session session){ JSONObject event = JSON.parseObject(message); - SpiderWebSocketContext context = new SpiderWebSocketContext(session); - if("test".equals(event.getString("eventType"))){ - String xml = event.getString("message"); - if(xml != null){ - spider.runWithTest(SpiderFlowUtils.loadXMLFromString(xml), context); - }else{ - context.write(new WebSocketEvent<>("error", "xml不正确!")); - } - }else if("testDatasource".equals(event.getString("eventType"))){ + SpiderWebSocketContext context = contextMap.get(session.getId()); + if(context == null){ + context = new SpiderWebSocketContext(session); + contextMap.put(session.getId(), context); + } + String eventType = event.getString("eventType"); + if("test".equals(eventType)){ + context.setRunning(true); + final SpiderWebSocketContext spiderContext = context; + new Thread(()->{ + String xml = event.getString("message"); + if(xml != null){ + spider.runWithTest(SpiderFlowUtils.loadXMLFromString(xml), spiderContext); + spiderContext.write(new WebSocketEvent<>("finish", null)); + }else{ + spiderContext.write(new WebSocketEvent<>("error", "xml不正确!")); + } + }).start(); + }else if("stop".equals(eventType)){ + context.setRunning(false); + }else if("testDatasource".equals(eventType)){ JSONObject dsConfig = event.getJSONObject("message"); String className = DataSourceUtils.getDriverClassByDataBaseType(dsConfig.getString("type")); if(StringUtils.isEmpty(className)){ @@ -66,5 +83,14 @@ public class WebSocketEditorServer { } } } + + @OnClose + public void onClose(Session session){ + SpiderWebSocketContext context = contextMap.get(session.getId()); + if(context != null){ + context.setRunning(false); + } + contextMap.remove(session.getId()); + } } diff --git a/spider-flow-web/src/main/resources/static/js/editor.js b/spider-flow-web/src/main/resources/static/js/editor.js index dbafa7d..004d3e4 100644 --- a/spider-flow-web/src/main/resources/static/js/editor.js +++ b/spider-flow-web/src/main/resources/static/js/editor.js @@ -569,13 +569,13 @@ function bindToolbarClickAction(editor){ var tableMap = {}; var socket; var first = true; - layui.layer.open({ + var testWindowIndex = layui.layer.open({ id : 'test-window', content : '
    ', area : ["980px","600px"], shade : 0, title : '测试窗口', - btn : ['关闭','显示/隐藏输出','显示/隐藏日志'], + btn : ['关闭','显示/隐藏输出','显示/隐藏日志','停止'], btn2 : function(){ var $output = $(".test-window-container .output-container"); var $log = $(".test-window-container .log-container"); @@ -628,6 +628,21 @@ function bindToolbarClickAction(editor){ } return false; }, + btn4 : function(){ + var $btn = $("#layui-layer" + testWindowIndex).find('.layui-layer-btn3'); + if($btn.html() == '停止'){ + socket.send(JSON.stringify({ + eventType : 'stop' + })); + }else{ + socket.send(JSON.stringify({ + eventType : 'test', + message : editor.getXML() + })); + $btn.html('停止'); + } + return false; + }, end : function(){ if(socket){ socket.close(); @@ -664,7 +679,9 @@ function bindToolbarClickAction(editor){ var event = JSON.parse(e.data); var eventType = event.eventType; var message = event.message; - if(eventType == 'output'){ + if(eventType == 'finish'){ + $("#layui-layer" + testWindowIndex).find('.layui-layer-btn3').html('重新开始'); + }else if(eventType == 'output'){ var tableId = 'output-' + message.nodeId; var $table = $('#' + tableId); if($table.length == 0){