feat: 关闭终端连接.

This commit is contained in:
lijiahangmax
2024-01-04 00:38:40 +08:00
parent e60570069c
commit 71299801c5
11 changed files with 257 additions and 34 deletions

View File

@@ -1,12 +1,9 @@
package com.orion.ops.module.asset.handler.host.terminal.enums;
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.TerminalCheckHandler;
import com.orion.ops.module.asset.handler.host.terminal.handler.TerminalConnectHandler;
import com.orion.ops.module.asset.handler.host.terminal.handler.*;
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.TerminalConnectRequest;
import com.orion.ops.module.asset.handler.host.terminal.model.request.*;
import com.orion.spring.SpringHolder;
import lombok.Getter;
import org.springframework.stereotype.Component;
@@ -42,41 +39,41 @@ public enum InputTypeEnum {
* 关闭连接
*/
CLOSE("cl",
TerminalConnectHandler.class,
TerminalCloseHandler.class,
new String[]{"type", "session"},
TerminalConnectRequest.class),
TerminalBasePayload.class),
/**
* ping
*/
PING("p",
TerminalConnectHandler.class,
new String[]{"type", "session"},
TerminalConnectRequest.class),
TerminalPingHandler.class,
new String[]{"type"},
TerminalBasePayload.class),
/**
* 修改大小
*/
RESIZE("rs",
TerminalConnectHandler.class,
TerminalResizeHandler.class,
new String[]{"type", "session", "cols", "rows"},
TerminalConnectRequest.class),
TerminalResizeRequest.class),
/**
* 执行
*/
EXEC("e",
TerminalConnectHandler.class,
TerminalExecHandler.class,
new String[]{"type", "session", "command"},
TerminalConnectRequest.class),
TerminalExecRequest.class),
/**
* 输入
*/
INPUT("i",
TerminalConnectHandler.class,
TerminalInputHandler.class,
new String[]{"type", "session", "command"},
TerminalConnectRequest.class),
TerminalInputRequest.class),
;
@@ -109,7 +106,7 @@ public enum InputTypeEnum {
return null;
}
for (InputTypeEnum value : values()) {
if (payload.startsWith(value.type + SEPARATOR)) {
if (payload.startsWith(value.type + SEPARATOR) || value.type.equals(payload)) {
return value;
}
}

View File

@@ -28,22 +28,15 @@ public enum OutputTypeEnum {
/**
* pong
*/
PONG("p", "${type}|${session}"),
PONG("p", "${type}"),
/**
* 输出
*/
OUTPUT("o", "${type}|${session}|${body}"),
/**
* 发生错误
*/
ERROR("e", "${type}|${session}"),
;
private static final char SEPARATOR = '|';
private final String type;
private final String template;

View File

@@ -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());
}
}

View File

@@ -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());
}
}
}

View File

@@ -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());
}
}
}

View File

@@ -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());
}
}

View File

@@ -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());
}
}
}

View File

@@ -51,9 +51,11 @@ public class TerminalManager {
* @param token token
*/
public void closeSession(String id, String token) {
ITerminalSession session = sessions.get(id, token);
Streams.close(session);
sessions.removeElement(id, token);
// 获取并移除
ITerminalSession session = sessions.removeElement(id, token);
if (session != null) {
Streams.close(session);
}
}
/**
@@ -62,12 +64,11 @@ public class TerminalManager {
* @param id id
*/
public void closeAll(String id) {
ConcurrentHashMap<String, ITerminalSession> session = sessions.get(id);
// 获取并移除
ConcurrentHashMap<String, ITerminalSession> session = sessions.remove(id);
if (Maps.isEmpty(session)) {
return;
session.values().forEach(Streams::close);
}
session.values().forEach(Streams::close);
sessions.remove(id);
}
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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.websocket.core.utils.WebSockets;
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.model.TerminalConfig;
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.extern.slf4j.Slf4j;
import org.springframework.web.socket.WebSocketSession;
@@ -96,12 +99,15 @@ public class TerminalSession implements ITerminalSession {
return;
}
this.close = true;
// 关闭流
try {
Streams.close(executor);
Streams.close(sessionStore);
} catch (Exception 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
if (close) {
return;
log.info("terminal eof回调 {}", token);
}
log.info("terminal eof回调 {}", token);
}
}