feat: 关闭终端连接.
This commit is contained in:
@@ -1,12 +1,9 @@
|
|||||||
package com.orion.ops.module.asset.handler.host.terminal.enums;
|
package com.orion.ops.module.asset.handler.host.terminal.enums;
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import com.orion.ops.module.asset.handler.host.terminal.handler.ITerminalHandler;
|
import com.orion.ops.module.asset.handler.host.terminal.handler.*;
|
||||||
import com.orion.ops.module.asset.handler.host.terminal.handler.TerminalCheckHandler;
|
|
||||||
import com.orion.ops.module.asset.handler.host.terminal.handler.TerminalConnectHandler;
|
|
||||||
import com.orion.ops.module.asset.handler.host.terminal.model.TerminalBasePayload;
|
import com.orion.ops.module.asset.handler.host.terminal.model.TerminalBasePayload;
|
||||||
import com.orion.ops.module.asset.handler.host.terminal.model.request.TerminalCheckRequest;
|
import com.orion.ops.module.asset.handler.host.terminal.model.request.*;
|
||||||
import com.orion.ops.module.asset.handler.host.terminal.model.request.TerminalConnectRequest;
|
|
||||||
import com.orion.spring.SpringHolder;
|
import com.orion.spring.SpringHolder;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@@ -42,41 +39,41 @@ public enum InputTypeEnum {
|
|||||||
* 关闭连接
|
* 关闭连接
|
||||||
*/
|
*/
|
||||||
CLOSE("cl",
|
CLOSE("cl",
|
||||||
TerminalConnectHandler.class,
|
TerminalCloseHandler.class,
|
||||||
new String[]{"type", "session"},
|
new String[]{"type", "session"},
|
||||||
TerminalConnectRequest.class),
|
TerminalBasePayload.class),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ping
|
* ping
|
||||||
*/
|
*/
|
||||||
PING("p",
|
PING("p",
|
||||||
TerminalConnectHandler.class,
|
TerminalPingHandler.class,
|
||||||
new String[]{"type", "session"},
|
new String[]{"type"},
|
||||||
TerminalConnectRequest.class),
|
TerminalBasePayload.class),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改大小
|
* 修改大小
|
||||||
*/
|
*/
|
||||||
RESIZE("rs",
|
RESIZE("rs",
|
||||||
TerminalConnectHandler.class,
|
TerminalResizeHandler.class,
|
||||||
new String[]{"type", "session", "cols", "rows"},
|
new String[]{"type", "session", "cols", "rows"},
|
||||||
TerminalConnectRequest.class),
|
TerminalResizeRequest.class),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 执行
|
* 执行
|
||||||
*/
|
*/
|
||||||
EXEC("e",
|
EXEC("e",
|
||||||
TerminalConnectHandler.class,
|
TerminalExecHandler.class,
|
||||||
new String[]{"type", "session", "command"},
|
new String[]{"type", "session", "command"},
|
||||||
TerminalConnectRequest.class),
|
TerminalExecRequest.class),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 输入
|
* 输入
|
||||||
*/
|
*/
|
||||||
INPUT("i",
|
INPUT("i",
|
||||||
TerminalConnectHandler.class,
|
TerminalInputHandler.class,
|
||||||
new String[]{"type", "session", "command"},
|
new String[]{"type", "session", "command"},
|
||||||
TerminalConnectRequest.class),
|
TerminalInputRequest.class),
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
@@ -109,7 +106,7 @@ public enum InputTypeEnum {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
for (InputTypeEnum value : values()) {
|
for (InputTypeEnum value : values()) {
|
||||||
if (payload.startsWith(value.type + SEPARATOR)) {
|
if (payload.startsWith(value.type + SEPARATOR) || value.type.equals(payload)) {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,22 +28,15 @@ public enum OutputTypeEnum {
|
|||||||
/**
|
/**
|
||||||
* pong
|
* pong
|
||||||
*/
|
*/
|
||||||
PONG("p", "${type}|${session}"),
|
PONG("p", "${type}"),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 输出
|
* 输出
|
||||||
*/
|
*/
|
||||||
OUTPUT("o", "${type}|${session}|${body}"),
|
OUTPUT("o", "${type}|${session}|${body}"),
|
||||||
|
|
||||||
/**
|
|
||||||
* 发生错误
|
|
||||||
*/
|
|
||||||
ERROR("e", "${type}|${session}"),
|
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
private static final char SEPARATOR = '|';
|
|
||||||
|
|
||||||
private final String type;
|
private final String type;
|
||||||
|
|
||||||
private final String template;
|
private final String template;
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package com.orion.ops.module.asset.handler.host.terminal.handler;
|
||||||
|
|
||||||
|
import com.orion.ops.module.asset.handler.host.terminal.manager.TerminalManager;
|
||||||
|
import com.orion.ops.module.asset.handler.host.terminal.model.TerminalBasePayload;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.socket.WebSocketSession;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关闭处理器
|
||||||
|
*
|
||||||
|
* @author Jiahang Li
|
||||||
|
* @version 1.0.0
|
||||||
|
* @since 2023/12/29 15:32
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class TerminalCloseHandler extends AbstractTerminalHandler<TerminalBasePayload> {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private TerminalManager terminalManager;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(WebSocketSession session, TerminalBasePayload payload) {
|
||||||
|
// 关闭会话
|
||||||
|
terminalManager.closeSession(session.getId(), payload.getSession());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package com.orion.ops.module.asset.handler.host.terminal.handler;
|
||||||
|
|
||||||
|
import com.orion.ops.module.asset.handler.host.terminal.manager.TerminalManager;
|
||||||
|
import com.orion.ops.module.asset.handler.host.terminal.model.request.TerminalExecRequest;
|
||||||
|
import com.orion.ops.module.asset.handler.host.terminal.session.ITerminalSession;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.socket.WebSocketSession;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行命令处理器
|
||||||
|
*
|
||||||
|
* @author Jiahang Li
|
||||||
|
* @version 1.0.0
|
||||||
|
* @since 2023/12/29 15:32
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class TerminalExecHandler extends AbstractTerminalHandler<TerminalExecRequest> {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private TerminalManager terminalManager;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(WebSocketSession session, TerminalExecRequest payload) {
|
||||||
|
// 获取会话
|
||||||
|
ITerminalSession terminalSession = terminalManager.getSession(session.getId(), payload.getSession());
|
||||||
|
if (terminalSession != null) {
|
||||||
|
// 执行命令
|
||||||
|
terminalSession.write(payload.getCommand());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package com.orion.ops.module.asset.handler.host.terminal.handler;
|
||||||
|
|
||||||
|
import com.orion.ops.module.asset.handler.host.terminal.manager.TerminalManager;
|
||||||
|
import com.orion.ops.module.asset.handler.host.terminal.model.request.TerminalInputRequest;
|
||||||
|
import com.orion.ops.module.asset.handler.host.terminal.session.ITerminalSession;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.socket.WebSocketSession;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理输入处理器
|
||||||
|
*
|
||||||
|
* @author Jiahang Li
|
||||||
|
* @version 1.0.0
|
||||||
|
* @since 2023/12/29 15:32
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class TerminalInputHandler extends AbstractTerminalHandler<TerminalInputRequest> {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private TerminalManager terminalManager;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(WebSocketSession session, TerminalInputRequest payload) {
|
||||||
|
// 获取会话
|
||||||
|
ITerminalSession terminalSession = terminalManager.getSession(session.getId(), payload.getSession());
|
||||||
|
if (terminalSession != null) {
|
||||||
|
// 处理输入
|
||||||
|
terminalSession.write(payload.getCommand());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package com.orion.ops.module.asset.handler.host.terminal.handler;
|
||||||
|
|
||||||
|
import com.orion.ops.module.asset.handler.host.terminal.enums.OutputTypeEnum;
|
||||||
|
import com.orion.ops.module.asset.handler.host.terminal.model.TerminalBasePayload;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.socket.WebSocketSession;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ping 处理器
|
||||||
|
*
|
||||||
|
* @author Jiahang Li
|
||||||
|
* @version 1.0.0
|
||||||
|
* @since 2023/12/29 15:32
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class TerminalPingHandler extends AbstractTerminalHandler<TerminalBasePayload> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(WebSocketSession session, TerminalBasePayload payload) {
|
||||||
|
// 发送 pong
|
||||||
|
this.send(session, OutputTypeEnum.PONG.getType());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package com.orion.ops.module.asset.handler.host.terminal.handler;
|
||||||
|
|
||||||
|
import com.orion.ops.module.asset.handler.host.terminal.manager.TerminalManager;
|
||||||
|
import com.orion.ops.module.asset.handler.host.terminal.model.request.TerminalResizeRequest;
|
||||||
|
import com.orion.ops.module.asset.handler.host.terminal.session.ITerminalSession;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.socket.WebSocketSession;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改大小处理器
|
||||||
|
*
|
||||||
|
* @author Jiahang Li
|
||||||
|
* @version 1.0.0
|
||||||
|
* @since 2023/12/29 15:32
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class TerminalResizeHandler extends AbstractTerminalHandler<TerminalResizeRequest> {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private TerminalManager terminalManager;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(WebSocketSession session, TerminalResizeRequest payload) {
|
||||||
|
// 获取会话
|
||||||
|
ITerminalSession terminalSession = terminalManager.getSession(session.getId(), payload.getSession());
|
||||||
|
if (terminalSession != null) {
|
||||||
|
// 修改大小
|
||||||
|
terminalSession.resize(payload.getCols(), payload.getRows());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -51,9 +51,11 @@ public class TerminalManager {
|
|||||||
* @param token token
|
* @param token token
|
||||||
*/
|
*/
|
||||||
public void closeSession(String id, String token) {
|
public void closeSession(String id, String token) {
|
||||||
ITerminalSession session = sessions.get(id, token);
|
// 获取并移除
|
||||||
|
ITerminalSession session = sessions.removeElement(id, token);
|
||||||
|
if (session != null) {
|
||||||
Streams.close(session);
|
Streams.close(session);
|
||||||
sessions.removeElement(id, token);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -62,12 +64,11 @@ public class TerminalManager {
|
|||||||
* @param id id
|
* @param id id
|
||||||
*/
|
*/
|
||||||
public void closeAll(String id) {
|
public void closeAll(String id) {
|
||||||
ConcurrentHashMap<String, ITerminalSession> session = sessions.get(id);
|
// 获取并移除
|
||||||
|
ConcurrentHashMap<String, ITerminalSession> session = sessions.remove(id);
|
||||||
if (Maps.isEmpty(session)) {
|
if (Maps.isEmpty(session)) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
session.values().forEach(Streams::close);
|
session.values().forEach(Streams::close);
|
||||||
sessions.remove(id);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package com.orion.ops.module.asset.handler.host.terminal.model.request;
|
||||||
|
|
||||||
|
import com.orion.ops.module.asset.handler.host.terminal.model.TerminalBasePayload;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.experimental.SuperBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行命令请求 实体对象
|
||||||
|
* <p>
|
||||||
|
* e|eff00a1|command
|
||||||
|
*
|
||||||
|
* @author Jiahang Li
|
||||||
|
* @version 1.0.0
|
||||||
|
* @since 2023/12/29 16:20
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@SuperBuilder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Schema(name = "TerminalExecRequest", description = "执行命令请求 实体对象")
|
||||||
|
public class TerminalExecRequest extends TerminalBasePayload {
|
||||||
|
|
||||||
|
@Schema(description = "command")
|
||||||
|
private String command;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package com.orion.ops.module.asset.handler.host.terminal.model.request;
|
||||||
|
|
||||||
|
import com.orion.ops.module.asset.handler.host.terminal.model.TerminalBasePayload;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.experimental.SuperBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 输入请求 实体对象
|
||||||
|
* <p>
|
||||||
|
* i|eff00a1|command
|
||||||
|
*
|
||||||
|
* @author Jiahang Li
|
||||||
|
* @version 1.0.0
|
||||||
|
* @since 2023/12/29 16:20
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@SuperBuilder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Schema(name = "TerminalInputRequest", description = "输入请求 实体对象")
|
||||||
|
public class TerminalInputRequest extends TerminalBasePayload {
|
||||||
|
|
||||||
|
@Schema(description = "command")
|
||||||
|
private String command;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -7,9 +7,12 @@ import com.orion.net.host.ssh.shell.ShellExecutor;
|
|||||||
import com.orion.ops.framework.common.constant.Const;
|
import com.orion.ops.framework.common.constant.Const;
|
||||||
import com.orion.ops.framework.websocket.core.utils.WebSockets;
|
import com.orion.ops.framework.websocket.core.utils.WebSockets;
|
||||||
import com.orion.ops.module.asset.define.AssetThreadPools;
|
import com.orion.ops.module.asset.define.AssetThreadPools;
|
||||||
|
import com.orion.ops.module.asset.enums.HostConnectStatusEnum;
|
||||||
import com.orion.ops.module.asset.handler.host.terminal.enums.OutputTypeEnum;
|
import com.orion.ops.module.asset.handler.host.terminal.enums.OutputTypeEnum;
|
||||||
import com.orion.ops.module.asset.handler.host.terminal.model.TerminalConfig;
|
import com.orion.ops.module.asset.handler.host.terminal.model.TerminalConfig;
|
||||||
import com.orion.ops.module.asset.handler.host.terminal.model.response.TerminalOutputResponse;
|
import com.orion.ops.module.asset.handler.host.terminal.model.response.TerminalOutputResponse;
|
||||||
|
import com.orion.ops.module.asset.service.HostConnectLogService;
|
||||||
|
import com.orion.spring.SpringHolder;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.web.socket.WebSocketSession;
|
import org.springframework.web.socket.WebSocketSession;
|
||||||
@@ -96,12 +99,15 @@ public class TerminalSession implements ITerminalSession {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.close = true;
|
this.close = true;
|
||||||
|
// 关闭流
|
||||||
try {
|
try {
|
||||||
Streams.close(executor);
|
Streams.close(executor);
|
||||||
Streams.close(sessionStore);
|
Streams.close(sessionStore);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("terminal 断开连接 失败 token: {}", token, e);
|
log.error("terminal 断开连接 失败 token: {}", token, e);
|
||||||
}
|
}
|
||||||
|
// 修改状态
|
||||||
|
SpringHolder.getBean(HostConnectLogService.class).updateStatusByToken(token, HostConnectStatusEnum.COMPLETE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -129,9 +135,8 @@ public class TerminalSession implements ITerminalSession {
|
|||||||
}
|
}
|
||||||
// eof
|
// eof
|
||||||
if (close) {
|
if (close) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
log.info("terminal eof回调 {}", token);
|
log.info("terminal eof回调 {}", token);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user