diff --git a/client+/neutrino-proxy-client-starter/Dockerfile b/client+/neutrino-proxy-client-starter/Dockerfile
index e2a41943..bfa84f56 100644
--- a/client+/neutrino-proxy-client-starter/Dockerfile
+++ b/client+/neutrino-proxy-client-starter/Dockerfile
@@ -9,7 +9,7 @@ RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN mkdir -p /root/neutrino-proxy/config
WORKDIR /root/neutrino-proxy
COPY ./target/neutrino-proxy-client.jar /root/neutrino-proxy/neutrino-proxy-client.jar
-COPY ./src/main/resources/app-copy.yml /root/neutrino-proxy/config/app.yml
+COPY src/main/resources/app-copy.yml /root/neutrino-proxy/config/app.yml
#VOLUME ["/root/neutrino-proxy"]
ENTRYPOINT ["java","-jar","neutrino-proxy-client.jar","config=./config/app.yml"]
diff --git a/client+/neutrino-proxy-client-starter/pom.xml b/client+/neutrino-proxy-client-starter/pom.xml
index 9c2a34ba..ae6e3488 100644
--- a/client+/neutrino-proxy-client-starter/pom.xml
+++ b/client+/neutrino-proxy-client-starter/pom.xml
@@ -4,8 +4,9 @@
4.0.0
io.github.javpower
neutrino-proxy-client-spring-boot-starter
- ${revision}
- jar
+ 2.0.1
+ neutrino-proxy-client-spring-boot-starter
+ a tool about easy neutrino-proxy-client
https://github.com/javpower/neutrino-proxy
@@ -28,7 +29,7 @@
- 2.3.2
+ 2.3.2
2.7.13
2.0.1
@@ -67,12 +68,6 @@
lombok
1.18.30
-
- net.dreamlu
- mica-auto
- ${mica-auto.vaersion}
- provided
-
com.jcraft
@@ -84,7 +79,12 @@
jzlib
1.1.3
-
+
+ net.dreamlu
+ mica-auto
+ ${mica-auto.version}
+ provided
+
@@ -116,9 +116,20 @@
maven-compiler-plugin
3.8.1
- 21
- 21
- UTF-8
+ 8
+ 8
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ 3.1.0
+
+
+
+ true
+
+
@@ -126,7 +137,7 @@
spring-boot-maven-plugin
${spring-boot.version}
- com.gc.easy.EasyHttpApplication
+ org.dromara.neutrinoproxy.client.starter.SpringProxyClient
true
@@ -197,5 +208,4 @@
-
diff --git a/client+/neutrino-proxy-client-starter/src/main/java/org/dromara/neutrinoproxy/client/starter/ssh/Test.java b/client+/neutrino-proxy-client-starter/src/main/java/org/dromara/neutrinoproxy/client/starter/ssh/Test.java
deleted file mode 100644
index 6ef517de..00000000
--- a/client+/neutrino-proxy-client-starter/src/main/java/org/dromara/neutrinoproxy/client/starter/ssh/Test.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package org.dromara.neutrinoproxy.client.starter.ssh;
-/**
- *
- * @author: gc.x
- * @date: 2024/1/21
- */
-public class Test {
- public static void main(String[] args) {
-
- // 添加SSH连接
- String sshId = SSHConnectionFactory.factory.addConnection("194.36.209.398", "root", "xxxxxx", 1234, 6379,"xx.xx.xx.xx");
- SSHConnectionFactory.factory.openTunnel(sshId);
- try {
- Thread.sleep(100000000);
- } catch (InterruptedException e) {
- throw new RuntimeException(e);
- }
- // 关闭SSH隧道
- SSHConnectionFactory.factory.closeTunnel(sshId);
-
- }
-}
diff --git a/client+/neutrino-proxy-client-starter/src/main/java/org/dromara/neutrinoproxy/client/starter/util/RemoteDeployUtil.java b/client+/neutrino-proxy-client-starter/src/main/java/org/dromara/neutrinoproxy/client/starter/util/RemoteDeployUtil.java
new file mode 100644
index 00000000..380ca75b
--- /dev/null
+++ b/client+/neutrino-proxy-client-starter/src/main/java/org/dromara/neutrinoproxy/client/starter/util/RemoteDeployUtil.java
@@ -0,0 +1,139 @@
+package org.dromara.neutrinoproxy.client.starter.util;
+
+import com.jcraft.jsch.*;
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.*;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicLong;
+/**
+ * 远程发布工具类
+ * @author: gc.x
+ * @date: 2024/1/21
+ */
+@Slf4j
+public class RemoteDeployUtil {
+
+ public static void uploadAndStartJar(List localFilePaths, String remoteDirectory, String remoteStartCommand,
+ String remoteUsername, String remoteHost, String remotePassword) {
+ log.info("Start=================");
+ JSch jsch = new JSch();
+ Session session = null;
+ ChannelSftp channelSftp = null;
+ try {
+ session = jsch.getSession(remoteUsername, remoteHost, 22);
+ session.setPassword(remotePassword);
+ session.setConfig("StrictHostKeyChecking", "no");
+ session.connect();
+ channelSftp = (ChannelSftp) session.openChannel("sftp");
+ channelSftp.connect();
+ // 创建远程目录(如果不存在)
+ try {
+ channelSftp.cd(remoteDirectory);
+ } catch (SftpException e) {
+ channelSftp.mkdir(remoteDirectory);
+ channelSftp.cd(remoteDirectory);
+ }
+ // 上传本地文件到远程服务器指定目录
+ for (String localFilePath : localFilePaths) {
+ uploadFileWithProgress(channelSftp, localFilePath, remoteDirectory);
+ }
+ channelSftp.disconnect();
+ // 执行远程命令启动jar包
+ log.info("Command:"+remoteStartCommand);
+ ChannelExec channelExec = (ChannelExec) session.openChannel("exec");
+ channelExec.setCommand(remoteStartCommand);
+ ByteArrayOutputStream commandOutput = new ByteArrayOutputStream();
+ channelExec.setOutputStream(commandOutput);
+ channelExec.connect();
+ // 使用新线程读取并打印命令输出
+ Thread outputThread = new Thread(() -> {
+ try (BufferedReader reader = new BufferedReader(new InputStreamReader(channelExec.getInputStream()))) {
+ String line;
+ while ((line = reader.readLine()) != null) {
+ System.out.println(line);
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ });
+ outputThread.start();
+ // 等待命令执行完成
+ while (!channelExec.isClosed()) {
+ Thread.sleep(1000);
+ }
+ // 等待命令输出线程结束
+ outputThread.join();
+ channelExec.disconnect();
+ log.info("=================End");
+ } catch (JSchException | SftpException | InterruptedException | IOException e) {
+ e.printStackTrace();
+ } finally {
+ if (channelSftp != null) {
+ channelSftp.disconnect();
+ }
+ if (session != null) {
+ session.disconnect();
+ }
+ }
+ }
+
+ private static void uploadFileWithProgress(ChannelSftp channelSftp, String localFilePath, String remoteDirectory) throws SftpException, IOException {
+ File file = new File(localFilePath);
+ String fileName = file.getName();
+ String remoteFilePath = remoteDirectory + File.separator + fileName;
+ AtomicLong uploadedSize = new AtomicLong();
+ try (InputStream inputStream = new FileInputStream(file)) {
+ // 如果远程目录已经存在同名文件,则先备份原文件
+ if (fileExists(channelSftp, remoteFilePath)) {
+ backupRemoteFile(channelSftp, remoteFilePath);
+ }
+ channelSftp.put(inputStream, remoteFilePath, new SftpProgressMonitor() {
+ @Override
+ public void init(int op, String src, String dest, long max) {
+ // 初始化回调函数,可以做一些准备工作
+ }
+ @Override
+ public void end() {
+ // 上传结束回调函数,可以做一些清理工作
+ }
+ @Override
+ public boolean count(long count) {
+ uploadedSize.addAndGet(count);
+ // 计算上传进度
+ int progress = (int) ((uploadedSize.get() * 100) / file.length());
+
+ // 每上传 10% 显示一次进度,可根据实际情况调整
+ if (progress % 10 == 0) {
+ log.info(fileName+"-----Upload progress: " + progress + "%");
+ }
+ // 返回 true 则继续传输,否则中止传输
+ return true;
+ }
+ }, ChannelSftp.RESUME);
+ }
+ }
+
+ private static boolean fileExists(ChannelSftp channelSftp, String remoteFilePath) {
+ try {
+ channelSftp.lstat(remoteFilePath);
+ return true;
+ } catch (SftpException e) {
+ return false;
+ }
+ }
+
+ private static void backupRemoteFile(ChannelSftp channelSftp, String remoteFilePath) throws SftpException {
+ LocalDateTime now = LocalDateTime.now();
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
+ String backupTime = now.format(formatter);
+ String backupFilePath = remoteFilePath + "." + backupTime;
+ channelSftp.rename(remoteFilePath, backupFilePath);
+ log.info("Remote file already exists. Backing up the original file as: " + backupFilePath);
+ }
+}
+
+
+
diff --git a/client+/neutrino-proxy-client-starter/src/main/java/org/dromara/neutrinoproxy/client/starter/util/SSHClient.java b/client+/neutrino-proxy-client-starter/src/main/java/org/dromara/neutrinoproxy/client/starter/util/SSHClient.java
new file mode 100644
index 00000000..aad352dc
--- /dev/null
+++ b/client+/neutrino-proxy-client-starter/src/main/java/org/dromara/neutrinoproxy/client/starter/util/SSHClient.java
@@ -0,0 +1,122 @@
+package org.dromara.neutrinoproxy.client.starter.util;
+
+import com.jcraft.jsch.*;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.nio.file.Paths;
+import java.util.Scanner;
+/**
+ * 简易ssh客户端
+ * @author: gc.x
+ * @date: 2024/1/21
+ */
+public class SSHClient {
+
+ private static final String COMMAND_UPLOAD = "upload";
+ private Session session;
+
+ public void connect(String remoteHost, String remoteUsername, String remotePassword) {
+ JSch jsch = new JSch();
+ try {
+ session = jsch.getSession(remoteUsername, remoteHost, 22);
+ session.setPassword(remotePassword);
+ session.setConfig("StrictHostKeyChecking", "no");
+ session.connect();
+ System.out.println("Connected to " + remoteHost);
+ } catch (JSchException e) {
+ e.printStackTrace();
+ }
+ }
+ public void startShell() {
+ if (session == null || !session.isConnected()) {
+ System.out.println("Not connected to a remote host");
+ return;
+ }
+ Channel channel;
+ try {
+ channel = session.openChannel("shell");
+ channel.connect();
+ Scanner scanner = new Scanner(System.in);
+ String line;
+ while (true) {
+ System.out.print("$ ");
+ line = scanner.nextLine();
+ if (line.equals("exit")) {
+ break;
+ } else if (line.startsWith(COMMAND_UPLOAD)) {
+ processUploadCommand(line);
+ } else {
+ System.out.println("Executing command: " + line);
+ executeCommand(line);
+ }
+ }
+ } catch (JSchException e) {
+ e.printStackTrace();
+ }finally {
+ disconnect();
+ }
+ }
+
+ public void disconnect() {
+ if (session != null && session.isConnected()) {
+ session.disconnect();
+ System.out.println("Disconnected from remote host");
+ }
+ }
+
+ private void processUploadCommand(String command) {
+ String[] parts = command.split("\\s+");
+ if (parts.length < 3) {
+ System.out.println("Invalid upload command");
+ return;
+ }
+ String localFilePath = parts[1];
+ String remoteDirectory = parts[2];
+ String remoteFilename = Paths.get(localFilePath).getFileName().toString();
+ if (parts.length >= 4) {
+ remoteFilename = parts[3];
+ }
+ uploadFile(localFilePath, remoteDirectory, remoteFilename);
+ }
+
+ private void uploadFile(String localFilePath, String remoteDirectory, String remoteFilename) {
+ ChannelSftp channelSftp = null;
+ try {
+ channelSftp = (ChannelSftp) session.openChannel("sftp");
+ channelSftp.connect();
+ channelSftp.cd(remoteDirectory);
+ System.out.println("Uploading file: " + localFilePath + " to: " + remoteDirectory + "/" + remoteFilename);
+ channelSftp.put(localFilePath, remoteFilename);
+ System.out.println("File uploaded successfully");
+ } catch (JSchException | SftpException e) {
+ e.printStackTrace();
+ } finally {
+ if (channelSftp != null) {
+ channelSftp.disconnect();
+ }
+ }
+ }
+ private void executeCommand(String command) {
+ ChannelExec channelExec = null;
+
+ try {
+ channelExec = (ChannelExec) session.openChannel("exec");
+ channelExec.setCommand(command);
+ BufferedReader in = new BufferedReader(new InputStreamReader(channelExec.getInputStream()));
+ channelExec.connect();
+ String line;
+ while ((line = in.readLine()) != null) {
+ System.out.println(line);
+ }
+ channelExec.disconnect();
+ } catch (JSchException | IOException e) {
+ e.printStackTrace();
+ } finally {
+ if (channelExec != null) {
+ channelExec.disconnect();
+ }
+ }
+ }
+}
diff --git a/client+/neutrino-proxy-client-starter/src/main/resources/test.jks b/client+/neutrino-proxy-client-starter/src/main/resources/test.jks
index 3a4d1ad8..e69de29b 100644
Binary files a/client+/neutrino-proxy-client-starter/src/main/resources/test.jks and b/client+/neutrino-proxy-client-starter/src/main/resources/test.jks differ