添加ssh 服务 2023年3月11日17:59:54
parent
e3065d4ffb
commit
e095236234
|
|
@ -1,12 +1,26 @@
|
||||||
package com.zhangmeng.tools.controller;
|
package com.zhangmeng.tools.controller;
|
||||||
|
|
||||||
import com.zhangmeng.tools.ssh.SSHService;
|
import cn.hutool.core.io.BufferUtil;
|
||||||
import com.zhangmeng.tools.ssh.SSHServiceImpl;
|
import cn.hutool.core.io.FileUtil;
|
||||||
|
import cn.hutool.core.io.IORuntimeException;
|
||||||
|
import cn.hutool.core.io.IoUtil;
|
||||||
|
import cn.hutool.core.util.CharsetUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.hutool.extra.ssh.ChannelType;
|
||||||
|
import cn.hutool.extra.ssh.JschRuntimeException;
|
||||||
|
import cn.hutool.extra.ssh.JschUtil;
|
||||||
|
import cn.hutool.socket.aio.AioSession;
|
||||||
|
import cn.hutool.socket.aio.SimpleIoAction;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.jcraft.jsch.*;
|
||||||
|
import com.zhangmeng.tools.ssh.*;
|
||||||
import com.zhangmeng.tools.utils.AlertUtils;
|
import com.zhangmeng.tools.utils.AlertUtils;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.beans.property.SimpleObjectProperty;
|
import javafx.beans.property.SimpleObjectProperty;
|
||||||
import javafx.beans.value.ChangeListener;
|
import javafx.beans.value.ChangeListener;
|
||||||
import javafx.beans.value.ObservableValue;
|
import javafx.beans.value.ObservableValue;
|
||||||
|
import javafx.collections.FXCollections;
|
||||||
import javafx.collections.ListChangeListener;
|
import javafx.collections.ListChangeListener;
|
||||||
import javafx.collections.ObservableList;
|
import javafx.collections.ObservableList;
|
||||||
import javafx.event.EventHandler;
|
import javafx.event.EventHandler;
|
||||||
|
|
@ -17,6 +31,26 @@ import javafx.scene.control.TextField;
|
||||||
import javafx.scene.input.MouseButton;
|
import javafx.scene.input.MouseButton;
|
||||||
import javafx.scene.input.MouseEvent;
|
import javafx.scene.input.MouseEvent;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.java_websocket.WebSocket;
|
||||||
|
import org.java_websocket.client.WebSocketClient;
|
||||||
|
import org.java_websocket.drafts.Draft_6455;
|
||||||
|
import org.java_websocket.handshake.ClientHandshake;
|
||||||
|
import org.java_websocket.handshake.ServerHandshake;
|
||||||
|
import org.java_websocket.server.WebSocketServer;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import static cn.hutool.extra.ssh.JschUtil.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author : 芊芊墨客
|
* @author : 芊芊墨客
|
||||||
|
|
@ -47,64 +81,26 @@ public class SSHConnectionController {
|
||||||
@FXML
|
@FXML
|
||||||
private TextField port;
|
private TextField port;
|
||||||
|
|
||||||
private SSHService sshService = null;
|
private SimpleObjectProperty<String> uuid = new SimpleObjectProperty<>("202331112221255544555");
|
||||||
|
|
||||||
private SimpleObjectProperty<String> uuid = new SimpleObjectProperty<>("2023311");
|
|
||||||
private SimpleObjectProperty<Integer> status = new SimpleObjectProperty<>(0);
|
private SimpleObjectProperty<Integer> status = new SimpleObjectProperty<>(0);
|
||||||
|
public static ObservableList<String> message_list = FXCollections.observableArrayList();
|
||||||
|
|
||||||
|
private WebSocketServer webSocketServer;
|
||||||
|
private WebSocketClient webSocketClient;
|
||||||
|
private SSHService sshService;
|
||||||
|
|
||||||
|
private SimpleObjectProperty<String> cmd = new SimpleObjectProperty<>();
|
||||||
|
|
||||||
|
private boolean isConnection = false;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
|
|
||||||
sshService = new SSHServiceImpl();
|
username.setText("root");
|
||||||
|
password.setText("root");
|
||||||
|
host.setText("192.168.52.165");
|
||||||
|
port.setText("22");
|
||||||
|
|
||||||
connection.setOnAction(event -> {
|
|
||||||
if (username.getText().length() == 0 ){
|
|
||||||
AlertUtils.alert_warning("用户名不能为空!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (password.getText().length() == 0 ){
|
|
||||||
AlertUtils.alert_warning("密码不能为空!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (host.getText().length() == 0 ){
|
|
||||||
AlertUtils.alert_warning("服务地址不能为空!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (port.getText().length() == 0 ){
|
|
||||||
AlertUtils.alert_warning("服务端口不能为空!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
SSHServiceImpl.SSHConnectInfo sshConnectInfo = new SSHServiceImpl.SSHConnectInfo();
|
|
||||||
sshConnectInfo.setUsername(username.getText());
|
|
||||||
sshConnectInfo.setPassword(password.getText());
|
|
||||||
sshConnectInfo.setHost(host.getText());
|
|
||||||
sshConnectInfo.setPort(Integer.parseInt(port.getText()));
|
|
||||||
|
|
||||||
//init
|
|
||||||
this.sshService.initConnection(uuid.get(),sshConnectInfo);
|
|
||||||
|
|
||||||
//connection
|
|
||||||
this.sshService.recvHandle("", SSHServiceImpl.Type.connect,uuid.get());
|
|
||||||
|
|
||||||
AlertUtils.alert_msg("连额成功!");
|
|
||||||
status.set(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
command.setOnAction(event -> {
|
|
||||||
if (status.getValue() != 1){
|
|
||||||
AlertUtils.alert_warning("请连接后再试!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (command.getText().length() == 0 ){
|
|
||||||
AlertUtils.alert_warning("请输入命令后再试!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.sshService.recvHandle(command.getText(),SSHServiceImpl.Type.command, uuid.get());
|
|
||||||
});
|
|
||||||
ObservableList<String> message_list = SSHServiceImpl.message_list;
|
|
||||||
message_list.addListener((ListChangeListener<String>) c -> {
|
message_list.addListener((ListChangeListener<String>) c -> {
|
||||||
while (c.next()) {
|
while (c.next()) {
|
||||||
if (c.wasAdded()) {
|
if (c.wasAdded()) {
|
||||||
|
|
@ -116,10 +112,151 @@ public class SSHConnectionController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
sshService = new SSHServiceImpl();
|
||||||
|
//启动socket server
|
||||||
|
webSocketServer = new WebSocketServer(new InetSocketAddress(8888)) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onOpen(WebSocket webSocket, ClientHandshake clientHandshake) {
|
||||||
|
add_msg("WebSocketServer:onOpen--------------------------------------------");
|
||||||
|
sshService.initConnection(webSocket,uuid.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void receive(String msg){
|
@Override
|
||||||
|
public void onClose(WebSocket webSocket, int i, String s, boolean b) {
|
||||||
|
add_msg("WebSocketServer:onClose--------------------------------------------");
|
||||||
|
sshService.close(webSocket,uuid.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onMessage(WebSocket webSocket, String s) {
|
||||||
|
add_msg("WebSocketServer:onMessage---" + s);
|
||||||
|
sshService.recvHandle(s,webSocket,uuid.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(WebSocket webSocket, Exception e) {
|
||||||
|
add_msg("WebSocketServer:onError--------------------------------------------");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart() {
|
||||||
|
add_msg("WebSocketServer:onStart--------------------------------------------");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
connection.setOnAction(event -> {
|
||||||
|
if (username.getText().length() == 0) {
|
||||||
|
AlertUtils.alert_warning("用户名不能为空!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (password.getText().length() == 0) {
|
||||||
|
AlertUtils.alert_warning("密码不能为空!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (host.getText().length() == 0) {
|
||||||
|
AlertUtils.alert_warning("服务地址不能为空!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (port.getText().length() == 0) {
|
||||||
|
AlertUtils.alert_warning("服务端口不能为空!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
webSocketServer.start();
|
||||||
|
getConnection();
|
||||||
|
try {
|
||||||
|
Thread.sleep(1000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
//发送连接信息
|
||||||
|
SSHData ssh_data = create_ssh_data(command.getText(), SSHData.Type.connect);
|
||||||
|
webSocketClient.send(toString(ssh_data));
|
||||||
|
isConnection = true;
|
||||||
|
status.set(1);
|
||||||
|
});
|
||||||
|
command.textProperty().addListener((observable, oldValue, newValue) -> {
|
||||||
|
if (newValue != null){
|
||||||
|
char[] chars = newValue.toCharArray();
|
||||||
|
char num = 0;
|
||||||
|
for (int i = 0; i < chars.length; i++) {
|
||||||
|
if (i == chars.length -1 ){
|
||||||
|
num = chars[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SSHData ssh_data = create_ssh_data(String.valueOf(num), SSHData.Type.command);
|
||||||
|
webSocketClient.send(toString(ssh_data));
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
command.setOnAction(event -> {
|
||||||
|
SSHData ssh_data = create_ssh_data("\r", SSHData.Type.command);
|
||||||
|
webSocketClient.send(toString(ssh_data));
|
||||||
|
command.setText(null);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private String toString(SSHData sshData){
|
||||||
|
return JSON.toJSONString(sshData);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SSHData create_ssh_data(String command,SSHData.Type type ){
|
||||||
|
SSHData sshData = new SSHData();
|
||||||
|
sshData.setUsername(username.getText());
|
||||||
|
sshData.setPassword(password.getText());
|
||||||
|
sshData.setHost(host.getText());
|
||||||
|
sshData.setPort(Integer.parseInt(port.getText()));
|
||||||
|
sshData.setOperate(type);
|
||||||
|
sshData.setCommand(command);
|
||||||
|
return sshData;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void getConnection(){
|
||||||
|
if (webSocketClient == null) {
|
||||||
|
webSocketClient( "localhost", 8888);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void webSocketClient( String socket_address, int socket_port) {
|
||||||
|
try {
|
||||||
|
webSocketClient = new WebSocketClient(new URI( "ws://" + socket_address + ":" + socket_port), new Draft_6455()) {
|
||||||
|
//连接服务端时触发
|
||||||
|
@Override
|
||||||
|
public void onOpen(ServerHandshake handshakedata) {
|
||||||
|
add_msg("websocket客户端和服务器连接成功!");
|
||||||
|
}
|
||||||
|
//收到服务端消息时触发
|
||||||
|
@Override
|
||||||
|
public void onMessage(String message) {
|
||||||
|
|
||||||
|
}
|
||||||
|
//和服务端断开连接时触发
|
||||||
|
@Override
|
||||||
|
public void onClose(int code, String reason, boolean remote) {
|
||||||
|
add_msg("websocket客户端退出连接");
|
||||||
|
}
|
||||||
|
//连接异常时触发
|
||||||
|
@Override
|
||||||
|
public void onError(Exception ex) {
|
||||||
|
add_msg("websocket客户端和服务器连接发生错误={" + ex.getMessage() + "}");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
webSocketClient.connect();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void add_msg(String msg) {
|
||||||
|
message_list.add(msg);
|
||||||
|
message_list.add("------------------------------------------------------------------->");
|
||||||
|
message_list.add(System.lineSeparator());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void receive(String msg) {
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
this.show_result.setText(msg);
|
this.show_result.setText(msg);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
package com.zhangmeng.tools.ssh;
|
||||||
|
|
||||||
|
import cn.hutool.socket.aio.AioSession;
|
||||||
|
import com.jcraft.jsch.Channel;
|
||||||
|
import com.jcraft.jsch.JSch;
|
||||||
|
import org.java_websocket.WebSocket;
|
||||||
|
import org.springframework.web.socket.WebSocketSession;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author : 芊芊墨客
|
||||||
|
* @version : 1.0
|
||||||
|
* @date : 2023-03-13 12:25
|
||||||
|
*/
|
||||||
|
public class SSHConnectInfo {
|
||||||
|
private WebSocket webSocket;
|
||||||
|
private JSch jSch;
|
||||||
|
private Channel channel;
|
||||||
|
|
||||||
|
public WebSocket getWebSocket() {
|
||||||
|
return webSocket;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWebSocket(WebSocket webSocket) {
|
||||||
|
this.webSocket = webSocket;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSch getjSch() {
|
||||||
|
return jSch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setjSch(JSch jSch) {
|
||||||
|
this.jSch = jSch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Channel getChannel() {
|
||||||
|
return channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setChannel(Channel channel) {
|
||||||
|
this.channel = channel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,86 @@
|
||||||
|
package com.zhangmeng.tools.ssh;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author : 芊芊墨客
|
||||||
|
* @version : 1.0
|
||||||
|
* @date : 2023-03-13 12:26
|
||||||
|
*/
|
||||||
|
public class SSHData {
|
||||||
|
|
||||||
|
public enum Type{
|
||||||
|
connect("连接"),
|
||||||
|
command("命令"),
|
||||||
|
;
|
||||||
|
|
||||||
|
private String desc;
|
||||||
|
|
||||||
|
Type(String desc) {
|
||||||
|
this.desc = desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDesc() {
|
||||||
|
return desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDesc(String desc) {
|
||||||
|
this.desc = desc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//操作
|
||||||
|
private Type operate;
|
||||||
|
private String host;
|
||||||
|
//端口号默认为22
|
||||||
|
private Integer port = 22;
|
||||||
|
private String username;
|
||||||
|
private String password;
|
||||||
|
private String command = "";
|
||||||
|
|
||||||
|
public Type getOperate() {
|
||||||
|
return operate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOperate(Type operate) {
|
||||||
|
this.operate = operate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHost() {
|
||||||
|
return host;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHost(String host) {
|
||||||
|
this.host = host;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getPort() {
|
||||||
|
return port;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPort(Integer port) {
|
||||||
|
this.port = port;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUsername(String username) {
|
||||||
|
this.username = username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPassword(String password) {
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCommand() {
|
||||||
|
return command;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCommand(String command) {
|
||||||
|
this.command = command;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,16 +1,22 @@
|
||||||
package com.zhangmeng.tools.ssh;
|
package com.zhangmeng.tools.ssh;
|
||||||
|
|
||||||
|
import org.java_websocket.WebSocket;
|
||||||
|
import org.springframework.web.socket.WebSocketSession;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author : 芊芊墨客
|
* @author : 芊芊墨客
|
||||||
* @version : 1.0
|
* @version : 1.0
|
||||||
* @date : 2023-03-11 16:16
|
* @date : 2023-03-13 17:05
|
||||||
* 接口地址: https://blog.51cto.com/zhongmayisheng/5216135
|
|
||||||
*/
|
*/
|
||||||
public interface SSHService {
|
public interface SSHService {
|
||||||
|
|
||||||
public void initConnection(String USER_UUID_KEY, SSHServiceImpl.SSHConnectInfo sshConnectInfo);
|
public void initConnection(WebSocket webSocket, String uuid);
|
||||||
|
|
||||||
public void recvHandle(String command, SSHServiceImpl.Type type, String USER_UUID_KEY);
|
public void recvHandle(String buffer, WebSocket webSocket,String uuid);
|
||||||
|
|
||||||
public void close(String USER_UUID_KEY);
|
public void sendMessage(WebSocket webSocket, byte[] buffer) throws IOException;
|
||||||
|
|
||||||
|
public void close(WebSocket webSocket,String uuid);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,21 @@
|
||||||
package com.zhangmeng.tools.ssh;
|
package com.zhangmeng.tools.ssh;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.jcraft.jsch.Channel;
|
import com.jcraft.jsch.Channel;
|
||||||
import com.jcraft.jsch.JSch;
|
import com.jcraft.jsch.JSch;
|
||||||
import com.jcraft.jsch.JSchException;
|
import com.jcraft.jsch.JSchException;
|
||||||
import com.jcraft.jsch.Session;
|
import com.jcraft.jsch.Session;
|
||||||
import javafx.collections.FXCollections;
|
|
||||||
import javafx.collections.ObservableList;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.java_websocket.WebSocket;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.web.socket.TextMessage;
|
||||||
|
import org.springframework.web.socket.WebSocketSession;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
@ -22,72 +26,91 @@ import java.util.concurrent.Executors;
|
||||||
/**
|
/**
|
||||||
* @author : 芊芊墨客
|
* @author : 芊芊墨客
|
||||||
* @version : 1.0
|
* @version : 1.0
|
||||||
* @date : 2023-03-11 16:18
|
* @date : 2023-03-13 17:07
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class SSHServiceImpl implements SSHService {
|
public class SSHServiceImpl implements SSHService{
|
||||||
|
|
||||||
//存放ssh连接信息的map
|
//存放ssh连接信息的map
|
||||||
private static final Map<String, Object> sshMap = new ConcurrentHashMap<>();
|
private static final Map<String, Object> sshMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
//线程池
|
//线程池
|
||||||
private final ExecutorService executorService = Executors.newCachedThreadPool();
|
private final ExecutorService executorService = Executors.newCachedThreadPool();
|
||||||
|
|
||||||
public static ObservableList<String> message_list = FXCollections.observableArrayList();
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initConnection(String USER_UUID_KEY,SSHConnectInfo sshConnectInfo) {
|
public void initConnection(WebSocket webSocket, String uuid) {
|
||||||
JSch jSch = new JSch();
|
JSch jSch = new JSch();
|
||||||
|
SSHConnectInfo sshConnectInfo = new SSHConnectInfo();
|
||||||
sshConnectInfo.setjSch(jSch);
|
sshConnectInfo.setjSch(jSch);
|
||||||
|
sshConnectInfo.setWebSocket(webSocket);
|
||||||
//将这个ssh连接信息放入map中
|
//将这个ssh连接信息放入map中
|
||||||
sshMap.put(USER_UUID_KEY, sshConnectInfo);
|
sshMap.put(uuid, sshConnectInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: 处理客户端发送的数据
|
||||||
|
* @Param: [buffer, session]
|
||||||
|
* @return: void
|
||||||
|
* @Author: NoCortY
|
||||||
|
* @Date: 2020/3/7
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void recvHandle(String command, Type type,String USER_UUID_KEY) {
|
public void recvHandle(String buffer, WebSocket webSocket,String uuid) {
|
||||||
|
ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
SSHData webSSHData = null;
|
||||||
|
try {
|
||||||
|
webSSHData = objectMapper.readValue(buffer, SSHData.class);
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("Json转换异常");
|
||||||
|
log.error("异常信息:{}", e.getMessage());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (Type.connect.equals(type)) {
|
if (SSHData.Type.connect.equals(webSSHData.getOperate())) {
|
||||||
//如果是连接请求
|
|
||||||
//找到刚才存储的ssh连接对象
|
//找到刚才存储的ssh连接对象
|
||||||
SSHConnectInfo sshConnectInfo = (SSHConnectInfo) sshMap.get(USER_UUID_KEY);
|
SSHConnectInfo sshConnectInfo = (SSHConnectInfo) sshMap.get(uuid);
|
||||||
//启动线程异步处理
|
//启动线程异步处理
|
||||||
|
SSHData finalWebSSHData = webSSHData;
|
||||||
executorService.execute(() -> {
|
executorService.execute(() -> {
|
||||||
try {
|
try {
|
||||||
//连接到终端
|
connectToSSH(sshConnectInfo, finalWebSSHData, webSocket);
|
||||||
connectToSSH(sshConnectInfo);
|
|
||||||
} catch (JSchException | IOException e) {
|
} catch (JSchException | IOException e) {
|
||||||
log.error("webssh连接异常");
|
log.error("webssh连接异常");
|
||||||
log.error("异常信息:{}", e.getMessage());
|
log.error("异常信息:{}", e.getMessage());
|
||||||
close(USER_UUID_KEY);
|
close(webSocket,uuid);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
} else if (SSHData.Type.command.equals(webSSHData.getOperate())) {
|
||||||
if (Type.command.equals(type)) {
|
String command = webSSHData.getCommand();
|
||||||
//如果是发送命令的请求
|
SSHConnectInfo sshConnectInfo = (SSHConnectInfo) sshMap.get(uuid);
|
||||||
SSHConnectInfo sshConnectInfo = (SSHConnectInfo) sshMap.get(USER_UUID_KEY);
|
|
||||||
if (sshConnectInfo != null) {
|
if (sshConnectInfo != null) {
|
||||||
try {
|
try {
|
||||||
//发送命令到终端
|
|
||||||
transToSSH(sshConnectInfo.getChannel(), command);
|
transToSSH(sshConnectInfo.getChannel(), command);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
log.error("webssh连接异常");
|
log.error("webssh连接异常");
|
||||||
log.error("异常信息:{}", e.getMessage());
|
log.error("异常信息:{}", e.getMessage());
|
||||||
close(USER_UUID_KEY);
|
close(webSocket,uuid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.error("不支持的操作");
|
log.error("不支持的操作");
|
||||||
close(USER_UUID_KEY);
|
close(webSocket,uuid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close(String USER_UUID_KEY) {
|
public void sendMessage(WebSocket webSocket, byte[] buffer) throws IOException {
|
||||||
SSHConnectInfo sshConnectInfo = (SSHConnectInfo) sshMap.get(USER_UUID_KEY);
|
webSocket.send(StrUtil.utf8Str(buffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close(WebSocket webSocket,String uuid) {
|
||||||
|
SSHConnectInfo sshConnectInfo = (SSHConnectInfo) sshMap.get(uuid);
|
||||||
if (sshConnectInfo != null) {
|
if (sshConnectInfo != null) {
|
||||||
//断开连接
|
//断开连接
|
||||||
if (sshConnectInfo.getChannel() != null) sshConnectInfo.getChannel().disconnect();
|
if (sshConnectInfo.getChannel() != null) sshConnectInfo.getChannel().disconnect();
|
||||||
//map中移除
|
//map中移除
|
||||||
sshMap.remove(USER_UUID_KEY);
|
sshMap.remove(uuid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -98,16 +121,15 @@ public class SSHServiceImpl implements SSHService {
|
||||||
* @Author: NoCortY
|
* @Author: NoCortY
|
||||||
* @Date: 2020/3/7
|
* @Date: 2020/3/7
|
||||||
*/
|
*/
|
||||||
private void connectToSSH(SSHConnectInfo sshConnectInfo) throws JSchException, IOException {
|
private void connectToSSH(SSHConnectInfo sshConnectInfo, SSHData webSSHData, WebSocket webSocket) throws JSchException, IOException {
|
||||||
Session session = null;
|
Session session = null;
|
||||||
Properties config = new Properties();
|
Properties config = new Properties();
|
||||||
config.put("StrictHostKeyChecking", "no");
|
config.put("StrictHostKeyChecking", "no");
|
||||||
//获取jsch的会话
|
//获取jsch的会话
|
||||||
JSch jSch = new JSch();
|
session = sshConnectInfo.getjSch().getSession(webSSHData.getUsername(), webSSHData.getHost(), webSSHData.getPort());
|
||||||
session = jSch.getSession(sshConnectInfo.username, sshConnectInfo.host, sshConnectInfo.port);
|
|
||||||
session.setConfig(config);
|
session.setConfig(config);
|
||||||
//设置密码
|
//设置密码
|
||||||
session.setPassword(sshConnectInfo.password);
|
session.setPassword(webSSHData.getPassword());
|
||||||
//连接 超时时间30s
|
//连接 超时时间30s
|
||||||
session.connect(30000);
|
session.connect(30000);
|
||||||
|
|
||||||
|
|
@ -124,32 +146,33 @@ public class SSHServiceImpl implements SSHService {
|
||||||
transToSSH(channel, "\r");
|
transToSSH(channel, "\r");
|
||||||
|
|
||||||
//读取终端返回的信息流
|
//读取终端返回的信息流
|
||||||
try (InputStream inputStream = channel.getInputStream()) {
|
InputStream inputStream = channel.getInputStream();
|
||||||
|
try {
|
||||||
//循环读取
|
//循环读取
|
||||||
byte[] buffer = new byte[1024];
|
byte[] buffer = new byte[1024];
|
||||||
int i = 0;
|
int i = 0;
|
||||||
//如果没有数据来,线程会一直阻塞在这个地方等待数据。
|
//如果没有数据来,线程会一直阻塞在这个地方等待数据。
|
||||||
while ((i = inputStream.read(buffer)) != -1) {
|
while ((i = inputStream.read(buffer)) != -1) {
|
||||||
sendMessage(Arrays.copyOfRange(buffer, 0, i));
|
sendMessage(webSocket, Arrays.copyOfRange(buffer, 0, i));
|
||||||
}
|
}
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
//断开连接后关闭会话
|
//断开连接后关闭会话
|
||||||
session.disconnect();
|
session.disconnect();
|
||||||
channel.disconnect();
|
channel.disconnect();
|
||||||
|
if (inputStream != null) {
|
||||||
|
inputStream.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendMessage(byte[] buffer){
|
|
||||||
message_list.add(buf_to_string(buffer));
|
|
||||||
message_list.add(System.lineSeparator());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String buf_to_string(byte[] buffer){
|
|
||||||
return new String(buffer, StandardCharsets.UTF_8);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description: 将消息转发到终端
|
* @Description: 将消息转发到终端
|
||||||
|
* @Param: [channel, data]
|
||||||
|
* @return: void
|
||||||
|
* @Author: NoCortY
|
||||||
|
* @Date: 2020/3/7
|
||||||
*/
|
*/
|
||||||
private void transToSSH(Channel channel, String command) throws IOException {
|
private void transToSSH(Channel channel, String command) throws IOException {
|
||||||
if (channel != null) {
|
if (channel != null) {
|
||||||
|
|
@ -158,91 +181,4 @@ public class SSHServiceImpl implements SSHService {
|
||||||
outputStream.flush();
|
outputStream.flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum Type{
|
|
||||||
connect("连接"),
|
|
||||||
command("命令"),
|
|
||||||
;
|
|
||||||
|
|
||||||
private String desc;
|
|
||||||
|
|
||||||
Type(String desc) {
|
|
||||||
this.desc = desc;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDesc() {
|
|
||||||
return desc;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDesc(String desc) {
|
|
||||||
this.desc = desc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class SSHConnectInfo{
|
|
||||||
public String host;
|
|
||||||
private JSch jSch;
|
|
||||||
private String username;
|
|
||||||
private String password;
|
|
||||||
private int port;
|
|
||||||
private Channel channel;
|
|
||||||
|
|
||||||
public Channel getChannel() {
|
|
||||||
return channel;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getHost() {
|
|
||||||
return host;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHost(String host) {
|
|
||||||
this.host = host;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setChannel(Channel channel) {
|
|
||||||
this.channel = channel;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SSHConnectInfo() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public SSHConnectInfo(JSch jSch, String username, String password, int port) {
|
|
||||||
this.jSch = jSch;
|
|
||||||
this.username = username;
|
|
||||||
this.password = password;
|
|
||||||
this.port = port;
|
|
||||||
}
|
|
||||||
|
|
||||||
public JSch getjSch() {
|
|
||||||
return jSch;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setjSch(JSch jSch) {
|
|
||||||
this.jSch = jSch;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUsername() {
|
|
||||||
return username;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUsername(String username) {
|
|
||||||
this.username = username;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPassword() {
|
|
||||||
return password;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPassword(String password) {
|
|
||||||
this.password = password;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getPort() {
|
|
||||||
return port;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPort(int port) {
|
|
||||||
this.port = port;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue