feat: 关闭终端连接.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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.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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user