mirror of
https://gitee.com/wujiawei1207537021/wu-lazy-cloud-network.git
synced 2026-02-04 23:15:52 +08:00
Compare commits
20 Commits
d5561b341c
...
1.3.6-JDK2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3f4a05ba5c | ||
|
|
a42694af58 | ||
|
|
eee7b9e511 | ||
|
|
3b231083fe | ||
|
|
8938bfca6a | ||
|
|
55ca1974da | ||
|
|
f28efb5fe8 | ||
|
|
fc05d9a09b | ||
|
|
0aaf8a47ec | ||
|
|
eab0dacaa9 | ||
|
|
ae962c7393 | ||
|
|
4e4dc0dc78 | ||
|
|
85a44c1665 | ||
|
|
5aa9ca4b85 | ||
|
|
43193138cd | ||
|
|
abaea6c2ca | ||
|
|
d8285fd074 | ||
|
|
8d845c64c1 | ||
|
|
b8bfe15368 | ||
|
|
6c496ce7da |
35
pom.xml
35
pom.xml
@@ -8,12 +8,12 @@
|
||||
<parent>
|
||||
<artifactId>wu-framework-parent</artifactId>
|
||||
<groupId>top.wu2020</groupId>
|
||||
<version>1.3.4-JDK24-SNAPSHOT</version>
|
||||
<version>1.3.6-JDK24</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>wu-lazy-cloud-network</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<version>1.3.4-JDK24-SNAPSHOT</version>
|
||||
<version>1.3.6-JDK24</version>
|
||||
<description>云上云下</description>
|
||||
<name>wlcn项目</name>
|
||||
<url>https://gitee.com/wujiawei1207537021/wu-lazy-cloud-network</url>
|
||||
@@ -45,7 +45,7 @@
|
||||
<module>wu-lazy-cloud-heartbeat-dns</module>
|
||||
<module>wu-lazy-cloud-heartbeat-protocol-proxy</module>
|
||||
|
||||
<!-- 样例 -->
|
||||
<!-- 启动类 -->
|
||||
<module>wu-lazy-cloud-heartbeat-start</module>
|
||||
</modules>
|
||||
|
||||
@@ -93,7 +93,7 @@
|
||||
<dependency>
|
||||
<groupId>top.wu2020</groupId>
|
||||
<artifactId>wu-framework-dependencies</artifactId>
|
||||
<version>1.3.4-JDK24-SNAPSHOT</version>
|
||||
<version>1.3.6-JDK24</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -102,5 +102,32 @@
|
||||
|
||||
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>windows</id>
|
||||
<activation>
|
||||
<os>
|
||||
<family>windows</family>
|
||||
</os>
|
||||
</activation>
|
||||
<properties>
|
||||
<packaging.type>msi</packaging.type>
|
||||
</properties>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>mac</id>
|
||||
<activation>
|
||||
<os>
|
||||
<family>mac</family>
|
||||
</os>
|
||||
</activation>
|
||||
<properties>
|
||||
<packaging.type>dmg</packaging.type>
|
||||
</properties>
|
||||
</profile>
|
||||
<!-- 可以添加更多针对不同操作系统的 profile -->
|
||||
</profiles>
|
||||
|
||||
|
||||
|
||||
</project>
|
||||
14
version.md
14
version.md
@@ -1,6 +1,6 @@
|
||||
### 版本更新
|
||||
#### 1.2.3-JDK17-SNAPSHOT
|
||||
【fix】修正流量计算保存两位小数
|
||||
[fix]修正流量计算保存两位小数
|
||||
[fix] 添加配置spring.lazy.netty.enable 控制是否开启客户端默认是自动连接服务端的 需要手动关闭
|
||||
|
||||
|
||||
@@ -48,4 +48,14 @@
|
||||
#### 1.3.3-JDK24
|
||||
[fix] 优化代理日志记录性能影响,支持自定义spring.lazy.netty.protocol.proxy.sendMsgQueue、sendMsgQueue
|
||||
[add] 服务上架dockerhub
|
||||
#### 下一版本计划
|
||||
|
||||
#### 1.3.4-JDK24
|
||||
[fix]支持Mac平台应用安装,默认wlcn-client、wlcn-server 使用本地h2作为数据存储
|
||||
[fix]UI优化
|
||||
[add]添加区域管理
|
||||
[add]默认客户端ID为当前设备唯一标识
|
||||
|
||||
|
||||
#### 下一版本计划
|
||||
[add] 流媒体抓取
|
||||
[add] 监听本地网卡进行代理
|
||||
@@ -237,5 +237,5 @@ CMD ["nginx", "-g", "daemon off;"]
|
||||
---
|
||||
|
||||
**版本**: 1.0.0
|
||||
**更新时间**: 2024年12月
|
||||
**更新时间**: 2025年8月
|
||||
**维护者**: 吴佳伟
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "wu-lazy-cloud-network-website",
|
||||
"version": "1.3.1",
|
||||
"version": "1.3.3",
|
||||
"description": "Wu-Lazy-Cloud-Network 官方网站",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
Before Width: | Height: | Size: 185 B After Width: | Height: | Size: 185 B |
@@ -19,6 +19,10 @@
|
||||
</nav>
|
||||
|
||||
<div class="header-actions">
|
||||
<a href="http://demo-wlcn.wu-framework.cn/wlcn/index.html#/login" target="_blank" class="btn btn-outline">
|
||||
<el-icon><Platform /></el-icon>
|
||||
体验地址
|
||||
</a>
|
||||
<a href="https://gitee.com/wujiawei1207537021/wu-lazy-cloud-network" target="_blank" class="btn btn-outline">
|
||||
<el-icon><Platform /></el-icon>
|
||||
Gitee
|
||||
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
@@ -51,7 +51,7 @@
|
||||
|
||||
<div class="intro-stats">
|
||||
<div class="stat-item">
|
||||
<div class="stat-number">1.3.1</div>
|
||||
<div class="stat-number">1.3.3</div>
|
||||
<div class="stat-label">当前版本</div>
|
||||
</div>
|
||||
<div class="stat-item">
|
||||
@@ -239,8 +239,8 @@
|
||||
<div class="timeline-item completed">
|
||||
<div class="timeline-marker"></div>
|
||||
<div class="timeline-content">
|
||||
<h3>v1.3.1 (当前版本)</h3>
|
||||
<p class="timeline-date">2024年12月</p>
|
||||
<h3>v1.3.3 (当前版本)</h3>
|
||||
<p class="timeline-date">2025年8月</p>
|
||||
<ul>
|
||||
<li>升级到 JDK 24 和 Spring Boot 3.5.0</li>
|
||||
<li>优化网络性能和稳定性</li>
|
||||
@@ -25,7 +25,7 @@
|
||||
<div class="version-details">
|
||||
<div class="detail-item">
|
||||
<span class="label">发布日期</span>
|
||||
<span class="value">2024年12月</span>
|
||||
<span class="value">2025年8月</span>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<span class="label">JDK 版本</span>
|
||||
@@ -26,7 +26,7 @@
|
||||
</div>
|
||||
<div class="hero-stats">
|
||||
<div class="stat-item">
|
||||
<div class="stat-number">1.3.1</div>
|
||||
<div class="stat-number">1.3.3</div>
|
||||
<div class="stat-label">当前版本</div>
|
||||
</div>
|
||||
<div class="stat-item">
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>top.wu2020</groupId>
|
||||
<artifactId>wu-lazy-cloud-network</artifactId>
|
||||
<version>1.3.4-JDK24-SNAPSHOT</version>
|
||||
<version>1.3.6-JDK24</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
<properties>
|
||||
<maven.compiler.source>24</maven.compiler.source>
|
||||
<maven.compiler.target>24</maven.compiler.target>
|
||||
<javafx.version>24</javafx.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
@@ -72,6 +73,15 @@
|
||||
<version>${wu-database-lazy-orm-plus-starter.version}</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- JavaFX Web 模块(包含 javafx.scene.web.JSObject) -->
|
||||
<!-- 窗口 -->
|
||||
<dependency>
|
||||
<groupId>top.wu2020</groupId>
|
||||
<artifactId>wu-framework-javafx-spring-starter</artifactId>
|
||||
<version>1.3.6-JDK24</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
package org.framework.lazy.cloud.network.heartbeat.client.config;
|
||||
|
||||
import jdk.jfr.Description;
|
||||
import lombok.Data;
|
||||
import org.framework.lazy.cloud.network.heartbeat.common.enums.ProtocolType;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.wu.framework.core.NormalUsedString;
|
||||
import org.wu.framework.core.utils.ComputerUniqueIdUtil;
|
||||
|
||||
/**
|
||||
* netty 客户服务端地址配置属性
|
||||
@@ -30,20 +32,19 @@ public class NettyClientProperties {
|
||||
/**
|
||||
* 客户端ID 如:1024
|
||||
*/
|
||||
private String clientId;
|
||||
@Description("客户端ID,默认当前机器唯一序列号")
|
||||
private String clientId = ComputerUniqueIdUtil.generateUniqueId();
|
||||
|
||||
/**
|
||||
* 协议类型
|
||||
*/
|
||||
private ProtocolType protocolType = ProtocolType.TCP;
|
||||
/**
|
||||
*
|
||||
* 令牌key
|
||||
*/
|
||||
private String appKey;
|
||||
|
||||
/**
|
||||
*
|
||||
* 令牌密钥
|
||||
*/
|
||||
private String appSecret;
|
||||
|
||||
@@ -9,69 +9,64 @@ import org.framework.lazy.cloud.network.heartbeat.common.enums.ProtocolType;
|
||||
import org.wu.framework.core.NormalUsedString;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* describe 服务端配置信息
|
||||
* describe 服务端配置信息
|
||||
*
|
||||
* @author Jia wei Wu
|
||||
* @date 2024/04/03 03:00 下午
|
||||
* @see org.wu.framework.lazy.orm.core.persistence.reverse.lazy.ddd.DefaultDDDLazyDomain
|
||||
* @see org.wu.framework.lazy.orm.core.persistence.reverse.lazy.ddd.DefaultDDDLazyDomain
|
||||
**/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@Schema(title = "lazy_netty_server_properties",description = "服务端配置信息")
|
||||
@Schema(title = "lazy_netty_server_properties", description = "服务端配置信息")
|
||||
public class LazyNettyServerProperties {
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* 客户身份ID
|
||||
*/
|
||||
@Schema(description ="客户身份ID",name ="clientId",example = "")
|
||||
@Schema(description = "客户身份ID", name = "clientId", example = "")
|
||||
private String clientId;
|
||||
|
||||
/**
|
||||
*
|
||||
* 状态(on_line、off_line)
|
||||
*/
|
||||
@Schema(description ="状态(on_line、off_line)",name ="connectStatus",example = "")
|
||||
@Schema(description = "状态(on_line、off_line)", name = "connectStatus", example = "")
|
||||
private NettyClientStatus connectStatus;
|
||||
|
||||
/**
|
||||
*
|
||||
* 创建时间
|
||||
*/
|
||||
@Schema(description ="创建时间",name ="createTime",example = "")
|
||||
@Schema(description = "创建时间", name = "createTime", example = "")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* 服务端host
|
||||
*/
|
||||
@Schema(description ="服务端host",name ="inetHost",example = "")
|
||||
@Schema(description = "服务端host", name = "inetHost", example = "")
|
||||
private String inetHost;
|
||||
|
||||
/**
|
||||
*
|
||||
* 服务端端口
|
||||
*/
|
||||
@Schema(description ="服务端端口",name ="inetPort",example = "")
|
||||
@Schema(description = "服务端端口", name = "inetPort", example = "")
|
||||
private Integer inetPort;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* 类型(配置、DB)
|
||||
*/
|
||||
@Schema(description ="类型(配置、DB)",name ="type",example = "")
|
||||
@Schema(description = "类型(配置、DB)", name = "type", example = "")
|
||||
private PropertiesType type;
|
||||
|
||||
/**
|
||||
* 协议类型
|
||||
* 默认tcp
|
||||
*/
|
||||
@Schema(description = "协议类型", name = "protocol_type", example = "")
|
||||
private ProtocolType protocolType;
|
||||
private ProtocolType protocolType = ProtocolType.TCP;
|
||||
/**
|
||||
* 令牌key
|
||||
*/
|
||||
@@ -84,10 +79,9 @@ public class LazyNettyServerProperties {
|
||||
@Schema(description = "令牌密钥", name = "appSecret", example = "")
|
||||
private String appSecret;
|
||||
/**
|
||||
*
|
||||
* 更新时间
|
||||
*/
|
||||
@Schema(description ="更新时间",name ="updateTime",example = "")
|
||||
@Schema(description = "更新时间", name = "updateTime", example = "")
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
}
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>top.wu2020</groupId>
|
||||
<artifactId>wu-lazy-cloud-network</artifactId>
|
||||
<version>1.3.4-JDK24-SNAPSHOT</version>
|
||||
<version>1.3.6-JDK24</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>wu-lazy-cloud-heartbeat-common</artifactId>
|
||||
@@ -56,8 +56,15 @@
|
||||
<dependency>
|
||||
<groupId>top.wu2020</groupId>
|
||||
<artifactId>wu-framework-queue</artifactId>
|
||||
<version>1.3.4-JDK24-SNAPSHOT</version>
|
||||
<version>1.3.6-JDK24</version>
|
||||
</dependency>
|
||||
<!-- log -->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>top.wu2020</groupId>-->
|
||||
<!-- <artifactId>wu-framework-log-spring-starter</artifactId>-->
|
||||
<!-- <version>1.3.6-JDK24</version>-->
|
||||
<!-- </dependency>-->
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>top.wu2020</groupId>
|
||||
<artifactId>wu-lazy-cloud-network</artifactId>
|
||||
<version>1.3.4-JDK24-SNAPSHOT</version>
|
||||
<version>1.3.6-JDK24</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>top.wu2020</groupId>
|
||||
<artifactId>wu-lazy-cloud-network</artifactId>
|
||||
<version>1.3.4-JDK24-SNAPSHOT</version>
|
||||
<version>1.3.6-JDK24</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
@@ -81,7 +81,7 @@
|
||||
<dependency>
|
||||
<groupId>top.wu2020</groupId>
|
||||
<artifactId>wu-framework-queue</artifactId>
|
||||
<version>1.3.4-JDK24-SNAPSHOT</version>
|
||||
<version>1.3.6-JDK24</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
@@ -0,0 +1,210 @@
|
||||
package org.framework.lazy.cloud.network.heartbeat.protocol.test1;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.*;
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
import io.netty.channel.socket.nio.NioSocketChannel;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
/**
|
||||
* 流量拦截处理器:执行拦截策略,处理流量转发/丢弃/修改
|
||||
*/
|
||||
public class TrafficInterceptHandler extends ChannelDuplexHandler {
|
||||
private final TrafficInterceptor.InterceptStrategy strategy;
|
||||
private Channel forwardChannel; // 转发通道(连接原目标服务器)
|
||||
private InetSocketAddress originalTarget; // 流量的原目标地址(需解析获取)
|
||||
|
||||
public TrafficInterceptHandler(TrafficInterceptor.InterceptStrategy strategy) {
|
||||
this.strategy = strategy;
|
||||
}
|
||||
|
||||
/**
|
||||
* 客户端连接建立时,解析原目标地址(关键:透明代理需知道流量要发往的原目标)
|
||||
* 注:原目标地址的解析方式需根据场景调整(如通过路由表、ARP 缓存、或 RAW socket 抓包解析 IP 头部)
|
||||
*/
|
||||
@Override
|
||||
public void channelActive(ChannelHandlerContext ctx) throws Exception {
|
||||
InetSocketAddress clientAddr = (InetSocketAddress) ctx.channel().remoteAddress();
|
||||
System.out.println("拦截到新连接:客户端 " + clientAddr);
|
||||
|
||||
// 关键步骤:解析流量的原目标地址(此处为模拟,实际需通过以下方式获取)
|
||||
// 方式 1:若拦截器作为网关,原目标地址即客户端请求的目标 IP:Port(需解析应用层协议,如 HTTP Host 头)
|
||||
// 方式 2:用 RAW socket 抓包,解析 IP 头部的「目的地址」字段(推荐,适用于所有 TCP 流量)
|
||||
// 方式 3:通过 iptables 端口转发,原目标地址由 iptables 传递(Linux 环境)
|
||||
// 此处模拟:假设原目标是百度服务器(实际需动态解析)
|
||||
originalTarget = new InetSocketAddress("220.181.38.251", 80);
|
||||
|
||||
// 根据策略初始化转发通道(若需要转发)
|
||||
if (strategy == TrafficInterceptor.InterceptStrategy.FORWARD || strategy == TrafficInterceptor.InterceptStrategy.MODIFY) {
|
||||
initForwardChannel(ctx);
|
||||
}
|
||||
|
||||
super.channelActive(ctx);
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化转发通道:连接原目标服务器,实现透明转发
|
||||
*/
|
||||
private void initForwardChannel(ChannelHandlerContext ctx) {
|
||||
Bootstrap bootstrap = new Bootstrap()
|
||||
.group(ctx.channel().eventLoop()) // 复用客户端事件循环组,性能更优
|
||||
.channel(NioSocketChannel.class)
|
||||
.option(io.netty.channel.ChannelOption.SO_KEEPALIVE, true)
|
||||
.handler(new ChannelDuplexHandler() {
|
||||
// 接收原目标服务器的响应,转发回客户端
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext forwardCtx, Object msg) throws Exception {
|
||||
ByteBuf response = (ByteBuf) msg;
|
||||
System.out.printf("收到原目标 %s 响应,长度:%d 字节%n", originalTarget, response.readableBytes());
|
||||
|
||||
// 若策略是「修改流量」,则修改响应内容
|
||||
if (strategy == TrafficInterceptor.InterceptStrategy.MODIFY) {
|
||||
modifyData(response, false); // false 表示修改响应流量
|
||||
}
|
||||
|
||||
// 转发响应到客户端
|
||||
ctx.channel().writeAndFlush(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelInactive(ChannelHandlerContext forwardCtx) throws Exception {
|
||||
System.out.println("转发通道断开:原目标 " + originalTarget);
|
||||
ctx.channel().close(); // 转发通道断开,关闭客户端连接
|
||||
}
|
||||
});
|
||||
|
||||
// 连接原目标服务器
|
||||
bootstrap.connect(originalTarget).addListener((ChannelFutureListener) future -> {
|
||||
if (future.isSuccess()) {
|
||||
forwardChannel = future.channel();
|
||||
System.out.println("成功连接原目标:" + originalTarget);
|
||||
} else {
|
||||
System.err.println("连接原目标失败:" + originalTarget + ",原因:" + future.cause().getMessage());
|
||||
ctx.channel().close();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 拦截客户端发送的流量(出站流量)
|
||||
*/
|
||||
@Override
|
||||
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
|
||||
ByteBuf request = (ByteBuf) msg;
|
||||
InetSocketAddress clientAddr = (InetSocketAddress) ctx.channel().remoteAddress();
|
||||
System.out.printf("拦截到客户端 %s 发送的流量,长度:%d 字节%n", clientAddr, request.readableBytes());
|
||||
|
||||
switch (strategy) {
|
||||
case DROP:
|
||||
// 丢弃流量,释放缓冲区
|
||||
request.release();
|
||||
System.out.println("已丢弃该流量(策略:DROP)");
|
||||
break;
|
||||
|
||||
case MODIFY:
|
||||
// 修改流量内容(示例:在 HTTP 请求头添加自定义字段)
|
||||
modifyData(request, true); // true 表示修改请求流量
|
||||
System.out.println("已修改流量,准备转发");
|
||||
// fall through 到 FORWARD 逻辑
|
||||
case FORWARD:
|
||||
// 转发流量到原目标服务器
|
||||
if (forwardChannel != null && forwardChannel.isActive()) {
|
||||
forwardChannel.writeAndFlush(msg).addListener((ChannelFutureListener) future -> {
|
||||
if (!future.isSuccess()) {
|
||||
System.err.println("流量转发失败:" + future.cause().getMessage());
|
||||
ctx.channel().close();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
request.release();
|
||||
System.err.println("转发通道未就绪,丢弃流量");
|
||||
}
|
||||
break;
|
||||
|
||||
case LOG_ONLY:
|
||||
// 仅记录日志,不拦截,直接放行(透传流量)
|
||||
super.write(ctx, msg, promise);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改流量内容(示例:修改 HTTP 请求/响应)
|
||||
* @param data 要修改的 ByteBuf 数据
|
||||
* @param isRequest 是否为请求流量(true:请求,false:响应)
|
||||
*/
|
||||
private void modifyData(ByteBuf data, boolean isRequest) {
|
||||
// 示例:在 HTTP 请求头添加 X-Intercepted: true 字段
|
||||
if (isRequest) {
|
||||
// 切换为读模式,读取 HTTP 头
|
||||
data.markReaderIndex();
|
||||
byte[] temp = new byte[data.readableBytes()];
|
||||
data.readBytes(temp);
|
||||
String content = new String(temp);
|
||||
|
||||
// 找到 HTTP 头的结束位置("\r\n\r\n"),插入自定义字段
|
||||
if (content.contains("\r\n\r\n")) {
|
||||
content = content.replace("\r\n\r\n", "\r\nX-Intercepted: true\r\n\r\n");
|
||||
// 重置 ByteBuf,写入修改后的数据
|
||||
data.resetReaderIndex();
|
||||
data.clear();
|
||||
data.writeBytes(content.getBytes());
|
||||
System.out.println("已修改请求流量:添加 X-Intercepted 头");
|
||||
}
|
||||
} else {
|
||||
// 示例:修改 HTTP 响应的内容
|
||||
data.markReaderIndex();
|
||||
byte[] temp = new byte[data.readableBytes()];
|
||||
data.readBytes(temp);
|
||||
String content = new String(temp);
|
||||
if (content.contains("<body>")) {
|
||||
content = content.replace("<body>", "<body><h1>流量已被 Netty 拦截并修改</h1>");
|
||||
data.resetReaderIndex();
|
||||
data.clear();
|
||||
data.writeBytes(content.getBytes());
|
||||
System.out.println("已修改响应流量:添加拦截提示");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 拦截客户端接收的流量(响应流量)
|
||||
*/
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
||||
// 若策略为「仅记录日志」,直接放行;其他策略已在转发通道中处理
|
||||
if (strategy == TrafficInterceptor.InterceptStrategy.LOG_ONLY) {
|
||||
ByteBuf data = (ByteBuf) msg;
|
||||
System.out.printf("记录流量:客户端接收数据,长度:%d 字节%n", data.readableBytes());
|
||||
super.channelRead(ctx, msg);
|
||||
} else {
|
||||
((ByteBuf) msg).release(); // 已在转发通道中处理,此处释放缓冲区
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 连接断开时,关闭转发通道
|
||||
*/
|
||||
@Override
|
||||
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
|
||||
System.out.println("连接断开:客户端 " + ctx.channel().remoteAddress());
|
||||
if (forwardChannel != null && forwardChannel.isActive()) {
|
||||
forwardChannel.close();
|
||||
}
|
||||
super.channelInactive(ctx);
|
||||
}
|
||||
|
||||
/**
|
||||
* 异常处理:关闭所有连接
|
||||
*/
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
||||
System.err.println("流量拦截异常:" + cause.getMessage());
|
||||
ctx.close();
|
||||
if (forwardChannel != null && forwardChannel.isActive()) {
|
||||
forwardChannel.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
package org.framework.lazy.cloud.network.heartbeat.protocol.test1;
|
||||
|
||||
import io.netty.bootstrap.ServerBootstrap;
|
||||
import io.netty.channel.*;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
||||
import io.netty.handler.logging.LogLevel;
|
||||
import io.netty.handler.logging.LoggingHandler;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.SocketException;
|
||||
import java.util.Enumeration;
|
||||
|
||||
/**
|
||||
* 网络流量拦截器:绑定指定网卡,拦截该网卡的所有 TCP 流量,支持转发/丢弃/修改
|
||||
*/
|
||||
public class TrafficInterceptor {
|
||||
// 绑定的网卡 IP(必须是本地网卡已配置的 IP)
|
||||
private final String bindIp;
|
||||
// 拦截策略(可自定义:转发、丢弃、修改等)
|
||||
private final InterceptStrategy strategy;
|
||||
|
||||
// Netty 事件循环组
|
||||
private EventLoopGroup bossGroup;
|
||||
private EventLoopGroup workerGroup;
|
||||
|
||||
/**
|
||||
* 构造拦截器
|
||||
* @param bindIp 绑定的网卡 IP(如 192.168.1.100)
|
||||
* @param strategy 拦截策略
|
||||
*/
|
||||
public TrafficInterceptor(String bindIp, InterceptStrategy strategy) {
|
||||
this.bindIp = bindIp;
|
||||
this.strategy = strategy;
|
||||
validateBindIp(bindIp);
|
||||
}
|
||||
|
||||
/**
|
||||
* 启动拦截器(监听绑定网卡的所有 TCP 端口,实际通过端口复用实现)
|
||||
* 注:全端口监听需操作系统支持,或通过「端口范围监听」模拟(此处用 1-65535 端口范围)
|
||||
*/
|
||||
public void start() throws InterruptedException {
|
||||
bossGroup = new NioEventLoopGroup(1);
|
||||
workerGroup = new NioEventLoopGroup();
|
||||
|
||||
try {
|
||||
// 核心:启动服务端,绑定网卡 IP,监听所有 TCP 端口(模拟全端口拦截)
|
||||
// 实际生产中可优化为:监听常用端口 + 动态端口,或用 RAW socket 直接抓包
|
||||
ServerBootstrap bootstrap = new ServerBootstrap()
|
||||
.group(bossGroup, workerGroup)
|
||||
.channel(NioServerSocketChannel.class)
|
||||
.localAddress(new InetSocketAddress(bindIp, 0)) // 端口 0 表示随机端口,实际通过端口复用扩展
|
||||
.option(ChannelOption.SO_REUSEADDR, true) // 允许端口复用(关键)
|
||||
.option(ChannelOption.SO_BACKLOG, 1024)
|
||||
.childOption(ChannelOption.SO_KEEPALIVE, true)
|
||||
.handler(new LoggingHandler(LogLevel.INFO)) // 日志打印(可选)
|
||||
.childHandler(new ChannelInitializer<SocketChannel>() {
|
||||
@Override
|
||||
protected void initChannel(SocketChannel ch) throws Exception {
|
||||
ch.pipeline()
|
||||
.addLast(new LoggingHandler(LogLevel.DEBUG)) // 打印流量日志
|
||||
.addLast(new TrafficInterceptHandler(strategy)); // 核心拦截处理器
|
||||
}
|
||||
});
|
||||
|
||||
// 绑定网卡 IP,监听所有端口(模拟:实际需遍历端口或用 RAW socket,此处以常用端口为例)
|
||||
System.out.printf("流量拦截器启动成功!绑定网卡:%s,拦截策略:%s%n", bindIp, strategy);
|
||||
System.out.println("开始拦截该网卡的所有 TCP 流量...");
|
||||
|
||||
// 阻塞等待服务端关闭
|
||||
bootstrap.bind().sync().channel().closeFuture().sync();
|
||||
} finally {
|
||||
bossGroup.shutdownGracefully();
|
||||
workerGroup.shutdownGracefully();
|
||||
System.out.println("流量拦截器已关闭");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验绑定的网卡是否存在
|
||||
*/
|
||||
private void validateBindIp(String bindIp) {
|
||||
try {
|
||||
Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
|
||||
boolean exists = false;
|
||||
while (interfaces.hasMoreElements()) {
|
||||
NetworkInterface ni = interfaces.nextElement();
|
||||
Enumeration<java.net.InetAddress> addresses = ni.getInetAddresses();
|
||||
while (addresses.hasMoreElements()) {
|
||||
java.net.InetAddress addr = addresses.nextElement();
|
||||
if (addr.getHostAddress().equals(bindIp)) {
|
||||
exists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (exists) break;
|
||||
}
|
||||
if (!exists) {
|
||||
throw new IllegalArgumentException("绑定的网卡 IP " + bindIp + " 不存在于本地网卡");
|
||||
}
|
||||
} catch (SocketException e) {
|
||||
throw new RuntimeException("获取本地网卡信息失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 拦截策略枚举(可扩展)
|
||||
*/
|
||||
public enum InterceptStrategy {
|
||||
FORWARD("转发流量到原目标"),
|
||||
DROP("丢弃流量"),
|
||||
MODIFY("修改流量内容后转发"),
|
||||
LOG_ONLY("仅记录日志,不拦截");
|
||||
|
||||
private final String desc;
|
||||
|
||||
InterceptStrategy(String desc) {
|
||||
this.desc = desc;
|
||||
}
|
||||
|
||||
public String getDesc() {
|
||||
return desc;
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws InterruptedException {
|
||||
// 示例:绑定网卡 192.168.1.100,策略为「记录日志并转发」
|
||||
String bindIp = "192.168.3.6";
|
||||
TrafficInterceptor.InterceptStrategy strategy = TrafficInterceptor.InterceptStrategy.LOG_ONLY;
|
||||
new TrafficInterceptor(bindIp, strategy).start();
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>top.wu2020</groupId>
|
||||
<artifactId>wu-lazy-cloud-network</artifactId>
|
||||
<version>1.3.4-JDK24-SNAPSHOT</version>
|
||||
<version>1.3.6-JDK24</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>top.wu2020</groupId>
|
||||
<artifactId>wu-lazy-cloud-network</artifactId>
|
||||
<version>1.3.4-JDK24-SNAPSHOT</version>
|
||||
<version>1.3.6-JDK24</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
@@ -112,6 +112,12 @@
|
||||
<artifactId>wu-saas-share-platform-starter</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<!-- 窗口 -->
|
||||
<dependency>
|
||||
<groupId>top.wu2020</groupId>
|
||||
<artifactId>wu-framework-javafx-spring-starter</artifactId>
|
||||
<version>1.3.6-JDK24</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
.el-form-item[data-v-259b6f0a]{width:100%}.fl{float:left}.p0{padding:0!important}.application_item_class_[data-v-2aedb949],.role_edit_item{width:100%}.ve_container[data-v-7d12f6f5]{padding:20px}.el-form-item[data-v-7d12f6f5]{margin-bottom:20px}.el-form-item[data-v-cc75b748],.menu_edit_item[data-v-417eeee8]{width:100%}.ve_table .ve_table_page[data-v-11019130],.ve_table[data-v-11019130]{flex:1;display:flex;flex-direction:column}.ve_table .ve_table_page .ve_table_content[data-v-11019130]{flex:1}
|
||||
@@ -1 +1 @@
|
||||
.ve_404[data-v-3e778cc6]{height:100vh;width:100vw;position:relative;overflow:hidden;background:linear-gradient(90deg,#2f3640 23%,#181b20)}.moon[data-v-3e778cc6]{background:linear-gradient(90deg,#d0d0d0 48%,#919191);position:absolute;top:-30vh;left:-80vh;width:160vh;height:160%;content:"";border-radius:50%;box-shadow:0 0 30px -4px rgba(0,0,0,.5)}.moon__crater[data-v-3e778cc6]{position:absolute;content:"";border-radius:100%;background:linear-gradient(90deg,#7a7a7a 38%,#c3c3c3);opacity:.6}.moon__crater1[data-v-3e778cc6]{top:250px;left:500px;width:60px;height:180px}.moon__crater2[data-v-3e778cc6]{top:650px;left:340px;width:40px;height:80px;transform:rotate(55deg)}.moon__crater3[data-v-3e778cc6]{top:-20px;left:40px;width:65px;height:120px;transform:rotate(250deg)}.star[data-v-3e778cc6]{color:gray;position:absolute;width:10px;height:10px;content:"";border-radius:100%;transform:rotate(250deg);opacity:.4;animation-name:shimmer-3e778cc6;animation-duration:1.5s;animation-iteration-count:infinite;animation-direction:alternate}@keyframes shimmer-3e778cc6{0%{opacity:0}to{opacity:.7}}.star1[data-v-3e778cc6]{top:40%;left:50%;animation-delay:1s}.star2[data-v-3e778cc6]{top:60%;left:90%;animation-delay:3s}.star3[data-v-3e778cc6]{top:10%;left:70%;animation-delay:2s}.star4[data-v-3e778cc6]{top:90%;left:40%}.star5[data-v-3e778cc6]{top:20%;left:30%;animation-delay:.5s}.astronaut[data-v-3e778cc6]{position:absolute;width:60vw;height:100vh;top:0;right:0;z-index:0}.error[data-v-3e778cc6]{position:absolute;left:100px;top:400px;transform:translateY(-60%);font-family:Righteous,cursive;color:#363e49;z-index:1}.error__title[data-v-3e778cc6]{font-size:10em;font-weight:700;color:#d0d0d0;text-shadow:-5px -5px 0 rgba(0,0,0,.7);background-image:linear-gradient(90deg,#d0d0d0 48%,#919191);-webkit-background-clip:text;-webkit-text-fill-color:transparent}.error__subtitle[data-v-3e778cc6]{font-size:2em}.error__description[data-v-3e778cc6]{opacity:.5}.error__button[data-v-3e778cc6]{min-width:7em;margin-top:3em;margin-right:.5em;padding:.5em 2em;outline:none;border:2px solid #2f3640;background-color:transparent;border-radius:8em;color:#576375;cursor:pointer;transition-duration:.2s;font-size:.75em;font-family:Righteous,cursive}.error__button[data-v-3e778cc6]:hover{color:#21252c}.error__button--active[data-v-3e778cc6]{background-color:#409eff;border:2px solid #409eff;color:#fff}.error__button--active[data-v-3e778cc6]:hover{box-shadow:0 0 8px 0 rgba(0,0,0,.5);color:#fff}.ve_container[data-v-6caddbfd]{position:absolute;z-index:1;width:400px;top:50%;left:100px;transform:translateY(-50%);transition:all 1s;min-height:273px;text-align:center}.ve_container h1[data-v-6caddbfd]{font-size:24px;transition:all 1s;font-weight:700;margin-bottom:36px}.ve_container .ve_form .ve_submit[data-v-6caddbfd]{width:100%}.ve_container .ve_form[data-v-6caddbfd] .el-input-group__prepend{padding:0 10px}.el-form-item[data-v-6caddbfd]{width:100%}
|
||||
.ve_404[data-v-3e778cc6]{height:100vh;width:100vw;position:relative;overflow:hidden;background:linear-gradient(90deg,#2f3640 23%,#181b20)}.moon[data-v-3e778cc6]{background:linear-gradient(90deg,#d0d0d0 48%,#919191);position:absolute;top:-30vh;left:-80vh;width:160vh;height:160%;content:"";border-radius:50%;box-shadow:0 0 30px -4px rgba(0,0,0,.5)}.moon__crater[data-v-3e778cc6]{position:absolute;content:"";border-radius:100%;background:linear-gradient(90deg,#7a7a7a 38%,#c3c3c3);opacity:.6}.moon__crater1[data-v-3e778cc6]{top:250px;left:500px;width:60px;height:180px}.moon__crater2[data-v-3e778cc6]{top:650px;left:340px;width:40px;height:80px;transform:rotate(55deg)}.moon__crater3[data-v-3e778cc6]{top:-20px;left:40px;width:65px;height:120px;transform:rotate(250deg)}.star[data-v-3e778cc6]{color:gray;position:absolute;width:10px;height:10px;content:"";border-radius:100%;transform:rotate(250deg);opacity:.4;animation-name:shimmer-3e778cc6;animation-duration:1.5s;animation-iteration-count:infinite;animation-direction:alternate}@keyframes shimmer-3e778cc6{0%{opacity:0}to{opacity:.7}}.star1[data-v-3e778cc6]{top:40%;left:50%;animation-delay:1s}.star2[data-v-3e778cc6]{top:60%;left:90%;animation-delay:3s}.star3[data-v-3e778cc6]{top:10%;left:70%;animation-delay:2s}.star4[data-v-3e778cc6]{top:90%;left:40%}.star5[data-v-3e778cc6]{top:20%;left:30%;animation-delay:.5s}.astronaut[data-v-3e778cc6]{position:absolute;width:60vw;height:100vh;top:0;right:0;z-index:0}.error[data-v-3e778cc6]{position:absolute;left:100px;top:400px;transform:translateY(-60%);font-family:Righteous,cursive;color:#363e49;z-index:1}.error__title[data-v-3e778cc6]{font-size:10em;font-weight:700;color:#d0d0d0;text-shadow:-5px -5px 0 rgba(0,0,0,.7);background-image:linear-gradient(90deg,#d0d0d0 48%,#919191);-webkit-background-clip:text;-webkit-text-fill-color:transparent}.error__subtitle[data-v-3e778cc6]{font-size:2em}.error__description[data-v-3e778cc6]{opacity:.5}.error__button[data-v-3e778cc6]{min-width:7em;margin-top:3em;margin-right:.5em;padding:.5em 2em;outline:none;border:2px solid #2f3640;background-color:transparent;border-radius:8em;color:#576375;cursor:pointer;transition-duration:.2s;font-size:.75em;font-family:Righteous,cursive}.error__button[data-v-3e778cc6]:hover{color:#21252c}.error__button--active[data-v-3e778cc6]{background-color:#409eff;border:2px solid #409eff;color:#fff}.error__button--active[data-v-3e778cc6]:hover{box-shadow:0 0 8px 0 rgba(0,0,0,.5);color:#fff}.ve_container[data-v-295989a2]{position:absolute;z-index:1;width:400px;top:50%;left:100px;transform:translateY(-50%);transition:all 1s;min-height:273px;text-align:center}.ve_container h1[data-v-295989a2]{font-size:24px;transition:all 1s;font-weight:700;margin-bottom:36px}.ve_container .ve_form .ve_submit[data-v-295989a2]{width:100%}.ve_container .ve_form[data-v-295989a2] .el-input-group__prepend{padding:0 10px}.el-form-item[data-v-295989a2]{width:100%}
|
||||
@@ -1 +1 @@
|
||||
.ve_404[data-v-3e778cc6]{height:100vh;width:100vw;position:relative;overflow:hidden;background:linear-gradient(90deg,#2f3640 23%,#181b20)}.moon[data-v-3e778cc6]{background:linear-gradient(90deg,#d0d0d0 48%,#919191);position:absolute;top:-30vh;left:-80vh;width:160vh;height:160%;content:"";border-radius:50%;box-shadow:0 0 30px -4px rgba(0,0,0,.5)}.moon__crater[data-v-3e778cc6]{position:absolute;content:"";border-radius:100%;background:linear-gradient(90deg,#7a7a7a 38%,#c3c3c3);opacity:.6}.moon__crater1[data-v-3e778cc6]{top:250px;left:500px;width:60px;height:180px}.moon__crater2[data-v-3e778cc6]{top:650px;left:340px;width:40px;height:80px;transform:rotate(55deg)}.moon__crater3[data-v-3e778cc6]{top:-20px;left:40px;width:65px;height:120px;transform:rotate(250deg)}.star[data-v-3e778cc6]{color:gray;position:absolute;width:10px;height:10px;content:"";border-radius:100%;transform:rotate(250deg);opacity:.4;animation-name:shimmer-3e778cc6;animation-duration:1.5s;animation-iteration-count:infinite;animation-direction:alternate}@keyframes shimmer-3e778cc6{0%{opacity:0}to{opacity:.7}}.star1[data-v-3e778cc6]{top:40%;left:50%;animation-delay:1s}.star2[data-v-3e778cc6]{top:60%;left:90%;animation-delay:3s}.star3[data-v-3e778cc6]{top:10%;left:70%;animation-delay:2s}.star4[data-v-3e778cc6]{top:90%;left:40%}.star5[data-v-3e778cc6]{top:20%;left:30%;animation-delay:.5s}.astronaut[data-v-3e778cc6]{position:absolute;width:60vw;height:100vh;top:0;right:0;z-index:0}.error[data-v-3e778cc6]{position:absolute;left:100px;top:400px;transform:translateY(-60%);font-family:Righteous,cursive;color:#363e49;z-index:1}.error__title[data-v-3e778cc6]{font-size:10em;font-weight:700;color:#d0d0d0;text-shadow:-5px -5px 0 rgba(0,0,0,.7);background-image:linear-gradient(90deg,#d0d0d0 48%,#919191);-webkit-background-clip:text;-webkit-text-fill-color:transparent}.error__subtitle[data-v-3e778cc6]{font-size:2em}.error__description[data-v-3e778cc6]{opacity:.5}.error__button[data-v-3e778cc6]{min-width:7em;margin-top:3em;margin-right:.5em;padding:.5em 2em;outline:none;border:2px solid #2f3640;background-color:transparent;border-radius:8em;color:#576375;cursor:pointer;transition-duration:.2s;font-size:.75em;font-family:Righteous,cursive}.error__button[data-v-3e778cc6]:hover{color:#21252c}.error__button--active[data-v-3e778cc6]{background-color:#409eff;border:2px solid #409eff;color:#fff}.error__button--active[data-v-3e778cc6]:hover{box-shadow:0 0 8px 0 rgba(0,0,0,.5);color:#fff}.ve_container[data-v-2baa565c]{position:absolute;z-index:1;width:400px;top:50%;left:100px;transform:translateY(-50%);transition:all 1s;min-height:273px;text-align:center}.ve_container h1[data-v-2baa565c]{font-size:24px;transition:all 1s;font-weight:700;margin-bottom:36px}.ve_container .ve_form .ve_submit[data-v-2baa565c]{width:100%}.ve_container .ve_form[data-v-2baa565c] .el-input-group__prepend{padding:0 10px}.el-form-item[data-v-2baa565c]{width:100%}.scrollbar-zone-item[data-v-2baa565c]{display:flex;align-items:center;justify-content:center;height:50px;margin:10px;text-align:center;border-radius:4px;background:var(--el-color-primary-light-9);color:var(--el-color-primary);cursor:pointer}.scrollbar-zone-item[data-v-2baa565c]:hover{background-color:#07617e;color:#eef4fe}
|
||||
.ve_404[data-v-3e778cc6]{height:100vh;width:100vw;position:relative;overflow:hidden;background:linear-gradient(90deg,#2f3640 23%,#181b20)}.moon[data-v-3e778cc6]{background:linear-gradient(90deg,#d0d0d0 48%,#919191);position:absolute;top:-30vh;left:-80vh;width:160vh;height:160%;content:"";border-radius:50%;box-shadow:0 0 30px -4px rgba(0,0,0,.5)}.moon__crater[data-v-3e778cc6]{position:absolute;content:"";border-radius:100%;background:linear-gradient(90deg,#7a7a7a 38%,#c3c3c3);opacity:.6}.moon__crater1[data-v-3e778cc6]{top:250px;left:500px;width:60px;height:180px}.moon__crater2[data-v-3e778cc6]{top:650px;left:340px;width:40px;height:80px;transform:rotate(55deg)}.moon__crater3[data-v-3e778cc6]{top:-20px;left:40px;width:65px;height:120px;transform:rotate(250deg)}.star[data-v-3e778cc6]{color:gray;position:absolute;width:10px;height:10px;content:"";border-radius:100%;transform:rotate(250deg);opacity:.4;animation-name:shimmer-3e778cc6;animation-duration:1.5s;animation-iteration-count:infinite;animation-direction:alternate}@keyframes shimmer-3e778cc6{0%{opacity:0}to{opacity:.7}}.star1[data-v-3e778cc6]{top:40%;left:50%;animation-delay:1s}.star2[data-v-3e778cc6]{top:60%;left:90%;animation-delay:3s}.star3[data-v-3e778cc6]{top:10%;left:70%;animation-delay:2s}.star4[data-v-3e778cc6]{top:90%;left:40%}.star5[data-v-3e778cc6]{top:20%;left:30%;animation-delay:.5s}.astronaut[data-v-3e778cc6]{position:absolute;width:60vw;height:100vh;top:0;right:0;z-index:0}.error[data-v-3e778cc6]{position:absolute;left:100px;top:400px;transform:translateY(-60%);font-family:Righteous,cursive;color:#363e49;z-index:1}.error__title[data-v-3e778cc6]{font-size:10em;font-weight:700;color:#d0d0d0;text-shadow:-5px -5px 0 rgba(0,0,0,.7);background-image:linear-gradient(90deg,#d0d0d0 48%,#919191);-webkit-background-clip:text;-webkit-text-fill-color:transparent}.error__subtitle[data-v-3e778cc6]{font-size:2em}.error__description[data-v-3e778cc6]{opacity:.5}.error__button[data-v-3e778cc6]{min-width:7em;margin-top:3em;margin-right:.5em;padding:.5em 2em;outline:none;border:2px solid #2f3640;background-color:transparent;border-radius:8em;color:#576375;cursor:pointer;transition-duration:.2s;font-size:.75em;font-family:Righteous,cursive}.error__button[data-v-3e778cc6]:hover{color:#21252c}.error__button--active[data-v-3e778cc6]{background-color:#409eff;border:2px solid #409eff;color:#fff}.error__button--active[data-v-3e778cc6]:hover{box-shadow:0 0 8px 0 rgba(0,0,0,.5);color:#fff}.ve_container[data-v-b109eb42]{position:absolute;z-index:1;width:400px;top:50%;left:100px;transform:translateY(-50%);transition:all 1s;min-height:273px;text-align:center}.ve_container h1[data-v-b109eb42]{font-size:24px;transition:all 1s;font-weight:700;margin-bottom:36px}.ve_container .ve_form .ve_submit[data-v-b109eb42]{width:100%}.ve_container .ve_form[data-v-b109eb42] .el-input-group__prepend{padding:0 10px}.el-form-item[data-v-b109eb42]{width:100%}.scrollbar-zone-item[data-v-b109eb42]{display:flex;align-items:center;justify-content:center;height:50px;margin:10px;text-align:center;border-radius:4px;background:var(--el-color-primary-light-9);color:var(--el-color-primary);cursor:pointer}.scrollbar-zone-item[data-v-b109eb42]:hover{background-color:#07617e;color:#eef4fe}
|
||||
@@ -0,0 +1 @@
|
||||
.ve_container[data-v-7d12f6f5]{padding:20px}.el-form-item[data-v-7d12f6f5]{margin-bottom:20px}.el-form-item[data-v-259b6f0a],.el-form-item[data-v-cc75b748]{width:100%}.fl{float:left}.p0{padding:0!important}.application_item_class_[data-v-2aedb949],.menu_edit_item[data-v-417eeee8],.role_edit_item{width:100%}
|
||||
@@ -0,0 +1 @@
|
||||
.application_item_class_[data-v-2aedb949]{width:100%}.ve_container[data-v-7d12f6f5]{padding:20px}.el-form-item[data-v-7d12f6f5]{margin-bottom:20px}.el-form-item[data-v-259b6f0a],.el-form-item[data-v-cc75b748]{width:100%}.fl{float:left}.p0{padding:0!important}.menu_edit_item[data-v-417eeee8],.role_edit_item{width:100%}.ve_table .ve_table_page[data-v-11019130],.ve_table[data-v-11019130]{flex:1;display:flex;flex-direction:column}.ve_table .ve_table_page .ve_table_content[data-v-11019130]{flex:1}
|
||||
@@ -1 +1 @@
|
||||
.ve_404[data-v-3e778cc6]{height:100vh;width:100vw;position:relative;overflow:hidden;background:linear-gradient(90deg,#2f3640 23%,#181b20)}.moon[data-v-3e778cc6]{background:linear-gradient(90deg,#d0d0d0 48%,#919191);position:absolute;top:-30vh;left:-80vh;width:160vh;height:160%;content:"";border-radius:50%;box-shadow:0 0 30px -4px rgba(0,0,0,.5)}.moon__crater[data-v-3e778cc6]{position:absolute;content:"";border-radius:100%;background:linear-gradient(90deg,#7a7a7a 38%,#c3c3c3);opacity:.6}.moon__crater1[data-v-3e778cc6]{top:250px;left:500px;width:60px;height:180px}.moon__crater2[data-v-3e778cc6]{top:650px;left:340px;width:40px;height:80px;transform:rotate(55deg)}.moon__crater3[data-v-3e778cc6]{top:-20px;left:40px;width:65px;height:120px;transform:rotate(250deg)}.star[data-v-3e778cc6]{color:gray;position:absolute;width:10px;height:10px;content:"";border-radius:100%;transform:rotate(250deg);opacity:.4;animation-name:shimmer-3e778cc6;animation-duration:1.5s;animation-iteration-count:infinite;animation-direction:alternate}@keyframes shimmer-3e778cc6{0%{opacity:0}to{opacity:.7}}.star1[data-v-3e778cc6]{top:40%;left:50%;animation-delay:1s}.star2[data-v-3e778cc6]{top:60%;left:90%;animation-delay:3s}.star3[data-v-3e778cc6]{top:10%;left:70%;animation-delay:2s}.star4[data-v-3e778cc6]{top:90%;left:40%}.star5[data-v-3e778cc6]{top:20%;left:30%;animation-delay:.5s}.astronaut[data-v-3e778cc6]{position:absolute;width:60vw;height:100vh;top:0;right:0;z-index:0}.error[data-v-3e778cc6]{position:absolute;left:100px;top:400px;transform:translateY(-60%);font-family:Righteous,cursive;color:#363e49;z-index:1}.error__title[data-v-3e778cc6]{font-size:10em;font-weight:700;color:#d0d0d0;text-shadow:-5px -5px 0 rgba(0,0,0,.7);background-image:linear-gradient(90deg,#d0d0d0 48%,#919191);-webkit-background-clip:text;-webkit-text-fill-color:transparent}.error__subtitle[data-v-3e778cc6]{font-size:2em}.error__description[data-v-3e778cc6]{opacity:.5}.error__button[data-v-3e778cc6]{min-width:7em;margin-top:3em;margin-right:.5em;padding:.5em 2em;outline:none;border:2px solid #2f3640;background-color:transparent;border-radius:8em;color:#576375;cursor:pointer;transition-duration:.2s;font-size:.75em;font-family:Righteous,cursive}.error__button[data-v-3e778cc6]:hover{color:#21252c}.error__button--active[data-v-3e778cc6]{background-color:#409eff;border:2px solid #409eff;color:#fff}.error__button--active[data-v-3e778cc6]:hover{box-shadow:0 0 8px 0 rgba(0,0,0,.5);color:#fff}.ve_container[data-v-3ce0a490]{position:absolute;z-index:1;width:400px;top:50%;left:100px;transform:translateY(-50%);transition:all 1s;min-height:273px;text-align:center}.ve_container h1[data-v-3ce0a490]{font-size:24px;transition:all 1s;font-weight:700;margin-bottom:36px}.ve_container .ve_form .ve_submit[data-v-3ce0a490]{width:100%}.ve_container .ve_form[data-v-3ce0a490] .el-input-group__prepend{padding:0 10px}.el-form-item[data-v-3ce0a490]{width:100%}
|
||||
.ve_404[data-v-3e778cc6]{height:100vh;width:100vw;position:relative;overflow:hidden;background:linear-gradient(90deg,#2f3640 23%,#181b20)}.moon[data-v-3e778cc6]{background:linear-gradient(90deg,#d0d0d0 48%,#919191);position:absolute;top:-30vh;left:-80vh;width:160vh;height:160%;content:"";border-radius:50%;box-shadow:0 0 30px -4px rgba(0,0,0,.5)}.moon__crater[data-v-3e778cc6]{position:absolute;content:"";border-radius:100%;background:linear-gradient(90deg,#7a7a7a 38%,#c3c3c3);opacity:.6}.moon__crater1[data-v-3e778cc6]{top:250px;left:500px;width:60px;height:180px}.moon__crater2[data-v-3e778cc6]{top:650px;left:340px;width:40px;height:80px;transform:rotate(55deg)}.moon__crater3[data-v-3e778cc6]{top:-20px;left:40px;width:65px;height:120px;transform:rotate(250deg)}.star[data-v-3e778cc6]{color:gray;position:absolute;width:10px;height:10px;content:"";border-radius:100%;transform:rotate(250deg);opacity:.4;animation-name:shimmer-3e778cc6;animation-duration:1.5s;animation-iteration-count:infinite;animation-direction:alternate}@keyframes shimmer-3e778cc6{0%{opacity:0}to{opacity:.7}}.star1[data-v-3e778cc6]{top:40%;left:50%;animation-delay:1s}.star2[data-v-3e778cc6]{top:60%;left:90%;animation-delay:3s}.star3[data-v-3e778cc6]{top:10%;left:70%;animation-delay:2s}.star4[data-v-3e778cc6]{top:90%;left:40%}.star5[data-v-3e778cc6]{top:20%;left:30%;animation-delay:.5s}.astronaut[data-v-3e778cc6]{position:absolute;width:60vw;height:100vh;top:0;right:0;z-index:0}.error[data-v-3e778cc6]{position:absolute;left:100px;top:400px;transform:translateY(-60%);font-family:Righteous,cursive;color:#363e49;z-index:1}.error__title[data-v-3e778cc6]{font-size:10em;font-weight:700;color:#d0d0d0;text-shadow:-5px -5px 0 rgba(0,0,0,.7);background-image:linear-gradient(90deg,#d0d0d0 48%,#919191);-webkit-background-clip:text;-webkit-text-fill-color:transparent}.error__subtitle[data-v-3e778cc6]{font-size:2em}.error__description[data-v-3e778cc6]{opacity:.5}.error__button[data-v-3e778cc6]{min-width:7em;margin-top:3em;margin-right:.5em;padding:.5em 2em;outline:none;border:2px solid #2f3640;background-color:transparent;border-radius:8em;color:#576375;cursor:pointer;transition-duration:.2s;font-size:.75em;font-family:Righteous,cursive}.error__button[data-v-3e778cc6]:hover{color:#21252c}.error__button--active[data-v-3e778cc6]{background-color:#409eff;border:2px solid #409eff;color:#fff}.error__button--active[data-v-3e778cc6]:hover{box-shadow:0 0 8px 0 rgba(0,0,0,.5);color:#fff}.ve_container[data-v-c00b4710]{position:absolute;z-index:1;width:400px;top:50%;left:100px;transform:translateY(-50%);transition:all 1s;min-height:273px;text-align:center}.ve_container h1[data-v-c00b4710]{font-size:24px;transition:all 1s;font-weight:700;margin-bottom:36px}.ve_container .ve_form .ve_submit[data-v-c00b4710]{width:100%}.ve_container .ve_form[data-v-c00b4710] .el-input-group__prepend{padding:0 10px}.el-form-item[data-v-c00b4710]{width:100%}
|
||||
@@ -1 +1 @@
|
||||
<!doctype html><html lang="zh-cn"><head><meta charset="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><link rel="icon" href="favicon.png"/><title>网络渗透</title><script defer="defer" src="js/chunk-elementPlusIcon.5bb31008.js"></script><script defer="defer" src="js/chunk-elementPlus.300ed501.js"></script><script defer="defer" src="js/chunk-mockjs.a061ac24.js"></script><script defer="defer" src="js/chunk-vendors.609d0040.js"></script><script defer="defer" src="js/app.73783072.js"></script><link href="css/chunk-elementPlus.746c067c.css" rel="stylesheet"><link href="css/app.18deece7.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but wu-vue-zone-ecology-net doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>
|
||||
<!doctype html><html lang="zh-cn"><head><meta charset="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><link rel="icon" href="favicon.png"/><title>网络渗透</title><script defer="defer" src="js/chunk-elementPlusIcon.5bb31008.js"></script><script defer="defer" src="js/chunk-elementPlus.300ed501.js"></script><script defer="defer" src="js/chunk-mockjs.a061ac24.js"></script><script defer="defer" src="js/chunk-vendors.609d0040.js"></script><script defer="defer" src="js/app.5b03bfff.js"></script><link href="css/chunk-elementPlus.746c067c.css" rel="stylesheet"><link href="css/app.18deece7.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but wu-vue-zone-ecology-net doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>
|
||||
@@ -1 +0,0 @@
|
||||
"use strict";(self.webpackChunkwu_vue_zone_ecology_net=self.webpackChunkwu_vue_zone_ecology_net||[]).push([[1683,9285],{84143:function(e,a,t){t.r(a),t.d(a,{default:function(){return _}});t(31542);var s=t(38178),l=t(39090),r=t(49401),o=t(9707),n=t(94854),d=t(10425),u=t(89164),i=t(62859);const c={class:"ve_container"};var p={__name:"Login",setup(e){const a={username:[{required:!0,message:"请输入用户名",trigger:"blur"}],password:[{required:!0,message:"请输入密码",trigger:"blur"}]},t=(0,d.Pj)(),p=(0,u.rd)(),_=(0,l.Kh)({username:"",password:""}),{username:m,password:f}=(0,l.QW)(_),k=(0,l.KR)(null),b=(0,l.KR)(!1);sessionStorage.clear(),t.dispatch(`app/${o.$T}`,""),p.options.isAddDynamicMenuRoutes=!1;const g=()=>{k.value.validate(async e=>{if(e)try{const e=await VE_API.system.login(_);if(0===e.code){await t.dispatch(`app/${o.$T}`,e.data),await t.dispatch(`app/${o.w3}`,e.data.accessToken),await t.dispatch(`app/${o.jr}`,e.data.refreshToken),await t.dispatch(`app/${o.Q1}`,_.username);try{const a=await VE_API.system.resolvingUser({accessToken:e.data.accessToken});a&&a.id&&await t.dispatch(`app/${o.Dl}`,a.id)}catch(e){console.warn("获取用户信息失败:",e)}b.value=!0,i.nk.success("登录成功"),p.push({name:"Zone"})}else{const a=e.message||"登录失败,请检查用户名和密码";i.nk.error(a)}}catch(e){console.error("登录异常:",e)}})};return(e,t)=>{const o=(0,s.g2)("router-link"),d=(0,s.g2)("el-button"),u=(0,s.g2)("Avatar"),i=(0,s.g2)("el-icon"),p=(0,s.g2)("el-input"),h=(0,s.g2)("el-form-item"),v=(0,s.g2)("Key"),w=(0,s.g2)("el-form"),y=(0,s.g2)("el-card");return(0,s.uX)(),(0,s.Wv)((0,l.R1)(n.default),null,{default:(0,s.k6)(()=>[(0,s.Lk)("div",c,[(0,s.bF)(y,{"body-style":{background:"rgba(0,0,0,0.15)"}},{default:(0,s.k6)(()=>[(0,s.bF)(d,{class:"ve_submit",type:"plain",style:{float:"right"}},{default:(0,s.k6)(()=>[(0,s.bF)(o,{to:{path:"register"},style:{"text-decoration":"none",color:"inherit"}},{default:(0,s.k6)(()=>t[2]||(t[2]=[(0,s.eW)("注册")])),_:1,__:[2]})]),_:1}),t[4]||(t[4]=(0,s.Lk)("h1",null,"懒人生态",-1)),(0,s.bF)(r.eB,{name:"el-fade-in-linear"},{default:(0,s.k6)(()=>[(0,s.bo)((0,s.bF)(w,{model:_,rules:a,class:"ve_form",ref_key:"ref_form",ref:k,inline:!1,onKeyup:(0,r.jR)(g,["enter"])},{default:(0,s.k6)(()=>[(0,s.bF)(h,{prop:"username"},{default:(0,s.k6)(()=>[(0,s.bF)(p,{modelValue:(0,l.R1)(m),"onUpdate:modelValue":t[0]||(t[0]=e=>(0,l.i9)(m)?m.value=e:null),modelModifiers:{trim:!0},placeholder:"用户名"},{prepend:(0,s.k6)(()=>[(0,s.bF)(i,{size:20},{default:(0,s.k6)(()=>[(0,s.bF)(u)]),_:1})]),_:1},8,["modelValue"])]),_:1}),(0,s.bF)(h,{prop:"password"},{default:(0,s.k6)(()=>[(0,s.bF)(p,{modelValue:(0,l.R1)(f),"onUpdate:modelValue":t[1]||(t[1]=e=>(0,l.i9)(f)?f.value=e:null),modelModifiers:{trim:!0},"show-password":"",placeholder:"密码"},{prepend:(0,s.k6)(()=>[(0,s.bF)(i,{size:20},{default:(0,s.k6)(()=>[(0,s.bF)(v)]),_:1})]),_:1},8,["modelValue"])]),_:1}),(0,s.bF)(h,null,{default:(0,s.k6)(()=>[(0,s.bF)(d,{class:"ve_submit",type:"primary",onClick:g},{default:(0,s.k6)(()=>t[3]||(t[3]=[(0,s.eW)(" 登录 ")])),_:1,__:[3]})]),_:1})]),_:1},8,["model"]),[[r.aG,!b.value]])]),_:1})]),_:1,__:[4]})])]),_:1})}}};var _=(0,t(45924).A)(p,[["__scopeId","data-v-6caddbfd"]])}}]);
|
||||
@@ -1 +0,0 @@
|
||||
"use strict";(self.webpackChunkwu_vue_zone_ecology_net=self.webpackChunkwu_vue_zone_ecology_net||[]).push([[1731,9285],{63775:function(e,l,t){t.r(l),t.d(l,{default:function(){return i}});var n=t(38178),a=t(39090),o=t(49401),r=t(94854),u=t(89164);const s={class:"ve_container"};var d={__name:"ZoneInit",setup(e){const l={zoneName:[{required:!0,message:"请输入区域名称",trigger:"blur"}],password:[{required:!0,message:"请输入密码",trigger:"blur"}]},t=(0,u.rd)(),d=(0,a.Kh)({zoneName:"",password:""}),{zoneName:i}=(0,a.QW)(d),_=(0,a.KR)(null),c=(0,a.KR)(!1);t.options.isAddDynamicMenuRoutes=!1;const m=()=>{VE_API.system.createAndInitZone({zoneName:d.zoneName}).then(async e=>{const{code:l}=e;0===l&&t.go(-1)})};return(e,t)=>{const u=(0,n.g2)("router-link"),f=(0,n.g2)("el-button"),b=(0,n.g2)("Avatar"),g=(0,n.g2)("el-icon"),k=(0,n.g2)("el-input"),p=(0,n.g2)("el-form-item"),v=(0,n.g2)("el-form"),y=(0,n.g2)("el-card");return(0,n.uX)(),(0,n.Wv)((0,a.R1)(r.default),null,{default:(0,n.k6)(()=>[(0,n.Lk)("div",s,[(0,n.bF)(y,{"body-style":{background:"rgba(0,0,0,0.15)"}},{default:(0,n.k6)(()=>[(0,n.bF)(f,{class:"ve_submit",type:"plain",style:{float:"right"}},{default:(0,n.k6)(()=>[(0,n.bF)(u,{to:{path:"register"},style:{"text-decoration":"none",color:"inherit"}},{default:(0,n.k6)(()=>t[1]||(t[1]=[(0,n.eW)("登陆")])),_:1,__:[1]})]),_:1}),t[3]||(t[3]=(0,n.Lk)("h1",null,"懒人生态",-1)),(0,n.bF)(o.eB,{name:"el-fade-in-linear"},{default:(0,n.k6)(()=>[(0,n.bo)((0,n.bF)(v,{model:d,rules:l,class:"ve_form",ref_key:"ref_form",ref:_,inline:!1,onKeyup:(0,o.jR)(m,["enter"])},{default:(0,n.k6)(()=>[(0,n.bF)(p,{prop:"zoneName"},{default:(0,n.k6)(()=>[(0,n.bF)(k,{modelValue:(0,a.R1)(i),"onUpdate:modelValue":t[0]||(t[0]=e=>(0,a.i9)(i)?i.value=e:null),modelModifiers:{trim:!0},placeholder:"区域名称"},{prepend:(0,n.k6)(()=>[(0,n.bF)(g,{size:20},{default:(0,n.k6)(()=>[(0,n.bF)(b)]),_:1})]),_:1},8,["modelValue"])]),_:1}),(0,n.bF)(p,null,{default:(0,n.k6)(()=>[(0,n.bF)(f,{class:"ve_submit",type:"primary",onClick:m},{default:(0,n.k6)(()=>t[2]||(t[2]=[(0,n.eW)(" 创建个人空间 ")])),_:1,__:[2]})]),_:1})]),_:1},8,["model"]),[[o.aG,!c.value]])]),_:1})]),_:1,__:[3]})])]),_:1})}}};var i=(0,t(45924).A)(d,[["__scopeId","data-v-3ce0a490"]])}}]);
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
@@ -1 +1 @@
|
||||
"use strict";(self.webpackChunkwu_vue_zone_ecology_net=self.webpackChunkwu_vue_zone_ecology_net||[]).push([[211],{40211:function(e,l,t){t.r(l),t.d(l,{default:function(){return r}});var a=t(38178),o=t(39090);var r={__name:"CloudServerSendMessage2Client",props:{showDialog:{type:Boolean,default:!0},title:{type:String,default:"添加"},rowData:{type:Object,default:null}},emits:["closeDialog"],setup(e,{emit:l}){const t={clientId:[{required:!0,message:"请输入选择客户端",trigger:"blur"}],clientTargetIp:[{required:!0,message:"请输入客户端目标IP",trigger:"blur"}],clientTargetPort:[{required:!0,message:"请输入客户端目标端口",trigger:"blur"}],visitorPort:[{required:!0,message:"请选择访客端口",trigger:"blur"}]},r=e,u=l,{title:n,rowData:i}=(0,o.QW)(r),d=()=>{u("closeDialog",!1)},s=(0,o.KR)(null),c=(0,o.Kh)({message:"",clientId:""}),{clientId:g,message:m}=(0,o.QW)(c);i.value&&(g.value=i.value.clientId);return(0,a.sV)(async()=>{}),(l,r)=>{const u=(0,a.g2)("el-input"),i=(0,a.g2)("el-form-item"),p=(0,a.g2)("el-form"),b=(0,a.g2)("el-button"),f=(0,a.g2)("el-dialog");return(0,a.uX)(),(0,a.Wv)(f,{title:(0,o.R1)(n),"append-to-body":"","destroy-on-close":"","model-value":e.showDialog,onClose:r[4]||(r[4]=e=>d())},{footer:(0,a.k6)(()=>[(0,a.Lk)("span",null,[(0,a.bF)(b,{onClick:r[2]||(r[2]=e=>d())},{default:(0,a.k6)(()=>r[5]||(r[5]=[(0,a.eW)("取消")])),_:1,__:[5]}),(0,a.bF)(b,{type:"primary",onClick:r[3]||(r[3]=e=>{s.value.validate(async e=>{if(!e)return console.log("error submit!!"),!1;{let e=await VE_API.cloudNetwork.sendMessage2HeartbeatClient(c);const{code:l}=e;0===l&&d()}})})},{default:(0,a.k6)(()=>r[6]||(r[6]=[(0,a.eW)("发送")])),_:1,__:[6]})])]),default:(0,a.k6)(()=>[(0,a.bF)(p,{model:c,ref_key:"formRef",ref:s,rules:t,"label-width":"80px",inline:!1},{default:(0,a.k6)(()=>[(0,a.bF)(i,{label:"客户端ID",prop:"clientId"},{default:(0,a.k6)(()=>[(0,a.bF)(u,{modelValue:(0,o.R1)(g),"onUpdate:modelValue":r[0]||(r[0]=e=>(0,o.i9)(g)?g.value=e:null),placeholder:"",disabled:""},null,8,["modelValue"])]),_:1}),(0,a.bF)(i,{label:"发送的消息",prop:"describe"},{default:(0,a.k6)(()=>[(0,a.bF)(u,{modelValue:(0,o.R1)(m),"onUpdate:modelValue":r[1]||(r[1]=e=>(0,o.i9)(m)?m.value=e:null),placeholder:"",clearable:""},null,8,["modelValue"])]),_:1})]),_:1},8,["model"])]),_:1},8,["title","model-value"])}}}}}]);
|
||||
"use strict";(self.webpackChunkwu_vue_zone_ecology_net=self.webpackChunkwu_vue_zone_ecology_net||[]).push([[211],{40211:function(e,l,t){t.r(l),t.d(l,{default:function(){return r}});var a=t(38178),o=t(39090);var r={__name:"CloudServerSendMessage2Client",props:{showDialog:{type:Boolean,default:!0},title:{type:String,default:"添加"},rowData:{type:Object,default:null}},emits:["closeDialog"],setup(e,{emit:l}){const t={clientId:[{required:!0,message:"请输入选择客户端",trigger:"blur"}],clientTargetIp:[{required:!0,message:"请输入客户端目标IP",trigger:"blur"}],clientTargetPort:[{required:!0,message:"请输入目标客户端端口",trigger:"blur"}],visitorPort:[{required:!0,message:"请选择访客端口",trigger:"blur"}]},r=e,u=l,{title:n,rowData:i}=(0,o.QW)(r),d=()=>{u("closeDialog",!1)},s=(0,o.KR)(null),c=(0,o.Kh)({message:"",clientId:""}),{clientId:g,message:m}=(0,o.QW)(c);i.value&&(g.value=i.value.clientId);return(0,a.sV)(async()=>{}),(l,r)=>{const u=(0,a.g2)("el-input"),i=(0,a.g2)("el-form-item"),p=(0,a.g2)("el-form"),b=(0,a.g2)("el-button"),f=(0,a.g2)("el-dialog");return(0,a.uX)(),(0,a.Wv)(f,{title:(0,o.R1)(n),"append-to-body":"","destroy-on-close":"","model-value":e.showDialog,onClose:r[4]||(r[4]=e=>d())},{footer:(0,a.k6)(()=>[(0,a.Lk)("span",null,[(0,a.bF)(b,{onClick:r[2]||(r[2]=e=>d())},{default:(0,a.k6)(()=>r[5]||(r[5]=[(0,a.eW)("取消")])),_:1,__:[5]}),(0,a.bF)(b,{type:"primary",onClick:r[3]||(r[3]=e=>{s.value.validate(async e=>{if(!e)return console.log("error submit!!"),!1;{let e=await VE_API.cloudNetwork.sendMessage2HeartbeatClient(c);const{code:l}=e;0===l&&d()}})})},{default:(0,a.k6)(()=>r[6]||(r[6]=[(0,a.eW)("发送")])),_:1,__:[6]})])]),default:(0,a.k6)(()=>[(0,a.bF)(p,{model:c,ref_key:"formRef",ref:s,rules:t,"label-width":"80px",inline:!1},{default:(0,a.k6)(()=>[(0,a.bF)(i,{label:"客户端ID",prop:"clientId"},{default:(0,a.k6)(()=>[(0,a.bF)(u,{modelValue:(0,o.R1)(g),"onUpdate:modelValue":r[0]||(r[0]=e=>(0,o.i9)(g)?g.value=e:null),placeholder:"",disabled:""},null,8,["modelValue"])]),_:1}),(0,a.bF)(i,{label:"发送的消息",prop:"describe"},{default:(0,a.k6)(()=>[(0,a.bF)(u,{modelValue:(0,o.R1)(m),"onUpdate:modelValue":r[1]||(r[1]=e=>(0,o.i9)(m)?m.value=e:null),placeholder:"",clearable:""},null,8,["modelValue"])]),_:1})]),_:1},8,["model"])]),_:1},8,["title","model-value"])}}}}}]);
|
||||
@@ -0,0 +1 @@
|
||||
"use strict";(self.webpackChunkwu_vue_zone_ecology_net=self.webpackChunkwu_vue_zone_ecology_net||[]).push([[2160,9285],{42282:function(e,l,n){n.r(l),n.d(l,{default:function(){return i}});var t=n(38178),a=n(39090),o=n(49401),r=n(94854),u=n(89164);const s={class:"ve_container"};var d={__name:"ZoneInit",setup(e){const l={zoneName:[{required:!0,message:"请输入区域名称",trigger:"blur"}],password:[{required:!0,message:"请输入密码",trigger:"blur"}]},n=(0,u.rd)(),d=(0,a.Kh)({zoneName:"",password:""}),{zoneName:i}=(0,a.QW)(d),_=(0,a.KR)(null),c=(0,a.KR)(!1);n.options.isAddDynamicMenuRoutes=!1;const m=()=>{VE_API.system.createAndInitZone({zoneName:d.zoneName}).then(async e=>{const{code:l}=e;0===l&&n.go(-1)})};return(e,n)=>{const u=(0,t.g2)("router-link"),f=(0,t.g2)("el-button"),b=(0,t.g2)("Avatar"),g=(0,t.g2)("el-icon"),k=(0,t.g2)("el-input"),p=(0,t.g2)("el-form-item"),v=(0,t.g2)("el-form"),y=(0,t.g2)("el-card");return(0,t.uX)(),(0,t.Wv)((0,a.R1)(r.default),null,{default:(0,t.k6)(()=>[(0,t.Lk)("div",s,[(0,t.bF)(y,{"body-style":{background:"rgba(0,0,0,0.15)"}},{default:(0,t.k6)(()=>[(0,t.bF)(f,{class:"ve_submit",type:"plain",style:{float:"right"}},{default:(0,t.k6)(()=>[(0,t.bF)(u,{to:{path:"register"},style:{"text-decoration":"none",color:"inherit"}},{default:(0,t.k6)(()=>n[1]||(n[1]=[(0,t.eW)("登陆")])),_:1,__:[1]})]),_:1}),n[3]||(n[3]=(0,t.Lk)("h1",null,"wlcn服务端",-1)),(0,t.bF)(o.eB,{name:"el-fade-in-linear"},{default:(0,t.k6)(()=>[(0,t.bo)((0,t.bF)(v,{model:d,rules:l,class:"ve_form",ref_key:"ref_form",ref:_,inline:!1,onKeyup:(0,o.jR)(m,["enter"])},{default:(0,t.k6)(()=>[(0,t.bF)(p,{prop:"zoneName"},{default:(0,t.k6)(()=>[(0,t.bF)(k,{modelValue:(0,a.R1)(i),"onUpdate:modelValue":n[0]||(n[0]=e=>(0,a.i9)(i)?i.value=e:null),modelModifiers:{trim:!0},placeholder:"区域名称"},{prepend:(0,t.k6)(()=>[(0,t.bF)(g,{size:20},{default:(0,t.k6)(()=>[(0,t.bF)(b)]),_:1})]),_:1},8,["modelValue"])]),_:1}),(0,t.bF)(p,null,{default:(0,t.k6)(()=>[(0,t.bF)(f,{class:"ve_submit",type:"primary",onClick:m},{default:(0,t.k6)(()=>n[2]||(n[2]=[(0,t.eW)(" 创建个人空间 ")])),_:1,__:[2]})]),_:1})]),_:1},8,["model"]),[[o.aG,!c.value]])]),_:1})]),_:1,__:[3]})])]),_:1})}}};var i=(0,n(45924).A)(d,[["__scopeId","data-v-295989a2"]])}}]);
|
||||
@@ -1 +1 @@
|
||||
"use strict";(self.webpackChunkwu_vue_zone_ecology_net=self.webpackChunkwu_vue_zone_ecology_net||[]).push([[6545,9285],{49109:function(e,a,t){t.r(a),t.d(a,{default:function(){return w}});t(31542);var n=t(38178),o=t(39090),l=t(49401),c=t(54039),i=t(9707),d=t(64345),u=t(94854),s=t(10425),r=t(89164);const _={class:"ve_container"},p=["onClick"];var h={__name:"Zone",setup(e){const a=(0,s.Pj)(),t=(0,r.rd)(),h=(0,o.KR)([]),w=(0,o.KR)(!1);t.options.isAddDynamicMenuRoutes=!1;const f=async e=>{await a.dispatch(`app/${i.wC}`,e.id.toString());try{const e=await VE_API.configApi.getTitleInfo();0===e.code&&null!=e.data&&(!0===e.data.enabled?(await a.dispatch(`app/${i.e4}`,null==e.data.wechatVerificationCode?d.wechat_verification_code:e.data.wechatVerificationCode),await a.dispatch(`app/${i.FD}`,null==e.data.wechatKeyWord?d.wechat_key_word:e.data.wechatKeyWord)):(await a.dispatch(`app/${i.n7}`,!0),await a.dispatch(`app/${i.e4}`,!0)))}catch(e){console.error("获取标题信息异常:",e)}w.value=!0,await t.push({name:"AppMain"})};return(0,n.sV)(async()=>{await(async()=>{try{const{code:e,data:a}=await VE_API.system.findUseZoneList({module:d.moduleName});0===e?(h.value=a,1===h.value.length&&await f(h.value[0])):console.warn("获取区域列表失败:",a?.message)}catch(e){console.error("获取区域列表异常:",e)}})()}),(e,a)=>{const t=(0,n.g2)("router-link"),i=(0,n.g2)("el-button"),d=(0,n.g2)("el-scrollbar"),s=(0,n.g2)("el-card");return(0,n.uX)(),(0,n.Wv)((0,o.R1)(u.default),null,{default:(0,n.k6)(()=>[(0,n.Lk)("div",_,[(0,n.bF)(s,{"body-style":{background:"rgba(0,0,0,0.15)"}},{default:(0,n.k6)(()=>[(0,n.bF)(i,{class:"ve_submit",type:"plain",style:{float:"right"}},{default:(0,n.k6)(()=>[(0,n.bF)(t,{to:{path:"login"},style:{"text-decoration":"none",color:"inherit"}},{default:(0,n.k6)(()=>a[0]||(a[0]=[(0,n.eW)("登陆 ")])),_:1,__:[0]})]),_:1}),a[2]||(a[2]=(0,n.Lk)("h1",null,"懒人生态",-1)),(0,n.bF)(l.F,{name:"el-fade-in-linear"},{default:(0,n.k6)(()=>[(0,n.bF)(d,{height:"400px"},{default:(0,n.k6)(()=>[((0,n.uX)(!0),(0,n.CE)(n.FK,null,(0,n.pI)(h.value,e=>((0,n.uX)(),(0,n.CE)("p",{key:e.code,onClick:a=>f(e),class:"scrollbar-zone-item"},(0,c.v_)(e.name),9,p))),128))]),_:1}),0===h.value.length?((0,n.uX)(),(0,n.Wv)(i,{key:0},{default:(0,n.k6)(()=>[(0,n.bF)(t,{to:{path:"zone/init"},style:{"text-decoration":"none",color:"inherit"}},{default:(0,n.k6)(()=>a[1]||(a[1]=[(0,n.eW)("创建个人空间 ")])),_:1,__:[1]})]),_:1})):(0,n.Q3)("",!0)]),_:1})]),_:1,__:[2]})])]),_:1})}}};var w=(0,t(45924).A)(h,[["__scopeId","data-v-2baa565c"]])}}]);
|
||||
"use strict";(self.webpackChunkwu_vue_zone_ecology_net=self.webpackChunkwu_vue_zone_ecology_net||[]).push([[2767,9285],{96627:function(e,a,t){t.r(a),t.d(a,{default:function(){return w}});t(31542);var n=t(38178),o=t(39090),l=t(49401),c=t(54039),i=t(9707),d=t(64345),u=t(94854),s=t(10425),r=t(89164);const _={class:"ve_container"},p=["onClick"];var h={__name:"Zone",setup(e){const a=(0,s.Pj)(),t=(0,r.rd)(),h=(0,o.KR)([]),w=(0,o.KR)(!1);t.options.isAddDynamicMenuRoutes=!1;const f=async e=>{await a.dispatch(`app/${i.wC}`,e.id.toString());try{const e=await VE_API.configApi.getTitleInfo();0===e.code&&null!=e.data&&(!0===e.data.enabled?(await a.dispatch(`app/${i.e4}`,null==e.data.wechatVerificationCode?d.wechat_verification_code:e.data.wechatVerificationCode),await a.dispatch(`app/${i.FD}`,null==e.data.wechatKeyWord?d.wechat_key_word:e.data.wechatKeyWord)):(await a.dispatch(`app/${i.n7}`,!0),await a.dispatch(`app/${i.e4}`,!0)))}catch(e){console.error("获取标题信息异常:",e)}w.value=!0,await t.push({name:"AppMain"})};return(0,n.sV)(async()=>{await(async()=>{try{const{code:e,data:a}=await VE_API.system.findUseZoneList({module:d.moduleName});0===e?(h.value=a,1===h.value.length&&await f(h.value[0])):console.warn("获取区域列表失败:",a?.message)}catch(e){console.error("获取区域列表异常:",e)}})()}),(e,a)=>{const t=(0,n.g2)("router-link"),i=(0,n.g2)("el-button"),d=(0,n.g2)("el-scrollbar"),s=(0,n.g2)("el-card");return(0,n.uX)(),(0,n.Wv)((0,o.R1)(u.default),null,{default:(0,n.k6)(()=>[(0,n.Lk)("div",_,[(0,n.bF)(s,{"body-style":{background:"rgba(0,0,0,0.15)"}},{default:(0,n.k6)(()=>[(0,n.bF)(i,{class:"ve_submit",type:"plain",style:{float:"right"}},{default:(0,n.k6)(()=>[(0,n.bF)(t,{to:{path:"login"},style:{"text-decoration":"none",color:"inherit"}},{default:(0,n.k6)(()=>a[0]||(a[0]=[(0,n.eW)("登陆 ")])),_:1,__:[0]})]),_:1}),a[2]||(a[2]=(0,n.Lk)("h1",null,"wlcn服务端",-1)),(0,n.bF)(l.F,{name:"el-fade-in-linear"},{default:(0,n.k6)(()=>[(0,n.bF)(d,{height:"400px"},{default:(0,n.k6)(()=>[((0,n.uX)(!0),(0,n.CE)(n.FK,null,(0,n.pI)(h.value,e=>((0,n.uX)(),(0,n.CE)("p",{key:e.code,onClick:a=>f(e),class:"scrollbar-zone-item"},(0,c.v_)(e.name),9,p))),128))]),_:1}),0===h.value.length?((0,n.uX)(),(0,n.Wv)(i,{key:0},{default:(0,n.k6)(()=>[(0,n.bF)(t,{to:{path:"zone/init"},style:{"text-decoration":"none",color:"inherit"}},{default:(0,n.k6)(()=>a[1]||(a[1]=[(0,n.eW)("创建个人空间 ")])),_:1,__:[1]})]),_:1})):(0,n.Q3)("",!0)]),_:1})]),_:1,__:[2]})])]),_:1})}}};var w=(0,t(45924).A)(h,[["__scopeId","data-v-b109eb42"]])}}]);
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
@@ -0,0 +1 @@
|
||||
"use strict";(self.webpackChunkwu_vue_zone_ecology_net=self.webpackChunkwu_vue_zone_ecology_net||[]).push([[4127],{44127:function(e,t,a){a.r(t),a.d(t,{default:function(){return c}});a(31542);var s=a(38178),i=a(58405),n=a(52981);const r={class:"ve_container"},o={data:()=>({description:"网络渗透近七天访问流量",type:"1",icon:"DataLine",name:"网络渗透近七天访问流量",parentMenu:n.A})};var c=Object.assign(o,{__name:"ClientPortPerDayFlow",setup(e){return(0,s.sV)(async()=>{const{code:e,data:t}=await VE_API.cloudNetworkReport.findClient7DayFlow();if(0===e&&console.log(t),!t)return;const a=document.getElementById("client_port_per_day_flow"),s=i.Ts(a,null,{renderer:"canvas",useDirtyRect:!1});let n;const r=[];for(let e of t.clientInFlowList)r.push({type:"bar",name:"进口流量"+e.clientId+":"+e.visitorPort,stack:"in_flow_"+e.clientId,emphasis:{focus:"series"},data:e.flowList});for(let e of t.clientOutFlowList)r.push({type:"bar",name:"出口流量"+e.clientId+":"+e.visitorPort,stack:"out_flow_"+e.clientId,emphasis:{focus:"series"},data:e.flowList});console.log(r),n={tooltip:{trigger:"axis"},legend:{},grid:{left:"3%",right:"4%",bottom:"3%",containLabel:!0},xAxis:[{type:"category",data:t.dayList}],yAxis:[{type:"value"}],series:r,series1:[{name:"Direct",type:"bar",emphasis:{focus:"series"},data:[320,332,301,334,390,330,320]},{name:"Email",type:"bar",stack:"Ad",emphasis:{focus:"series"},data:[120,132,101,134,90,230,210]},{name:"Union Ads",type:"bar",stack:"Ad",emphasis:{focus:"series"},data:[220,182,191,234,290,330,310]},{name:"Video Ads",type:"bar",stack:"Ad",emphasis:{focus:"series"},data:[150,232,201,154,190,330,410]},{name:"Search Engine",type:"bar",data:[862,1018,964,1026,1679,1600,1570],emphasis:{focus:"series"},markLine:{lineStyle:{type:"dashed"},data:[[{type:"min"},{type:"max"}]]}},{name:"Baidu",type:"bar",barWidth:5,stack:"Search Engine",emphasis:{focus:"series"},data:[620,732,701,734,1090,1130,1120]},{name:"Google",type:"bar",stack:"Search Engine",emphasis:{focus:"series"},data:[120,132,101,134,290,230,220]},{name:"Bing",type:"bar",stack:"Search Engine",emphasis:{focus:"series"},data:[60,72,71,74,190,130,110]},{name:"Others",type:"bar",stack:"Search Engine",emphasis:{focus:"series"},data:[62,82,91,84,109,110,120]}]},n&&s.setOption(n),window.addEventListener("resize",s.resize)}),(e,t)=>((0,s.uX)(),(0,s.CE)("div",r,t[0]||(t[0]=[(0,s.Lk)("div",{id:"client_port_per_day_flow",style:{width:"100%",height:"600px"}},null,-1)])))}})}}]);
|
||||
@@ -1 +0,0 @@
|
||||
"use strict";(self.webpackChunkwu_vue_zone_ecology_net=self.webpackChunkwu_vue_zone_ecology_net||[]).push([[4127],{44127:function(e,t,a){a.r(t),a.d(t,{default:function(){return c}});a(31542);var s=a(38178),i=a(58405),n=a(52981);const r={class:"ve_container"},o={data:()=>({description:"客户端端口近七天访问流量",type:"1",icon:"DataLine",name:"客户端端口近七天访问流量",parentMenu:n.A})};var c=Object.assign(o,{__name:"ClientPortPerDayFlow",setup(e){return(0,s.sV)(async()=>{const{code:e,data:t}=await VE_API.cloudNetworkReport.findClient7DayFlow();if(0===e&&console.log(t),!t)return;const a=document.getElementById("client_port_per_day_flow"),s=i.Ts(a,null,{renderer:"canvas",useDirtyRect:!1});let n;const r=[];for(let e of t.clientInFlowList)r.push({type:"bar",name:"进口流量"+e.clientId+":"+e.visitorPort,stack:"in_flow_"+e.clientId,emphasis:{focus:"series"},data:e.flowList});for(let e of t.clientOutFlowList)r.push({type:"bar",name:"出口流量"+e.clientId+":"+e.visitorPort,stack:"out_flow_"+e.clientId,emphasis:{focus:"series"},data:e.flowList});console.log(r),n={tooltip:{trigger:"axis"},legend:{},grid:{left:"3%",right:"4%",bottom:"3%",containLabel:!0},xAxis:[{type:"category",data:t.dayList}],yAxis:[{type:"value"}],series:r,series1:[{name:"Direct",type:"bar",emphasis:{focus:"series"},data:[320,332,301,334,390,330,320]},{name:"Email",type:"bar",stack:"Ad",emphasis:{focus:"series"},data:[120,132,101,134,90,230,210]},{name:"Union Ads",type:"bar",stack:"Ad",emphasis:{focus:"series"},data:[220,182,191,234,290,330,310]},{name:"Video Ads",type:"bar",stack:"Ad",emphasis:{focus:"series"},data:[150,232,201,154,190,330,410]},{name:"Search Engine",type:"bar",data:[862,1018,964,1026,1679,1600,1570],emphasis:{focus:"series"},markLine:{lineStyle:{type:"dashed"},data:[[{type:"min"},{type:"max"}]]}},{name:"Baidu",type:"bar",barWidth:5,stack:"Search Engine",emphasis:{focus:"series"},data:[620,732,701,734,1090,1130,1120]},{name:"Google",type:"bar",stack:"Search Engine",emphasis:{focus:"series"},data:[120,132,101,134,290,230,220]},{name:"Bing",type:"bar",stack:"Search Engine",emphasis:{focus:"series"},data:[60,72,71,74,190,130,110]},{name:"Others",type:"bar",stack:"Search Engine",emphasis:{focus:"series"},data:[62,82,91,84,109,110,120]}]},n&&s.setOption(n),window.addEventListener("resize",s.resize)}),(e,t)=>((0,s.uX)(),(0,s.CE)("div",r,t[0]||(t[0]=[(0,s.Lk)("div",{id:"client_port_per_day_flow",style:{width:"100%",height:"600px"}},null,-1)])))}})}}]);
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
"use strict";(self.webpackChunkwu_vue_zone_ecology_net=self.webpackChunkwu_vue_zone_ecology_net||[]).push([[6724],{96724:function(e,l,a){a.r(l),a.d(l,{default:function(){return d}});a(9243),a(77369);var t=a(38178),r=a(39090),u=a(54039);const o={style:{float:"left"}};var d={__name:"ClientPermeateServerNetworkMappingEdit",props:{showDialog:{type:Boolean,default:!0},title:{type:String,default:"添加"},rowData:{type:Object,default:null}},emits:["closeDialog"],setup(e,{emit:l}){const a={clientId:[{required:!0,message:"请选择客户端",trigger:"blur"}],visitorPort:[{required:!0,message:"请选择访客端口",trigger:"blur"}],permeateTargetIp:[{required:!0,message:"请输入客户端目标IP",trigger:"blur"}],permeateTargetPort:[{required:!0,message:"请输入客户端目标端口",trigger:"blur"}]},d=e,n=l,{title:i,rowData:p}=(0,r.QW)(d),v=()=>{n("closeDialog",!1)},c=(0,r.KR)(null),s=(0,r.KR)(null),m=(0,r.KR)(null),b=(0,r.Kh)({permeateTargetIp:"0.0.0.0",permeateTargetPort:"",visitorPort:"",clientId:"",describe:"",id:""}),{permeateTargetIp:g,permeateTargetPort:_,visitorPort:k,clientId:f,describe:P,id:I}=(0,r.QW)(b);p.value&&(g.value=p.value.permeateTargetIp,f.value=p.value.clientId,_.value=p.value.permeateTargetPort,k.value=p.value.visitorPort,P.value=p.value.describe,I.value=p.value.id);return(0,t.sV)(async()=>{await(async()=>{VE_API.cloudNetwork.cloudClientFindListGroupByClient({}).then(e=>{0===e.code&&e.data&&(e.data.map(e=>{e.label=e.clientId,e.value=e.clientId}),m.value=e.data?e.data:[])})})()}),(l,d)=>{const n=(0,t.g2)("el-option"),I=(0,t.g2)("el-select"),y=(0,t.g2)("el-form-item"),w=(0,t.g2)("el-input"),V=(0,t.g2)("el-form"),F=(0,t.g2)("el-button"),h=(0,t.g2)("el-dialog");return(0,t.uX)(),(0,t.Wv)(h,{title:(0,r.R1)(i),"append-to-body":"","destroy-on-close":"","model-value":e.showDialog,onClose:d[8]||(d[8]=e=>v())},{footer:(0,t.k6)(()=>[(0,t.Lk)("span",null,[(0,t.bF)(F,{onClick:d[6]||(d[6]=e=>v())},{default:(0,t.k6)(()=>d[9]||(d[9]=[(0,t.eW)("取消")])),_:1,__:[9]}),(0,t.bF)(F,{type:"primary",onClick:d[7]||(d[7]=e=>{c.value.validate(async e=>{if(!e)return console.log("error submit!!"),!1;{let e;e="添加"===i.value?await VE_API.cloudNetworkServerPerMeate.lazyInternalNetworkClientPermeateServerMappingSave(b):await VE_API.cloudNetworkServerPerMeate.lazyInternalNetworkClientPermeateServerMappingUpdate({permeateTargetPort:p.value.permeateTargetPort,...b});const{code:l}=e;0===l&&v()}})})},{default:(0,t.k6)(()=>d[10]||(d[10]=[(0,t.eW)("确定")])),_:1,__:[10]})])]),default:(0,t.k6)(()=>[(0,t.bF)(V,{model:b,ref_key:"formRef",ref:c,rules:a,"label-width":"80px",inline:!1},{default:(0,t.k6)(()=>[(0,t.bF)(y,{label:"客户端ID",prop:"clientId"},{default:(0,t.k6)(()=>[(0,t.bF)(I,{modelValue:(0,r.R1)(f),"onUpdate:modelValue":d[0]||(d[0]=e=>(0,r.i9)(f)?f.value=e:null),placeholder:"客户端ID",clearable:"",onChange:d[1]||(d[1]=e=>(async e=>{let l=await VE_API.cloudNetworkServerPerMeate.lazyNettyClientPermeatePortPoolList({clientId:e});const{code:a}=l;0===a&&l.data&&(l.data.map(e=>{e.label=e.describe,e.value=e.visitorPort}),s.value=l.data?l.data:[])})((0,r.R1)(f)))},{default:(0,t.k6)(()=>[((0,t.uX)(!0),(0,t.CE)(t.FK,null,(0,t.pI)(m.value,e=>((0,t.uX)(),(0,t.Wv)(n,{key:e.value,label:e.label,value:e.value,namespace:e},null,8,["label","value","namespace"]))),128))]),_:1},8,["modelValue"])]),_:1}),(0,t.bF)(y,{label:"客户端访问端口",prop:"visitorPort"},{default:(0,t.k6)(()=>[(0,t.bF)(I,{modelValue:(0,r.R1)(k),"onUpdate:modelValue":d[2]||(d[2]=e=>(0,r.i9)(k)?k.value=e:null),placeholder:"客户端访问端口",clearable:""},{default:(0,t.k6)(()=>[((0,t.uX)(!0),(0,t.CE)(t.FK,null,(0,t.pI)(s.value,e=>((0,t.uX)(),(0,t.Wv)(n,{key:e.value,label:e.label,value:e.value},{default:(0,t.k6)(()=>[(0,t.Lk)("span",o," 端口:【"+(0,u.v_)(e.value)+"】"+(0,u.v_)(e.label),1)]),_:2},1032,["label","value"]))),128))]),_:1},8,["modelValue"])]),_:1}),(0,t.bF)(y,{label:"服务端目标地址",prop:"permeateTargetIp"},{default:(0,t.k6)(()=>[(0,t.bF)(w,{modelValue:(0,r.R1)(g),"onUpdate:modelValue":d[3]||(d[3]=e=>(0,r.i9)(g)?g.value=e:null),placeholder:"",clearable:""},null,8,["modelValue"])]),_:1}),(0,t.bF)(y,{label:"服务端目标端口",prop:"permeateTargetPort"},{default:(0,t.k6)(()=>[(0,t.bF)(w,{modelValue:(0,r.R1)(_),"onUpdate:modelValue":d[4]||(d[4]=e=>(0,r.i9)(_)?_.value=e:null),placeholder:"",clearable:""},null,8,["modelValue"])]),_:1}),(0,t.bF)(y,{label:"描述",prop:"describe"},{default:(0,t.k6)(()=>[(0,t.bF)(w,{modelValue:(0,r.R1)(P),"onUpdate:modelValue":d[5]||(d[5]=e=>(0,r.i9)(P)?P.value=e:null),placeholder:"",clearable:""},null,8,["modelValue"])]),_:1})]),_:1},8,["model"])]),_:1},8,["title","model-value"])}}}}}]);
|
||||
"use strict";(self.webpackChunkwu_vue_zone_ecology_net=self.webpackChunkwu_vue_zone_ecology_net||[]).push([[6724],{96724:function(e,l,a){a.r(l),a.d(l,{default:function(){return d}});a(9243),a(77369);var t=a(38178),r=a(39090),u=a(54039);const o={style:{float:"left"}};var d={__name:"ClientPermeateServerNetworkMappingEdit",props:{showDialog:{type:Boolean,default:!0},title:{type:String,default:"添加"},rowData:{type:Object,default:null}},emits:["closeDialog"],setup(e,{emit:l}){const a={clientId:[{required:!0,message:"请选择客户端",trigger:"blur"}],visitorPort:[{required:!0,message:"请选择访客端口",trigger:"blur"}],permeateTargetIp:[{required:!0,message:"请输入客户端目标IP",trigger:"blur"}],permeateTargetPort:[{required:!0,message:"请输入目标客户端端口",trigger:"blur"}]},d=e,n=l,{title:i,rowData:p}=(0,r.QW)(d),v=()=>{n("closeDialog",!1)},c=(0,r.KR)(null),s=(0,r.KR)(null),m=(0,r.KR)(null),b=(0,r.Kh)({permeateTargetIp:"0.0.0.0",permeateTargetPort:"",visitorPort:"",clientId:"",describe:"",id:""}),{permeateTargetIp:g,permeateTargetPort:_,visitorPort:k,clientId:f,describe:P,id:I}=(0,r.QW)(b);p.value&&(g.value=p.value.permeateTargetIp,f.value=p.value.clientId,_.value=p.value.permeateTargetPort,k.value=p.value.visitorPort,P.value=p.value.describe,I.value=p.value.id);return(0,t.sV)(async()=>{await(async()=>{VE_API.cloudNetwork.cloudClientFindListGroupByClient({}).then(e=>{0===e.code&&e.data&&(e.data.map(e=>{e.label=e.clientId,e.value=e.clientId}),m.value=e.data?e.data:[])})})()}),(l,d)=>{const n=(0,t.g2)("el-option"),I=(0,t.g2)("el-select"),y=(0,t.g2)("el-form-item"),w=(0,t.g2)("el-input"),V=(0,t.g2)("el-form"),F=(0,t.g2)("el-button"),h=(0,t.g2)("el-dialog");return(0,t.uX)(),(0,t.Wv)(h,{title:(0,r.R1)(i),"append-to-body":"","destroy-on-close":"","model-value":e.showDialog,onClose:d[8]||(d[8]=e=>v())},{footer:(0,t.k6)(()=>[(0,t.Lk)("span",null,[(0,t.bF)(F,{onClick:d[6]||(d[6]=e=>v())},{default:(0,t.k6)(()=>d[9]||(d[9]=[(0,t.eW)("取消")])),_:1,__:[9]}),(0,t.bF)(F,{type:"primary",onClick:d[7]||(d[7]=e=>{c.value.validate(async e=>{if(!e)return console.log("error submit!!"),!1;{let e;e="添加"===i.value?await VE_API.cloudNetworkServerPerMeate.lazyInternalNetworkClientPermeateServerMappingSave(b):await VE_API.cloudNetworkServerPerMeate.lazyInternalNetworkClientPermeateServerMappingUpdate({permeateTargetPort:p.value.permeateTargetPort,...b});const{code:l}=e;0===l&&v()}})})},{default:(0,t.k6)(()=>d[10]||(d[10]=[(0,t.eW)("确定")])),_:1,__:[10]})])]),default:(0,t.k6)(()=>[(0,t.bF)(V,{model:b,ref_key:"formRef",ref:c,rules:a,"label-width":"80px",inline:!1},{default:(0,t.k6)(()=>[(0,t.bF)(y,{label:"客户端ID",prop:"clientId"},{default:(0,t.k6)(()=>[(0,t.bF)(I,{modelValue:(0,r.R1)(f),"onUpdate:modelValue":d[0]||(d[0]=e=>(0,r.i9)(f)?f.value=e:null),placeholder:"客户端ID",clearable:"",onChange:d[1]||(d[1]=e=>(async e=>{let l=await VE_API.cloudNetworkServerPerMeate.lazyNettyClientPermeatePortPoolList({clientId:e});const{code:a}=l;0===a&&l.data&&(l.data.map(e=>{e.label=e.describe,e.value=e.visitorPort}),s.value=l.data?l.data:[])})((0,r.R1)(f)))},{default:(0,t.k6)(()=>[((0,t.uX)(!0),(0,t.CE)(t.FK,null,(0,t.pI)(m.value,e=>((0,t.uX)(),(0,t.Wv)(n,{key:e.value,label:e.label,value:e.value,namespace:e},null,8,["label","value","namespace"]))),128))]),_:1},8,["modelValue"])]),_:1}),(0,t.bF)(y,{label:"客户端访问端口",prop:"visitorPort"},{default:(0,t.k6)(()=>[(0,t.bF)(I,{modelValue:(0,r.R1)(k),"onUpdate:modelValue":d[2]||(d[2]=e=>(0,r.i9)(k)?k.value=e:null),placeholder:"客户端访问端口",clearable:""},{default:(0,t.k6)(()=>[((0,t.uX)(!0),(0,t.CE)(t.FK,null,(0,t.pI)(s.value,e=>((0,t.uX)(),(0,t.Wv)(n,{key:e.value,label:e.label,value:e.value},{default:(0,t.k6)(()=>[(0,t.Lk)("span",o," 端口:【"+(0,u.v_)(e.value)+"】"+(0,u.v_)(e.label),1)]),_:2},1032,["label","value"]))),128))]),_:1},8,["modelValue"])]),_:1}),(0,t.bF)(y,{label:"服务端目标地址",prop:"permeateTargetIp"},{default:(0,t.k6)(()=>[(0,t.bF)(w,{modelValue:(0,r.R1)(g),"onUpdate:modelValue":d[3]||(d[3]=e=>(0,r.i9)(g)?g.value=e:null),placeholder:"",clearable:""},null,8,["modelValue"])]),_:1}),(0,t.bF)(y,{label:"服务端目标端口",prop:"permeateTargetPort"},{default:(0,t.k6)(()=>[(0,t.bF)(w,{modelValue:(0,r.R1)(_),"onUpdate:modelValue":d[4]||(d[4]=e=>(0,r.i9)(_)?_.value=e:null),placeholder:"",clearable:""},null,8,["modelValue"])]),_:1}),(0,t.bF)(y,{label:"描述",prop:"describe"},{default:(0,t.k6)(()=>[(0,t.bF)(w,{modelValue:(0,r.R1)(P),"onUpdate:modelValue":d[5]||(d[5]=e=>(0,r.i9)(P)?P.value=e:null),placeholder:"",clearable:""},null,8,["modelValue"])]),_:1})]),_:1},8,["model"])]),_:1},8,["title","model-value"])}}}}}]);
|
||||
@@ -1 +1 @@
|
||||
"use strict";(self.webpackChunkwu_vue_zone_ecology_net=self.webpackChunkwu_vue_zone_ecology_net||[]).push([[7032],{47032:function(e,l,a){a.r(l),a.d(l,{default:function(){return d}});a(9243),a(77369);var t=a(38178),r=a(39090),o=a(54039);const u={style:{float:"left"}};var d={__name:"ServerPermeateServerNetworkMappingEdit",props:{showDialog:{type:Boolean,default:!0},title:{type:String,default:"添加"},rowData:{type:Object,default:null}},emits:["closeDialog"],setup(e,{emit:l}){const a={permeateTargetIp:[{required:!0,message:"请输入客户端目标IP",trigger:"blur"}],permeateTargetPort:[{required:!0,message:"请输入客户端目标端口",trigger:"blur"}],visitorPort:[{required:!0,message:"请选择访客端口",trigger:"blur"}]},d=e,i=l,{title:n,rowData:p}=(0,r.QW)(d),v=()=>{i("closeDialog",!1)},s=(0,r.KR)(null),m=(0,r.KR)(null),c=(0,r.Kh)({permeateTargetIp:"0.0.0.0",permeateTargetPort:"",visitorPort:"",describe:""}),{permeateTargetIp:g,permeateTargetPort:b,visitorPort:_,describe:f}=(0,r.QW)(c);p.value&&(g.value=p.value.permeateTargetIp,b.value=p.value.permeateTargetPort,_.value=p.value.visitorPort,f.value=p.value.describe);return(0,t.sV)(async()=>{await(async()=>{let e=await VE_API.cloudNetworkServerPerMeate.lazyNettyServerPermeatePortPoolList();const{code:l}=e;0===l&&(e.data.map(e=>{e.label=e.describe,e.value=e.visitorPort}),m.value=e.data?e.data:[])})()}),(l,d)=>{const i=(0,t.g2)("el-option"),k=(0,t.g2)("el-select"),P=(0,t.g2)("el-form-item"),w=(0,t.g2)("el-input"),y=(0,t.g2)("el-form"),V=(0,t.g2)("el-button"),F=(0,t.g2)("el-dialog");return(0,t.uX)(),(0,t.Wv)(F,{title:(0,r.R1)(n),"append-to-body":"","destroy-on-close":"","model-value":e.showDialog,onClose:d[6]||(d[6]=e=>v())},{footer:(0,t.k6)(()=>[(0,t.Lk)("span",null,[(0,t.bF)(V,{onClick:d[4]||(d[4]=e=>v())},{default:(0,t.k6)(()=>d[7]||(d[7]=[(0,t.eW)("取消")])),_:1,__:[7]}),(0,t.bF)(V,{type:"primary",onClick:d[5]||(d[5]=e=>{s.value.validate(async e=>{if(!e)return console.log("error submit!!"),!1;{let e;e="添加"===n.value?await VE_API.cloudNetworkServerPerMeate.lazyInternalNetworkServerPermeateMappingSave(c):await VE_API.cloudNetworkServerPerMeate.lazyInternalNetworkServerPermeateMappingUpdate({permeateTargetPort:p.value.permeateTargetPort,...c});const{code:l}=e;0===l&&v()}})})},{default:(0,t.k6)(()=>d[8]||(d[8]=[(0,t.eW)("确定")])),_:1,__:[8]})])]),default:(0,t.k6)(()=>[(0,t.bF)(y,{model:c,ref_key:"formRef",ref:s,rules:a,"label-width":"80px",inline:!1},{default:(0,t.k6)(()=>[(0,t.bF)(P,{label:"访问端口",prop:"visitorPort"},{default:(0,t.k6)(()=>[(0,t.bF)(k,{modelValue:(0,r.R1)(_),"onUpdate:modelValue":d[0]||(d[0]=e=>(0,r.i9)(_)?_.value=e:null),placeholder:"访问端口",clearable:""},{default:(0,t.k6)(()=>[((0,t.uX)(!0),(0,t.CE)(t.FK,null,(0,t.pI)(m.value,e=>((0,t.uX)(),(0,t.Wv)(i,{key:e.value,label:e.label,value:e.value},{default:(0,t.k6)(()=>[(0,t.Lk)("span",u," 端口:【"+(0,o.v_)(e.value)+"】"+(0,o.v_)(e.label),1)]),_:2},1032,["label","value"]))),128))]),_:1},8,["modelValue"])]),_:1}),(0,t.bF)(P,{label:"客户端目标地址",prop:"permeateTargetIp"},{default:(0,t.k6)(()=>[(0,t.bF)(w,{modelValue:(0,r.R1)(g),"onUpdate:modelValue":d[1]||(d[1]=e=>(0,r.i9)(g)?g.value=e:null),placeholder:"",clearable:""},null,8,["modelValue"])]),_:1}),(0,t.bF)(P,{label:"客户端目标端口",prop:"permeateTargetPort"},{default:(0,t.k6)(()=>[(0,t.bF)(w,{modelValue:(0,r.R1)(b),"onUpdate:modelValue":d[2]||(d[2]=e=>(0,r.i9)(b)?b.value=e:null),placeholder:"",clearable:""},null,8,["modelValue"])]),_:1}),(0,t.bF)(P,{label:"描述",prop:"describe"},{default:(0,t.k6)(()=>[(0,t.bF)(w,{modelValue:(0,r.R1)(f),"onUpdate:modelValue":d[3]||(d[3]=e=>(0,r.i9)(f)?f.value=e:null),placeholder:"",clearable:""},null,8,["modelValue"])]),_:1})]),_:1},8,["model"])]),_:1},8,["title","model-value"])}}}}}]);
|
||||
"use strict";(self.webpackChunkwu_vue_zone_ecology_net=self.webpackChunkwu_vue_zone_ecology_net||[]).push([[7032],{47032:function(e,l,a){a.r(l),a.d(l,{default:function(){return d}});a(9243),a(77369);var t=a(38178),r=a(39090),o=a(54039);const u={style:{float:"left"}};var d={__name:"ServerPermeateServerNetworkMappingEdit",props:{showDialog:{type:Boolean,default:!0},title:{type:String,default:"添加"},rowData:{type:Object,default:null}},emits:["closeDialog"],setup(e,{emit:l}){const a={permeateTargetIp:[{required:!0,message:"请输入客户端目标IP",trigger:"blur"}],permeateTargetPort:[{required:!0,message:"请输入目标客户端端口",trigger:"blur"}],visitorPort:[{required:!0,message:"请选择访客端口",trigger:"blur"}]},d=e,i=l,{title:n,rowData:p}=(0,r.QW)(d),v=()=>{i("closeDialog",!1)},s=(0,r.KR)(null),m=(0,r.KR)(null),c=(0,r.Kh)({permeateTargetIp:"0.0.0.0",permeateTargetPort:"",visitorPort:"",describe:""}),{permeateTargetIp:g,permeateTargetPort:b,visitorPort:_,describe:f}=(0,r.QW)(c);p.value&&(g.value=p.value.permeateTargetIp,b.value=p.value.permeateTargetPort,_.value=p.value.visitorPort,f.value=p.value.describe);return(0,t.sV)(async()=>{await(async()=>{let e=await VE_API.cloudNetworkServerPerMeate.lazyNettyServerPermeatePortPoolList();const{code:l}=e;0===l&&(e.data.map(e=>{e.label=e.describe,e.value=e.visitorPort}),m.value=e.data?e.data:[])})()}),(l,d)=>{const i=(0,t.g2)("el-option"),k=(0,t.g2)("el-select"),P=(0,t.g2)("el-form-item"),w=(0,t.g2)("el-input"),y=(0,t.g2)("el-form"),V=(0,t.g2)("el-button"),F=(0,t.g2)("el-dialog");return(0,t.uX)(),(0,t.Wv)(F,{title:(0,r.R1)(n),"append-to-body":"","destroy-on-close":"","model-value":e.showDialog,onClose:d[6]||(d[6]=e=>v())},{footer:(0,t.k6)(()=>[(0,t.Lk)("span",null,[(0,t.bF)(V,{onClick:d[4]||(d[4]=e=>v())},{default:(0,t.k6)(()=>d[7]||(d[7]=[(0,t.eW)("取消")])),_:1,__:[7]}),(0,t.bF)(V,{type:"primary",onClick:d[5]||(d[5]=e=>{s.value.validate(async e=>{if(!e)return console.log("error submit!!"),!1;{let e;e="添加"===n.value?await VE_API.cloudNetworkServerPerMeate.lazyInternalNetworkServerPermeateMappingSave(c):await VE_API.cloudNetworkServerPerMeate.lazyInternalNetworkServerPermeateMappingUpdate({permeateTargetPort:p.value.permeateTargetPort,...c});const{code:l}=e;0===l&&v()}})})},{default:(0,t.k6)(()=>d[8]||(d[8]=[(0,t.eW)("确定")])),_:1,__:[8]})])]),default:(0,t.k6)(()=>[(0,t.bF)(y,{model:c,ref_key:"formRef",ref:s,rules:a,"label-width":"80px",inline:!1},{default:(0,t.k6)(()=>[(0,t.bF)(P,{label:"访问端口",prop:"visitorPort"},{default:(0,t.k6)(()=>[(0,t.bF)(k,{modelValue:(0,r.R1)(_),"onUpdate:modelValue":d[0]||(d[0]=e=>(0,r.i9)(_)?_.value=e:null),placeholder:"访问端口",clearable:""},{default:(0,t.k6)(()=>[((0,t.uX)(!0),(0,t.CE)(t.FK,null,(0,t.pI)(m.value,e=>((0,t.uX)(),(0,t.Wv)(i,{key:e.value,label:e.label,value:e.value},{default:(0,t.k6)(()=>[(0,t.Lk)("span",u," 端口:【"+(0,o.v_)(e.value)+"】"+(0,o.v_)(e.label),1)]),_:2},1032,["label","value"]))),128))]),_:1},8,["modelValue"])]),_:1}),(0,t.bF)(P,{label:"目标客户端地址",prop:"permeateTargetIp"},{default:(0,t.k6)(()=>[(0,t.bF)(w,{modelValue:(0,r.R1)(g),"onUpdate:modelValue":d[1]||(d[1]=e=>(0,r.i9)(g)?g.value=e:null),placeholder:"",clearable:""},null,8,["modelValue"])]),_:1}),(0,t.bF)(P,{label:"目标客户端端口",prop:"permeateTargetPort"},{default:(0,t.k6)(()=>[(0,t.bF)(w,{modelValue:(0,r.R1)(b),"onUpdate:modelValue":d[2]||(d[2]=e=>(0,r.i9)(b)?b.value=e:null),placeholder:"",clearable:""},null,8,["modelValue"])]),_:1}),(0,t.bF)(P,{label:"描述",prop:"describe"},{default:(0,t.k6)(()=>[(0,t.bF)(w,{modelValue:(0,r.R1)(f),"onUpdate:modelValue":d[3]||(d[3]=e=>(0,r.i9)(f)?f.value=e:null),placeholder:"",clearable:""},null,8,["modelValue"])]),_:1})]),_:1},8,["model"])]),_:1},8,["title","model-value"])}}}}}]);
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
"use strict";(self.webpackChunkwu_vue_zone_ecology_net=self.webpackChunkwu_vue_zone_ecology_net||[]).push([[8694],{68694:function(e,l,a){a.r(l),a.d(l,{default:function(){return i}});a(9243),a(77369);var t=a(38178),r=a(39090),o=a(54039);const u={style:{float:"left"}};var i={__name:"ServerPermeateClientNetWorkMappingEdit",props:{showDialog:{type:Boolean,default:!0},title:{type:String,default:"添加"},rowData:{type:Object,default:null}},emits:["closeDialog"],setup(e,{emit:l}){const a={clientId:[{required:!0,message:"请输入选择客户端",trigger:"blur"}],clientTargetIp:[{required:!0,message:"请输入客户端目标IP",trigger:"blur"}],clientTargetPort:[{required:!0,message:"请输入客户端目标端口",trigger:"blur"}],visitorPort:[{required:!0,message:"请选择访客端口",trigger:"blur"}]},i=e,n=l,{title:d,rowData:c}=(0,r.QW)(i),p=()=>{n("closeDialog",!1)},v=(0,r.KR)(null),s=(0,r.KR)(null),b=(0,r.KR)(null),g=(0,r.Kh)({visitorPort:"",targetClientId:"",clientTargetIp:"0.0.0.0",clientTargetPort:"",describe:""}),{visitorPort:m,targetClientId:_,clientTargetIp:k,clientTargetPort:f,describe:P}=(0,r.QW)(g);c.value&&(_.value=c.value.targetClientId,k.value=c.value.clientTargetIp,f.value=c.value.clientTargetPort,m.value=c.value.visitorPort,P.value=c.value.describe);return(0,t.sV)(async()=>{await(async()=>{let e=await VE_API.cloudNetworkServerPerMeate.lazyNettyServerPermeatePortPoolList({});const{code:l}=e;0===l&&(e.data.map(e=>{e.label=e.describe,e.value=e.visitorPort}),b.value=e.data?e.data:[])})(),await(async()=>{VE_API.cloudNetwork.cloudClientFindListGroupByClient({}).then(e=>{0===e.code&&e.data&&(e.data.map(e=>{e.label=e.clientId,e.value=e.clientId}),s.value=e.data?e.data:[])})})()}),(l,i)=>{const n=(0,t.g2)("el-option"),I=(0,t.g2)("el-select"),w=(0,t.g2)("el-form-item"),y=(0,t.g2)("el-input"),V=(0,t.g2)("el-form"),F=(0,t.g2)("el-button"),C=(0,t.g2)("el-dialog");return(0,t.uX)(),(0,t.Wv)(C,{title:(0,r.R1)(d),"append-to-body":"","destroy-on-close":"","model-value":e.showDialog,onClose:i[7]||(i[7]=e=>p())},{footer:(0,t.k6)(()=>[(0,t.Lk)("span",null,[(0,t.bF)(F,{onClick:i[5]||(i[5]=e=>p())},{default:(0,t.k6)(()=>i[8]||(i[8]=[(0,t.eW)("取消")])),_:1,__:[8]}),(0,t.bF)(F,{type:"primary",onClick:i[6]||(i[6]=e=>{v.value.validate(async e=>{if(!e)return console.log("error submit!!"),!1;{let e;e="添加"===d.value?await VE_API.cloudNetwork.networkMappingSave(g):await VE_API.cloudNetwork.networkMappingUpdate({clientTargetPort:c.value.clientTargetPort,...g});const{code:l}=e;0===l&&p()}})})},{default:(0,t.k6)(()=>i[9]||(i[9]=[(0,t.eW)("确定")])),_:1,__:[9]})])]),default:(0,t.k6)(()=>[(0,t.bF)(V,{model:g,ref_key:"formRef",ref:v,rules:a,"label-width":"80px",inline:!1},{default:(0,t.k6)(()=>[(0,t.bF)(w,{label:"访问端口",prop:"visitorPort"},{default:(0,t.k6)(()=>[(0,t.bF)(I,{modelValue:(0,r.R1)(m),"onUpdate:modelValue":i[0]||(i[0]=e=>(0,r.i9)(m)?m.value=e:null),placeholder:"访问端口",clearable:""},{default:(0,t.k6)(()=>[((0,t.uX)(!0),(0,t.CE)(t.FK,null,(0,t.pI)(b.value,e=>((0,t.uX)(),(0,t.Wv)(n,{key:e.value,label:e.label,value:e.value},{default:(0,t.k6)(()=>[(0,t.Lk)("span",u," 端口:【"+(0,o.v_)(e.value)+"】"+(0,o.v_)(e.label),1)]),_:2},1032,["label","value"]))),128))]),_:1},8,["modelValue"])]),_:1}),(0,t.bF)(w,{label:"目标客户端ID",prop:"targetClientId"},{default:(0,t.k6)(()=>[(0,t.bF)(I,{modelValue:(0,r.R1)(_),"onUpdate:modelValue":i[1]||(i[1]=e=>(0,r.i9)(_)?_.value=e:null),placeholder:"目标客户端ID",clearable:""},{default:(0,t.k6)(()=>[((0,t.uX)(!0),(0,t.CE)(t.FK,null,(0,t.pI)(s.value,e=>((0,t.uX)(),(0,t.Wv)(n,{key:e.value,label:e.label,value:e.value,namespace:e},null,8,["label","value","namespace"]))),128))]),_:1},8,["modelValue"])]),_:1}),(0,t.bF)(w,{label:"客户端目标地址",prop:"clientTargetIp"},{default:(0,t.k6)(()=>[(0,t.bF)(y,{modelValue:(0,r.R1)(k),"onUpdate:modelValue":i[2]||(i[2]=e=>(0,r.i9)(k)?k.value=e:null),placeholder:"",clearable:""},null,8,["modelValue"])]),_:1}),(0,t.bF)(w,{label:"客户端目标端口",prop:"clientTargetPort"},{default:(0,t.k6)(()=>[(0,t.bF)(y,{modelValue:(0,r.R1)(f),"onUpdate:modelValue":i[3]||(i[3]=e=>(0,r.i9)(f)?f.value=e:null),placeholder:"",clearable:""},null,8,["modelValue"])]),_:1}),(0,t.bF)(w,{label:"描述",prop:"describe"},{default:(0,t.k6)(()=>[(0,t.bF)(y,{modelValue:(0,r.R1)(P),"onUpdate:modelValue":i[4]||(i[4]=e=>(0,r.i9)(P)?P.value=e:null),placeholder:"",clearable:""},null,8,["modelValue"])]),_:1})]),_:1},8,["model"])]),_:1},8,["title","model-value"])}}}}}]);
|
||||
"use strict";(self.webpackChunkwu_vue_zone_ecology_net=self.webpackChunkwu_vue_zone_ecology_net||[]).push([[8694],{68694:function(e,l,a){a.r(l),a.d(l,{default:function(){return i}});a(9243),a(77369);var t=a(38178),r=a(39090),o=a(54039);const u={style:{float:"left"}};var i={__name:"ServerPermeateClientNetWorkMappingEdit",props:{showDialog:{type:Boolean,default:!0},title:{type:String,default:"添加"},rowData:{type:Object,default:null}},emits:["closeDialog"],setup(e,{emit:l}){const a={clientId:[{required:!0,message:"请输入选择客户端",trigger:"blur"}],clientTargetIp:[{required:!0,message:"请输入客户端目标IP",trigger:"blur"}],clientTargetPort:[{required:!0,message:"请输入目标客户端端口",trigger:"blur"}],visitorPort:[{required:!0,message:"请选择访客端口",trigger:"blur"}]},i=e,n=l,{title:d,rowData:c}=(0,r.QW)(i),p=()=>{n("closeDialog",!1)},v=(0,r.KR)(null),s=(0,r.KR)(null),b=(0,r.KR)(null),g=(0,r.Kh)({visitorPort:"",targetClientId:"",clientTargetIp:"0.0.0.0",clientTargetPort:"",describe:""}),{visitorPort:m,targetClientId:_,clientTargetIp:k,clientTargetPort:f,describe:P}=(0,r.QW)(g);c.value&&(_.value=c.value.targetClientId,k.value=c.value.clientTargetIp,f.value=c.value.clientTargetPort,m.value=c.value.visitorPort,P.value=c.value.describe);return(0,t.sV)(async()=>{await(async()=>{let e=await VE_API.cloudNetworkServerPerMeate.lazyNettyServerPermeatePortPoolList({});const{code:l}=e;0===l&&(e.data.map(e=>{e.label=e.describe,e.value=e.visitorPort}),b.value=e.data?e.data:[])})(),await(async()=>{VE_API.cloudNetwork.cloudClientFindListGroupByClient({}).then(e=>{0===e.code&&e.data&&(e.data.map(e=>{e.label=e.clientId,e.value=e.clientId}),s.value=e.data?e.data:[])})})()}),(l,i)=>{const n=(0,t.g2)("el-option"),I=(0,t.g2)("el-select"),w=(0,t.g2)("el-form-item"),y=(0,t.g2)("el-input"),V=(0,t.g2)("el-form"),F=(0,t.g2)("el-button"),C=(0,t.g2)("el-dialog");return(0,t.uX)(),(0,t.Wv)(C,{title:(0,r.R1)(d),"append-to-body":"","destroy-on-close":"","model-value":e.showDialog,onClose:i[7]||(i[7]=e=>p())},{footer:(0,t.k6)(()=>[(0,t.Lk)("span",null,[(0,t.bF)(F,{onClick:i[5]||(i[5]=e=>p())},{default:(0,t.k6)(()=>i[8]||(i[8]=[(0,t.eW)("取消")])),_:1,__:[8]}),(0,t.bF)(F,{type:"primary",onClick:i[6]||(i[6]=e=>{v.value.validate(async e=>{if(!e)return console.log("error submit!!"),!1;{let e;e="添加"===d.value?await VE_API.cloudNetwork.networkMappingSave(g):await VE_API.cloudNetwork.networkMappingUpdate({clientTargetPort:c.value.clientTargetPort,...g});const{code:l}=e;0===l&&p()}})})},{default:(0,t.k6)(()=>i[9]||(i[9]=[(0,t.eW)("确定")])),_:1,__:[9]})])]),default:(0,t.k6)(()=>[(0,t.bF)(V,{model:g,ref_key:"formRef",ref:v,rules:a,"label-width":"80px",inline:!1},{default:(0,t.k6)(()=>[(0,t.bF)(w,{label:"访问端口",prop:"visitorPort"},{default:(0,t.k6)(()=>[(0,t.bF)(I,{modelValue:(0,r.R1)(m),"onUpdate:modelValue":i[0]||(i[0]=e=>(0,r.i9)(m)?m.value=e:null),placeholder:"访问端口",clearable:""},{default:(0,t.k6)(()=>[((0,t.uX)(!0),(0,t.CE)(t.FK,null,(0,t.pI)(b.value,e=>((0,t.uX)(),(0,t.Wv)(n,{key:e.value,label:e.label,value:e.value},{default:(0,t.k6)(()=>[(0,t.Lk)("span",u," 端口:【"+(0,o.v_)(e.value)+"】"+(0,o.v_)(e.label),1)]),_:2},1032,["label","value"]))),128))]),_:1},8,["modelValue"])]),_:1}),(0,t.bF)(w,{label:"目标客户端ID",prop:"targetClientId"},{default:(0,t.k6)(()=>[(0,t.bF)(I,{modelValue:(0,r.R1)(_),"onUpdate:modelValue":i[1]||(i[1]=e=>(0,r.i9)(_)?_.value=e:null),placeholder:"目标客户端ID",clearable:""},{default:(0,t.k6)(()=>[((0,t.uX)(!0),(0,t.CE)(t.FK,null,(0,t.pI)(s.value,e=>((0,t.uX)(),(0,t.Wv)(n,{key:e.value,label:e.label,value:e.value,namespace:e},null,8,["label","value","namespace"]))),128))]),_:1},8,["modelValue"])]),_:1}),(0,t.bF)(w,{label:"目标客户端地址",prop:"clientTargetIp"},{default:(0,t.k6)(()=>[(0,t.bF)(y,{modelValue:(0,r.R1)(k),"onUpdate:modelValue":i[2]||(i[2]=e=>(0,r.i9)(k)?k.value=e:null),placeholder:"",clearable:""},null,8,["modelValue"])]),_:1}),(0,t.bF)(w,{label:"目标客户端端口",prop:"clientTargetPort"},{default:(0,t.k6)(()=>[(0,t.bF)(y,{modelValue:(0,r.R1)(f),"onUpdate:modelValue":i[3]||(i[3]=e=>(0,r.i9)(f)?f.value=e:null),placeholder:"",clearable:""},null,8,["modelValue"])]),_:1}),(0,t.bF)(w,{label:"描述",prop:"describe"},{default:(0,t.k6)(()=>[(0,t.bF)(y,{modelValue:(0,r.R1)(P),"onUpdate:modelValue":i[4]||(i[4]=e=>(0,r.i9)(P)?P.value=e:null),placeholder:"",clearable:""},null,8,["modelValue"])]),_:1})]),_:1},8,["model"])]),_:1},8,["title","model-value"])}}}}}]);
|
||||
@@ -0,0 +1 @@
|
||||
"use strict";(self.webpackChunkwu_vue_zone_ecology_net=self.webpackChunkwu_vue_zone_ecology_net||[]).push([[9009,9285],{37141:function(e,a,t){t.r(a),t.d(a,{default:function(){return _}});t(31542);var l=t(38178),s=t(39090),r=t(49401),o=t(9707),n=t(94854),u=t(10425),d=t(89164),i=t(62859);const c={class:"ve_container"};var p={__name:"Login",setup(e){const a={username:[{required:!0,message:"请输入用户名",trigger:"blur"}],password:[{required:!0,message:"请输入密码",trigger:"blur"}]},t=(0,u.Pj)(),p=(0,d.rd)(),_=(0,s.Kh)({username:"",password:""}),{username:m,password:f}=(0,s.QW)(_),k=(0,s.KR)(null),b=(0,s.KR)(!1);sessionStorage.clear(),t.dispatch(`app/${o.$T}`,""),p.options.isAddDynamicMenuRoutes=!1;const g=()=>{k.value.validate(async e=>{if(e)try{const e=await VE_API.system.login(_);if(0===e.code){await t.dispatch(`app/${o.$T}`,e.data),await t.dispatch(`app/${o.w3}`,e.data.accessToken),await t.dispatch(`app/${o.jr}`,e.data.refreshToken),await t.dispatch(`app/${o.Q1}`,_.username);try{const a=await VE_API.system.resolvingUser({accessToken:e.data.accessToken});a&&a.id&&await t.dispatch(`app/${o.Dl}`,a.id)}catch(e){console.warn("获取用户信息失败:",e)}b.value=!0,i.nk.success("登录成功"),p.push({name:"Zone"})}else{const a=e.message||"登录失败,请检查用户名和密码";i.nk.error(a)}}catch(e){console.error("登录异常:",e)}})};return(e,t)=>{const o=(0,l.g2)("router-link"),u=(0,l.g2)("el-button"),d=(0,l.g2)("Avatar"),i=(0,l.g2)("el-icon"),p=(0,l.g2)("el-input"),h=(0,l.g2)("el-form-item"),v=(0,l.g2)("Key"),w=(0,l.g2)("el-form"),y=(0,l.g2)("el-card");return(0,l.uX)(),(0,l.Wv)((0,s.R1)(n.default),null,{default:(0,l.k6)(()=>[(0,l.Lk)("div",c,[(0,l.bF)(y,{"body-style":{background:"rgba(0,0,0,0.15)"}},{default:(0,l.k6)(()=>[(0,l.bF)(u,{class:"ve_submit",type:"plain",style:{float:"right"}},{default:(0,l.k6)(()=>[(0,l.bF)(o,{to:{path:"register"},style:{"text-decoration":"none",color:"inherit"}},{default:(0,l.k6)(()=>t[2]||(t[2]=[(0,l.eW)("注册")])),_:1,__:[2]})]),_:1}),t[4]||(t[4]=(0,l.Lk)("h1",null,"wlcn服务端",-1)),(0,l.bF)(r.eB,{name:"el-fade-in-linear"},{default:(0,l.k6)(()=>[(0,l.bo)((0,l.bF)(w,{model:_,rules:a,class:"ve_form",ref_key:"ref_form",ref:k,inline:!1,onKeyup:(0,r.jR)(g,["enter"])},{default:(0,l.k6)(()=>[(0,l.bF)(h,{prop:"username"},{default:(0,l.k6)(()=>[(0,l.bF)(p,{modelValue:(0,s.R1)(m),"onUpdate:modelValue":t[0]||(t[0]=e=>(0,s.i9)(m)?m.value=e:null),modelModifiers:{trim:!0},placeholder:"用户名"},{prepend:(0,l.k6)(()=>[(0,l.bF)(i,{size:20},{default:(0,l.k6)(()=>[(0,l.bF)(d)]),_:1})]),_:1},8,["modelValue"])]),_:1}),(0,l.bF)(h,{prop:"password"},{default:(0,l.k6)(()=>[(0,l.bF)(p,{modelValue:(0,s.R1)(f),"onUpdate:modelValue":t[1]||(t[1]=e=>(0,s.i9)(f)?f.value=e:null),modelModifiers:{trim:!0},"show-password":"",placeholder:"密码"},{prepend:(0,l.k6)(()=>[(0,l.bF)(i,{size:20},{default:(0,l.k6)(()=>[(0,l.bF)(v)]),_:1})]),_:1},8,["modelValue"])]),_:1}),(0,l.bF)(h,null,{default:(0,l.k6)(()=>[(0,l.bF)(u,{class:"ve_submit",type:"primary",onClick:g},{default:(0,l.k6)(()=>t[3]||(t[3]=[(0,l.eW)(" 登录 ")])),_:1,__:[3]})]),_:1})]),_:1},8,["model"]),[[r.aG,!b.value]])]),_:1})]),_:1,__:[4]})])]),_:1})}}};var _=(0,t(45924).A)(p,[["__scopeId","data-v-c00b4710"]])}}]);
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>top.wu2020</groupId>
|
||||
<artifactId>wu-lazy-cloud-network</artifactId>
|
||||
<version>1.3.4-JDK24-SNAPSHOT</version>
|
||||
<version>1.3.6-JDK24</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>wu-lazy-cloud-heartbeat-start</artifactId>
|
||||
@@ -35,7 +35,7 @@
|
||||
</scm>
|
||||
|
||||
<modules>
|
||||
<!-- 样例 -->
|
||||
<!-- 启动程序 -->
|
||||
<module>wu-lazy-cloud-heartbeat-client-start</module>
|
||||
<module>wu-lazy-cloud-heartbeat-server-start</module>
|
||||
<module>wu-lazy-cloud-heartbeat-server-cluster-start</module>
|
||||
|
||||
@@ -115,23 +115,3 @@ http://127.0.0.1:18080
|
||||
mkdir -p ./jpackage-input
|
||||
cp ./target/*.jar ./jpackage-input/app.jar
|
||||
|
||||
|
||||
```
|
||||
## 打包成Mac程序
|
||||
```shell
|
||||
|
||||
jpackage \
|
||||
--input target \
|
||||
--name wlcn-client \
|
||||
--main-jar wu-lazy-cloud-heartbeat-client-start-1.3.4-JDK24-SNAPSHOT.jar \
|
||||
--main-class org.framework.lazy.cloud.network.heartbeat.client.LazyCloudHeartbeatClientStart \
|
||||
--type dmg \
|
||||
--vendor "小吴小吴bug全无" \
|
||||
--app-version 1.3.4 \
|
||||
--icon src/main/resources/app.icns \
|
||||
--verbose\
|
||||
--java-options "-XstartOnFirstThread" \
|
||||
--java-options "-Dlogging.file.name=logs/wlcn-client.log" \
|
||||
--java-options "-Dapple.awt.UIElement=false"
|
||||
|
||||
```
|
||||
@@ -1,414 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# 异常日志文件路径
|
||||
ERROR_LOG_FILE="packaging_error.log"
|
||||
|
||||
#######################################
|
||||
# 配置参数 - 仅在此处修改参数值
|
||||
#######################################
|
||||
APP_NAME="wlcn-client"
|
||||
APP_VERSION="1.0.0"
|
||||
MAIN_CLASS="org.framework.lazy.cloud.network.heartbeat.client.LazyCloudHeartbeatClientStart"
|
||||
ICON_FILE="src/main/resources/app.icns"
|
||||
# 修复变量名拼写错误:OUTPUTPUT_BASE -> OUTPUT_BASE
|
||||
OUTPUT_BASE="./build"
|
||||
JDK_HOME=${JAVA_HOME}
|
||||
#######################################
|
||||
|
||||
# 派生路径
|
||||
JRE_DIR="${OUTPUT_BASE}/myjre"
|
||||
OUTPUT_DIR="${OUTPUT_BASE}/dist"
|
||||
MAIN_JAR="" # 初始化主JAR路径变量
|
||||
MODULES=""
|
||||
|
||||
# 函数:去除路径末尾的斜杠
|
||||
trim_trailing_slash() {
|
||||
local path="$1"
|
||||
# 若路径非空且以/结尾,则去除末尾的/
|
||||
if [ -n "$path" ] && [ "${path: -1}" = "/" ]; then
|
||||
echo "${path%/}"
|
||||
else
|
||||
echo "$path"
|
||||
fi
|
||||
}
|
||||
|
||||
# 函数:记录错误日志并退出
|
||||
error_exit() {
|
||||
local error_message="$1"
|
||||
local timestamp=$(date +"%Y-%m-%d %H:%M:%S")
|
||||
|
||||
# 输出到控制台
|
||||
echo -e "\033[0;31m错误: $error_message\033[0m" >&2
|
||||
|
||||
# 记录到日志文件
|
||||
echo "[$timestamp] 错误: $error_message" >> "$ERROR_LOG_FILE"
|
||||
echo "[$timestamp] 脚本异常退出" >> "$ERROR_LOG_FILE"
|
||||
echo "----------------------------------------" >> "$ERROR_LOG_FILE"
|
||||
|
||||
# 退出脚本
|
||||
exit 1
|
||||
}
|
||||
|
||||
# 函数:在指定目录中查找JAR文件并赋值给MAIN_JAR
|
||||
find_jar_in_directory() {
|
||||
local dir="$1"
|
||||
|
||||
# 检查目录是否存在
|
||||
if [ ! -d "$dir" ]; then
|
||||
echo "错误:目录 '$dir' 不存在"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# 查找目录中的JAR文件(兼容写法)
|
||||
local valid_jars=()
|
||||
for jar in $(ls -1 "$dir"/*.jar 2>/dev/null); do
|
||||
if [ -f "$jar" ]; then
|
||||
valid_jars+=("$jar")
|
||||
fi
|
||||
done
|
||||
|
||||
# 检查JAR文件情况
|
||||
if [ ${#valid_jars[@]} -eq 0 ]; then
|
||||
echo "错误:在目录 '$dir' 中未找到任何JAR文件"
|
||||
return 1
|
||||
elif [ ${#valid_jars[@]} -gt 1 ]; then
|
||||
echo "错误:在目录 '$dir' 中找到多个JAR文件:"
|
||||
for jar in "${valid_jars[@]}"; do
|
||||
echo " - $(basename "$jar")"
|
||||
done
|
||||
return 1
|
||||
else
|
||||
# 找到唯一JAR文件,赋值给全局变量MAIN_JAR
|
||||
MAIN_JAR="${valid_jars[0]}"
|
||||
echo "找到JAR文件:$MAIN_JAR"
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
# 函数:获取JAR文件,支持用户指定目录(带Tab补全)
|
||||
get_main_jar() {
|
||||
local valid_jars=()
|
||||
|
||||
# 过滤出当前目录中有效的JAR文件(兼容写法)
|
||||
for jar in $(ls -1 *.jar 2>/dev/null); do
|
||||
if [ -f "$jar" ]; then
|
||||
valid_jars+=("$jar")
|
||||
fi
|
||||
done
|
||||
|
||||
# 如果当前目录找到唯一JAR文件,直接赋值
|
||||
if [ ${#valid_jars[@]} -eq 1 ]; then
|
||||
MAIN_JAR="${valid_jars[0]}"
|
||||
echo "当前目录找到JAR文件:$MAIN_JAR"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# 处理多个JAR文件的情况
|
||||
if [ ${#valid_jars[@]} -gt 1 ]; then
|
||||
local jar_list=""
|
||||
for jar in "${valid_jars[@]}"; do
|
||||
jar_list+=" - $(basename "$jar")\n"
|
||||
done
|
||||
error_exit "当前目录下找到多个JAR文件,请保留唯一主JAR文件后重试:\n$jar_list"
|
||||
fi
|
||||
|
||||
# 当前目录未找到JAR文件,提示用户输入目录(支持Tab补全)
|
||||
echo "当前目录下未找到任何JAR文件。"
|
||||
local jar_dir=""
|
||||
local trimmed_dir=""
|
||||
|
||||
while true; do
|
||||
# 使用read -e启用Tab键路径补全
|
||||
read -e -p "请输入包含JAR文件的文件夹路径(相对路径,按Tab键可补全): " jar_dir
|
||||
|
||||
# 处理用户输入的路径(去除末尾斜杠)
|
||||
trimmed_dir=$(trim_trailing_slash "$jar_dir")
|
||||
|
||||
if [ -z "$trimmed_dir" ]; then
|
||||
echo "路径不能为空,请重新输入"
|
||||
continue
|
||||
fi
|
||||
|
||||
# 尝试查找JAR文件并赋值给MAIN_JAR
|
||||
if find_jar_in_directory "$trimmed_dir"; then
|
||||
# 查找成功,MAIN_JAR已被赋值
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# 函数:初始化参数数组(使用两个索引数组替代关联数组)
|
||||
init_parameters() {
|
||||
# 参数名称数组
|
||||
local names=(
|
||||
"应用名称"
|
||||
"版本号"
|
||||
"主类全路径"
|
||||
"主JAR文件"
|
||||
"图标文件"
|
||||
"输出目录"
|
||||
"JDK安装路径"
|
||||
"自定义JRE目录"
|
||||
)
|
||||
|
||||
# 参数值数组(与名称数组顺序对应)
|
||||
local values=(
|
||||
"$APP_NAME"
|
||||
"$APP_VERSION"
|
||||
"$MAIN_CLASS"
|
||||
"$MAIN_JAR"
|
||||
"$ICON_FILE"
|
||||
"$OUTPUT_DIR"
|
||||
"$JDK_HOME"
|
||||
"$JRE_DIR"
|
||||
)
|
||||
|
||||
# 返回两个数组(通过字符串拼接传递)
|
||||
echo "${names[*]}|||${values[*]}"
|
||||
}
|
||||
|
||||
# 函数:显示参数表格
|
||||
display_parameters() {
|
||||
local params_str="$1"
|
||||
# 拆分参数数组
|
||||
local names_str="${params_str%%|||*}"
|
||||
local values_str="${params_str#*|||}"
|
||||
|
||||
# 转换为数组
|
||||
local names=($names_str)
|
||||
local values=($values_str)
|
||||
|
||||
# 计算最长参数名长度
|
||||
local max_len=0
|
||||
for name in "${names[@]}"; do
|
||||
local len=${#name}
|
||||
if (( len > max_len )); then
|
||||
max_len=$len
|
||||
fi
|
||||
done
|
||||
|
||||
local term_width=$(tput cols 2>/dev/null || echo 80)
|
||||
local line=$(printf "%0.s-" $(seq 1 $term_width))
|
||||
|
||||
echo -e "\n===== 打包参数信息 ====="
|
||||
echo "$line"
|
||||
printf "| %-${max_len}s | %s |\n" "参数名称" "参数值"
|
||||
echo "$line"
|
||||
|
||||
# 遍历输出所有参数(使用索引对应)
|
||||
for ((i=0; i<${#names[@]}; i++)); do
|
||||
printf "| %-${max_len}s | %s |\n" "${names[$i]}" "${values[$i]}"
|
||||
done
|
||||
|
||||
echo "$line"
|
||||
}
|
||||
|
||||
# 函数:参数确认
|
||||
confirm_parameters() {
|
||||
local params_str="$1"
|
||||
display_parameters "$params_str"
|
||||
|
||||
while true; do
|
||||
read -p $'\n确认使用以上参数?(输入 o 继续,q 取消) ' -n 1 -r
|
||||
echo
|
||||
if [[ $REPLY =~ ^[Oo]$ ]]; then
|
||||
echo "用户确认,继续操作..."
|
||||
return 0
|
||||
elif [[ $REPLY =~ ^[Qq]$ ]]; then
|
||||
echo "用户取消操作"
|
||||
return 1
|
||||
else
|
||||
echo "无效输入,请输入 o 或 q"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# 函数:生成自定义JRE
|
||||
# 函数:生成自定义JRE
|
||||
generate_jre() {
|
||||
echo -e "\n==> 开始生成自定义JRE..."
|
||||
local timestamp=$(date +"%Y-%m-%d %H:%M:%S")
|
||||
echo "[$timestamp] 开始生成自定义JRE" >> "$ERROR_LOG_FILE"
|
||||
|
||||
# 检查JRE目录是否已存在
|
||||
if [ -d "${JRE_DIR}" ]; then
|
||||
echo -e "\033[0;33m警告:JRE目录已存在 - ${JRE_DIR}\033[0m"
|
||||
while true; do
|
||||
read -p "请选择操作 (1: 继续执行并删除现有目录, 2: 跳过生成JRE) [1/2]: " choice
|
||||
case $choice in
|
||||
1)
|
||||
echo "==> 删除现有JRE目录: ${JRE_DIR}"
|
||||
rm -rf "${JRE_DIR}" || error_exit "无法删除现有JRE目录,请检查权限"
|
||||
break
|
||||
;;
|
||||
2)
|
||||
echo "==> 跳过JRE生成操作"
|
||||
return 0
|
||||
;;
|
||||
*)
|
||||
echo "无效输入,请输入1或2"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
|
||||
# 检查JAR文件是否存在
|
||||
if [ ! -f "${MAIN_JAR}" ]; then
|
||||
error_exit "JAR文件不存在 - ${MAIN_JAR}\n请检查文件是否被移动或删除"
|
||||
fi
|
||||
|
||||
# 分析依赖模块
|
||||
echo "==> 分析应用依赖的Java模块..."
|
||||
MODULES=$(jdeps --print-module-deps --ignore-missing-deps "${MAIN_JAR}" 2>> "$ERROR_LOG_FILE" | tr -d '\n')
|
||||
|
||||
if [ -z "${MODULES}" ]; then
|
||||
echo "警告:未检测到依赖模块,使用默认模块集"
|
||||
MODULES="java.base,java.desktop"
|
||||
fi
|
||||
echo "检测到的Java模块:${MODULES}"
|
||||
echo "[$(date +"%Y-%m-%d %H:%M:%S")] 检测到的Java模块:${MODULES}" >> "$ERROR_LOG_FILE"
|
||||
|
||||
# 生成JRE(修复输出路径错误,移除多余的)
|
||||
if ! jlink \
|
||||
--module-path "${JDK_HOME}/jmods" \
|
||||
--add-modules "${MODULES}" \
|
||||
--output "${JRE_DIR}" \
|
||||
--strip-debug \
|
||||
--no-man-pages \
|
||||
--no-header-files; then
|
||||
error_exit "JLink命令执行失败,详情请查看日志文件: $ERROR_LOG_FILE"
|
||||
fi
|
||||
|
||||
# 验证JRE
|
||||
if [ ! -f "${JRE_DIR}/bin/java" ]; then
|
||||
error_exit "JRE生成失败,未找到java可执行文件"
|
||||
fi
|
||||
|
||||
echo -e "\n==> JRE生成成功!"
|
||||
echo "JRE版本信息:"
|
||||
"${JRE_DIR}/bin/java" -version
|
||||
echo "JRE路径:${JRE_DIR}"
|
||||
echo "[$(date +"%Y-%m-%d %H:%M:%S")] JRE生成成功:${JRE_DIR}" >> "$ERROR_LOG_FILE"
|
||||
return 0
|
||||
}
|
||||
|
||||
# 函数:打包DMG
|
||||
package_dmg() {
|
||||
echo -e "\n==> 开始打包DMG文件..."
|
||||
local timestamp=$(date +"%Y-%m-%d %H:%M:%S")
|
||||
echo "[$timestamp] 开始打包DMG文件" >> "$ERROR_LOG_FILE"
|
||||
|
||||
# 检查输出目录是否存在,不存在则创建
|
||||
if [ ! -d "${OUTPUT_DIR}" ]; then
|
||||
echo "==> 输出目录不存在,创建目录: ${OUTPUT_DIR}"
|
||||
mkdir -p "${OUTPUT_DIR}" || error_exit "无法创建输出目录: ${OUTPUT_DIR}"
|
||||
else
|
||||
echo "==> 输出目录已存在,无需创建: ${OUTPUT_DIR}"
|
||||
fi
|
||||
|
||||
# 检查JAR文件是否存在
|
||||
if [ ! -f "${MAIN_JAR}" ]; then
|
||||
error_exit "JAR文件不存在 - ${MAIN_JAR}\n请检查文件是否被移动或删除"
|
||||
fi
|
||||
|
||||
# 检查JRE是否存在
|
||||
if [ ! -d "${JRE_DIR}" ] || [ ! -f "${JRE_DIR}/bin/java" ]; then
|
||||
error_exit "未找到有效的JRE,请先执行生成JRE操作(选项1)"
|
||||
fi
|
||||
|
||||
|
||||
|
||||
# 执行打包
|
||||
if ! eval jpackage \
|
||||
--input . \
|
||||
--type dmg \
|
||||
--name "${APP_NAME}" \
|
||||
--app-version "${APP_VERSION}" \
|
||||
--main-jar "${MAIN_JAR}" \
|
||||
--main-class "${MAIN_CLASS}" \
|
||||
--runtime-image "${JRE_DIR}" \
|
||||
--dest "${OUTPUT_DIR}" \
|
||||
# --icon "${ICON_FILE}" \
|
||||
--vendor "小吴小吴bug全无" >> "$ERROR_LOG_FILE" 2>&1; then
|
||||
error_exit "JPackage命令执行失败,详情请查看日志文件: $ERROR_LOG_FILE"
|
||||
fi
|
||||
|
||||
echo -e "\n==> DMG打包完成!"
|
||||
echo "生成的DMG文件位于:${OUTPUT_DIR}"
|
||||
echo "应用名称:${APP_NAME}-${APP_VERSION}.dmg"
|
||||
echo "[$(date +"%Y-%m-%d %H:%M:%S")] DMG打包完成:${OUTPUT_DIR}/${APP_NAME}-${APP_VERSION}.dmg" >> "$ERROR_LOG_FILE"
|
||||
return 0
|
||||
}
|
||||
|
||||
# 函数:显示操作菜单
|
||||
show_menu() {
|
||||
clear
|
||||
echo "====================================="
|
||||
echo " 应用打包工具 "
|
||||
echo "====================================="
|
||||
echo "1. 生成自定义JRE"
|
||||
echo "2. 打包DMG文件(需先完成步骤1)"
|
||||
echo "3. 退出"
|
||||
echo "====================================="
|
||||
}
|
||||
|
||||
# 初始化日志文件
|
||||
echo "=====================================" > "$ERROR_LOG_FILE"
|
||||
echo "打包工具日志 - $(date +"%Y-%m-%d %H:%M:%S")" >> "$ERROR_LOG_FILE"
|
||||
echo "=====================================" >> "$ERROR_LOG_FILE"
|
||||
|
||||
# 主流程
|
||||
echo "==> 开始准备环境..."
|
||||
echo "[$(date +"%Y-%m-%d %H:%M:%S")] 开始准备环境" >> "$ERROR_LOG_FILE"
|
||||
|
||||
# 尝试获取主JAR并赋值给MAIN_JAR
|
||||
echo "==> 正在检测JAR文件..."
|
||||
if ! get_main_jar; then
|
||||
error_exit "获取JAR文件失败"
|
||||
fi
|
||||
echo "==> 主JAR文件已设置为:$MAIN_JAR"
|
||||
echo "[$(date +"%Y-%m-%d %H:%M:%S")] 主JAR文件已设置为:$MAIN_JAR" >> "$ERROR_LOG_FILE"
|
||||
|
||||
# 初始化参数数组
|
||||
params_str=$(init_parameters)
|
||||
|
||||
# 显示菜单并处理用户选择
|
||||
while true; do
|
||||
show_menu
|
||||
read -p "请选择操作 [1-3]: " choice
|
||||
|
||||
case $choice in
|
||||
1)
|
||||
# 生成自定义JRE
|
||||
if confirm_parameters "$params_str"; then
|
||||
# 仅确保基础输出目录存在,JRE目录在generate_jre中处理
|
||||
if [ ! -d "${OUTPUT_BASE}" ]; then
|
||||
mkdir -p "${OUTPUT_BASE}" || error_exit "无法创建基础输出目录: ${OUTPUT_BASE}"
|
||||
fi
|
||||
if ! generate_jre; then
|
||||
echo "生成JRE过程中出现错误,详情请查看日志"
|
||||
fi
|
||||
fi
|
||||
read -p "按任意键返回菜单..."
|
||||
;;
|
||||
2)
|
||||
# 打包DMG
|
||||
if confirm_parameters "$params_str"; then
|
||||
if ! package_dmg; then
|
||||
echo "打包DMG过程中出现错误,详情请查看日志"
|
||||
fi
|
||||
fi
|
||||
read -p "按任意键返回菜单..."
|
||||
;;
|
||||
3)
|
||||
echo "==> 退出程序,再见!"
|
||||
echo "[$(date +"%Y-%m-%d %H:%M:%S")] 正常退出程序" >> "$ERROR_LOG_FILE"
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "无效选择,请输入1-3之间的数字"
|
||||
read -p "按任意键继续..."
|
||||
;;
|
||||
esac
|
||||
done
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>top.wu2020</groupId>
|
||||
<artifactId>wu-lazy-cloud-heartbeat-start</artifactId>
|
||||
<version>1.3.4-JDK24-SNAPSHOT</version>
|
||||
<version>1.3.6-JDK24</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -68,29 +68,6 @@
|
||||
</annotationProcessorPaths>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<!-- <plugin>-->
|
||||
<!-- <groupId>org.graalvm.buildtools</groupId>-->
|
||||
<!-- <artifactId>native-maven-plugin</artifactId>-->
|
||||
<!-- <version>0.10.3</version>-->
|
||||
<!-- <configuration>-->
|
||||
<!-- <!– imageName用于设置生成的二进制文件名称 –>-->
|
||||
<!-- <imageName>${project.artifactId}</imageName>-->
|
||||
<!-- <!– mainClass用于指定main方法类路径 –>-->
|
||||
<!-- <mainClass>org.framework.lazy.cloud.network.heartbeat.client.LazyCloudHeartbeatClientStart</mainClass>-->
|
||||
<!-- <buildArgs>-->
|
||||
<!-- --no-fallback-->
|
||||
<!-- </buildArgs>-->
|
||||
<!-- </configuration>-->
|
||||
<!-- <executions>-->
|
||||
<!-- <execution>-->
|
||||
<!-- <id>build-native</id>-->
|
||||
<!-- <goals>-->
|
||||
<!-- <goal>compile-no-fork</goal>-->
|
||||
<!-- </goals>-->
|
||||
<!-- <phase>package</phase>-->
|
||||
<!-- </execution>-->
|
||||
<!-- </executions>-->
|
||||
<!-- </plugin>-->
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
@@ -122,9 +99,8 @@
|
||||
<argument>--verbose</argument>
|
||||
|
||||
<argument>--type</argument>
|
||||
<argument>dmg</argument>
|
||||
<!-- <argument>${os.name.contains("Windows") ? "msi" : (os.name.contains("Mac") ? "dmg" : "deb")}</argument>-->
|
||||
|
||||
<argument>${packaging.type}</argument>
|
||||
<!-- 根据操作系统动态设置打包类型 -->
|
||||
<argument>--input</argument>
|
||||
<argument>target</argument>
|
||||
|
||||
@@ -132,25 +108,29 @@
|
||||
<argument>target/installer</argument>
|
||||
|
||||
<argument>--name</argument>
|
||||
<argument>wlcn-client</argument>
|
||||
<argument>wlcn-client-${os.name}-${project.version}</argument>
|
||||
|
||||
<argument>--main-jar</argument>
|
||||
<argument>${project.build.finalName}.jar</argument>
|
||||
|
||||
<argument>--main-class</argument>
|
||||
<argument>org.framework.lazy.cloud.network.heartbeat.client.LazyCloudHeartbeatClientStart</argument>
|
||||
<argument>org.springframework.boot.loader.launch.JarLauncher</argument>
|
||||
|
||||
<!-- <argument>--icon</argument>-->
|
||||
<!-- <argument>src/main/resources/app${os.name.contains("Windows") ? ".ico" : (os.name.contains("Mac") ? ".icns" : ".png")}</argument>-->
|
||||
|
||||
<argument>--app-version</argument>
|
||||
<argument>1.3.4</argument>
|
||||
<argument>1.3.6</argument>
|
||||
|
||||
<argument>--vendor</argument>
|
||||
<argument>小吴小吴bug全无</argument>
|
||||
<argument>小吴小吴bug全无${os.name}</argument>
|
||||
|
||||
<argument>--description</argument>
|
||||
<argument>Spring Boot Application</argument>
|
||||
<argument>${description}</argument>
|
||||
|
||||
<argument>--java-options</argument>
|
||||
<argument>-server -XX:+TieredCompilation -XX:TieredStopAtLevel=1 -Xms64m -Xmx256m -XX:+UseParallelGC</argument>
|
||||
|
||||
</arguments>
|
||||
</configuration>
|
||||
</execution>
|
||||
|
||||
@@ -3,6 +3,8 @@ package org.framework.lazy.cloud.network.heartbeat.client;
|
||||
import io.netty.util.internal.PlatformDependent;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.wu.framework.javafx.spring.starter.SpringJavaFxLauncher;
|
||||
import org.wu.framework.lazy.orm.core.stereotype.LazyScan;
|
||||
|
||||
/**
|
||||
@@ -11,13 +13,13 @@ import org.wu.framework.lazy.orm.core.stereotype.LazyScan;
|
||||
|
||||
@LazyScan(scanBasePackages = "org.framework.lazy.cloud.network.heartbeat.client.infrastructure.entity")
|
||||
@SpringBootApplication
|
||||
@Import(SpringJavaFxLauncher.class)
|
||||
public class LazyCloudHeartbeatClientStart {
|
||||
public static void main(String[] args) {
|
||||
|
||||
String normalizedArch = PlatformDependent.normalizedArch();
|
||||
String normalizedOs = PlatformDependent.normalizedOs();
|
||||
System.out.println("normalizedArch: " + normalizedArch+"\nnormalizedOs: " + normalizedOs);
|
||||
|
||||
SpringApplication.run(LazyCloudHeartbeatClientStart.class,args);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
package org.framework.lazy.cloud.network.heartbeat.client;
|
||||
|
||||
import io.micrometer.core.instrument.Tags;
|
||||
import io.micrometer.core.instrument.binder.system.FileDescriptorMetrics;
|
||||
import io.micrometer.core.instrument.binder.system.ProcessorMetrics;
|
||||
import io.micrometer.core.instrument.binder.system.UptimeMetrics;
|
||||
import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties;
|
||||
import org.springframework.boot.actuate.metrics.system.DiskSpaceMetricsBinder;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
@Configuration
|
||||
@Import({MetricsAutoConfiguration.class, CompositeMeterRegistryAutoConfiguration.class})
|
||||
public class MetricsConfig {
|
||||
|
||||
// fix cgroup2fs环境
|
||||
@Bean
|
||||
public UptimeMetrics uptimeMetrics() {
|
||||
try {
|
||||
return new UptimeMetrics();
|
||||
} catch (Exception e) {
|
||||
System.err.println("Failed to initialize UptimeMetrics: " + e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@Bean
|
||||
public ProcessorMetrics processorMetrics() {
|
||||
try {
|
||||
return new ProcessorMetrics();
|
||||
} catch (Exception e) {
|
||||
System.err.println("Failed to initialize ProcessorMetrics: " + e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@Bean
|
||||
public FileDescriptorMetrics fileDescriptorMetrics(){
|
||||
try {
|
||||
return new FileDescriptorMetrics();
|
||||
}catch (Exception e){
|
||||
System.err.println("Failed to initialize FileDescriptorMetrics: " + e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@Bean
|
||||
public DiskSpaceMetricsBinder diskSpaceMetrics(MetricsProperties properties) {
|
||||
try {
|
||||
List<File> paths = properties.getSystem().getDiskspace().getPaths();
|
||||
return new DiskSpaceMetricsBinder(paths, Tags.empty());
|
||||
}catch (Exception e){
|
||||
System.err.println("Failed to initialize DiskSpaceMetricsBinder: " + e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,18 +5,18 @@ spring:
|
||||
# inet-host: 124.222.48.62
|
||||
# inet-port: 30676
|
||||
# inet-host: 124.222.152.160
|
||||
inet-port: 30560
|
||||
# inet-port: 30560
|
||||
# inet-host: 192.168.15.121
|
||||
# inet-port: 7001
|
||||
# inet-host: 127.0.0.1
|
||||
# inet-port: 7001
|
||||
inet-host: 124.222.152.160
|
||||
# inet-port: 31560
|
||||
inet-path: wu-lazy-cloud-heartbeat-server
|
||||
client-id: socks-local-proxy # 客户端ID
|
||||
app-key: a4bf4415-25aa-4007-914b-31ec77d1292f
|
||||
app-secret: 88e6d827-12e7-4a5d-93e0-92c04c2414bc
|
||||
protocol-type: tcp
|
||||
# inet-host: 1.116.249.110
|
||||
# inet-port: 30560
|
||||
# inet-path: wu-lazy-cloud-heartbeat-server
|
||||
# client-id: socks-local-proxy # 客户端ID
|
||||
# app-key: a4bf4415-25aa-4007-914b-31ec77d1292f
|
||||
# app-secret: 88e6d827-12e7-4a5d-93e0-92c04c2414bc
|
||||
# protocol-type: tcp
|
||||
|
||||
# inet-host: 124.222.48.62 # 服务端地址
|
||||
# inet-port: 30676 #服务端端口
|
||||
@@ -24,25 +24,19 @@ spring:
|
||||
# client-id: shuhan # 客户端ID
|
||||
# client-id: temp_id # 客户端ID
|
||||
---
|
||||
spring:
|
||||
data:
|
||||
redis:
|
||||
host: 192.168.17.221
|
||||
port: 30553
|
||||
password: wujiawei
|
||||
database: 2
|
||||
|
||||
---
|
||||
#spring:
|
||||
# datasource:
|
||||
# url: jdbc:h2:~/client_heartbeat;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE;DATABASE_TO_UPPER=true;MODE=MySQL;CASE_INSENSITIVE_IDENTIFIERS=TRUE
|
||||
# username: sa
|
||||
# driver-class-name: org.h2.Driver
|
||||
|
||||
---
|
||||
spring:
|
||||
datasource:
|
||||
url: jdbc:mysql://127.0.0.1:3306/wu_lazy_cloud_heartbeat_client_start?allowMultiQueries=true&useUnicode=true&autoReconnect=true&useAffectedRows=true&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&databaseTerm=SCHEMA
|
||||
username: root
|
||||
password: wujiawei
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
url: jdbc:h2:~/client_heartbeat;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE;DATABASE_TO_UPPER=true;MODE=MySQL;CASE_INSENSITIVE_IDENTIFIERS=TRUE
|
||||
username: sa
|
||||
driver-class-name: org.h2.Driver
|
||||
|
||||
---
|
||||
#spring:
|
||||
# datasource:
|
||||
# url: jdbc:mysql://127.0.0.1:3306/wu_lazy_cloud_heartbeat_client_start?allowMultiQueries=true&useUnicode=true&autoReconnect=true&useAffectedRows=true&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&databaseTerm=SCHEMA
|
||||
# username: root
|
||||
# password: wujiawei
|
||||
# driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
|
||||
@@ -2,4 +2,7 @@ spring:
|
||||
datasource:
|
||||
url: jdbc:h2:~/client_heartbeat
|
||||
username: sa
|
||||
driver-class-name: org.h2.Driver
|
||||
driver-class-name: org.h2.Driver
|
||||
|
||||
---
|
||||
spring.dem
|
||||
@@ -34,3 +34,19 @@ spring:
|
||||
port: 9002
|
||||
http-protocol-proxy:
|
||||
port: 8002
|
||||
---
|
||||
#窗口配置
|
||||
|
||||
spring:
|
||||
lazy:
|
||||
javafx:
|
||||
target-url: http://127.0.0.1:6004/netty-client-local-ui/index.html
|
||||
window:
|
||||
title: wlcn客户端
|
||||
|
||||
---
|
||||
#虚拟线程
|
||||
spring:
|
||||
threads:
|
||||
virtual:
|
||||
enabled: true
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>top.wu2020</groupId>
|
||||
<artifactId>wu-lazy-cloud-heartbeat-start</artifactId>
|
||||
<version>1.3.4-JDK24-SNAPSHOT</version>
|
||||
<version>1.3.6-JDK24</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>top.wu2020</groupId>
|
||||
<artifactId>wu-lazy-cloud-heartbeat-start</artifactId>
|
||||
<version>1.3.4-JDK24-SNAPSHOT</version>
|
||||
<version>1.3.6-JDK24</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
@@ -54,30 +54,7 @@
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<!-- <plugin>-->
|
||||
<!-- <groupId>org.graalvm.buildtools</groupId>-->
|
||||
<!-- <artifactId>native-maven-plugin</artifactId>-->
|
||||
<!-- <version>0.10.3</version>-->
|
||||
<!-- <configuration>-->
|
||||
<!-- <!– imageName用于设置生成的二进制文件名称 –>-->
|
||||
<!-- <imageName>${project.artifactId}</imageName>-->
|
||||
<!-- <!– mainClass用于指定main方法类路径 –>-->
|
||||
<!-- <mainClass>org.framework.lazy.cloud.network.heartbeat.server.LazyCloudHeartbeatServerStart-->
|
||||
<!-- </mainClass>-->
|
||||
<!-- <buildArgs>-->
|
||||
<!-- --no-fallback-->
|
||||
<!-- </buildArgs>-->
|
||||
<!-- </configuration>-->
|
||||
<!-- <executions>-->
|
||||
<!-- <execution>-->
|
||||
<!-- <id>build-native</id>-->
|
||||
<!-- <goals>-->
|
||||
<!-- <goal>compile-no-fork</goal>-->
|
||||
<!-- </goals>-->
|
||||
<!-- <phase>package</phase>-->
|
||||
<!-- </execution>-->
|
||||
<!-- </executions>-->
|
||||
<!-- </plugin>-->
|
||||
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
@@ -89,6 +66,58 @@
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<!-- 2. 配置jpackage打包脚本(通过Maven执行外部命令) -->
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>3.5.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>jpackage</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>exec</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<!-- 显示Maven执行详情 -->
|
||||
<executable>jpackage</executable>
|
||||
<arguments>
|
||||
<!-- 增加jpackage详细日志参数 -->
|
||||
<argument>--verbose</argument>
|
||||
|
||||
<argument>--type</argument>
|
||||
<argument>${packaging.type}</argument>
|
||||
<argument>--input</argument>
|
||||
<argument>target</argument>
|
||||
|
||||
<argument>--dest</argument>
|
||||
<argument>target/installer</argument>
|
||||
|
||||
<argument>--name</argument>
|
||||
<argument>wlcn-server-${os.name}-${project.version}</argument>
|
||||
|
||||
<argument>--main-jar</argument>
|
||||
<argument>${project.build.finalName}.jar</argument>
|
||||
|
||||
<argument>--main-class</argument>
|
||||
<argument>org.springframework.boot.loader.launch.JarLauncher</argument>
|
||||
<argument>--app-version</argument>
|
||||
<argument>1.3.6</argument>
|
||||
|
||||
<argument>--vendor</argument>
|
||||
<argument>小吴小吴bug全无${os.name}</argument>
|
||||
|
||||
<argument>--description</argument>
|
||||
<argument>${description}</argument>
|
||||
|
||||
<argument>--java-options</argument>
|
||||
<argument>-server -XX:+TieredCompilation -XX:TieredStopAtLevel=1 -Xms64m -Xmx256m -XX:+UseParallelGC</argument>
|
||||
|
||||
</arguments>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -0,0 +1,19 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
||||
<!-- 背景圆形 -->
|
||||
<circle cx="50" cy="50" r="45" fill="#2563eb" />
|
||||
|
||||
<!-- 网络信号图标 -->
|
||||
<path d="M25,75 Q50,45 75,75 M35,75 Q50,55 65,75 M45,75 Q50,65 55,75" fill="none" stroke="white" stroke-width="5" stroke-linecap="round" />
|
||||
|
||||
<!-- 中央连接点 -->
|
||||
<circle cx="50" cy="75" r="5" fill="white" />
|
||||
|
||||
<!-- 计算机屏幕 -->
|
||||
<rect x="35" y="25" width="30" height="20" rx="2" fill="white" stroke="#1e40af" stroke-width="2" />
|
||||
<rect x="38" y="28" width="24" height="14" fill="#1e40af" />
|
||||
|
||||
<!-- 计算机底座 -->
|
||||
<rect x="43" y="45" width="14" height="3" fill="#1e40af" />
|
||||
<rect x="46" y="48" width="8" height="2" fill="#1e40af" />
|
||||
</svg>
|
||||
|
||||
|
After Width: | Height: | Size: 750 B |
@@ -1,11 +1,11 @@
|
||||
|
||||
---
|
||||
## h2 配置
|
||||
#spring:
|
||||
# datasource:
|
||||
# url: jdbc:h2:./wu_lazy_cloud_netty_server:wu_lazy_cloud_netty_server;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE;DATABASE_TO_UPPER=true;MODE=MySQL;CASE_INSENSITIVE_IDENTIFIERS=TRUE
|
||||
# username: sa
|
||||
# driver-class-name: org.h2.Driver
|
||||
spring:
|
||||
datasource:
|
||||
url: jdbc:h2:./wlcn:wlcn_server;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE;DATABASE_TO_UPPER=true;MODE=MySQL;CASE_INSENSITIVE_IDENTIFIERS=TRUE
|
||||
username: sa
|
||||
driver-class-name: org.h2.Driver
|
||||
---
|
||||
# h2 web
|
||||
spring:
|
||||
@@ -16,12 +16,12 @@ spring:
|
||||
settings:
|
||||
web-allow-others: true
|
||||
---
|
||||
spring:
|
||||
datasource:
|
||||
url: jdbc:mysql://127.0.0.1:3306/wu_lazy_cloud_netty_server?allowMultiQueries=true&useUnicode=true&autoReconnect=true&useAffectedRows=true&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&databaseTerm=SCHEMA
|
||||
username: root
|
||||
password: wujiawei
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
#spring:
|
||||
# datasource:
|
||||
# url: jdbc:mysql://127.0.0.1:3306/wu_lazy_cloud_netty_server?allowMultiQueries=true&useUnicode=true&autoReconnect=true&useAffectedRows=true&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&databaseTerm=SCHEMA
|
||||
# username: root
|
||||
# password: wujiawei
|
||||
# driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
|
||||
---
|
||||
#logging:
|
||||
|
||||
@@ -56,4 +56,33 @@ spring:
|
||||
- /druid/**
|
||||
- /.well-known/appspecific/com.chrome.devtools.json
|
||||
- /token/access_token
|
||||
- /sys/user/findUseZoneList
|
||||
- /sys/user/findUseZoneList
|
||||
|
||||
---
|
||||
#窗口配置
|
||||
spring:
|
||||
lazy:
|
||||
javafx:
|
||||
target-url: http://127.0.0.1:6001/wlcn/index.html
|
||||
window:
|
||||
title: wlcn服务端
|
||||
|
||||
---
|
||||
# 配置额外字段
|
||||
spring:
|
||||
lazy:
|
||||
ddl-configure:
|
||||
extra-fields:
|
||||
- name: zoneId
|
||||
columnName: zone_id
|
||||
columnType: varchar(255)
|
||||
comment: 区域ID
|
||||
exist: true
|
||||
|
||||
|
||||
---
|
||||
#虚拟线程
|
||||
spring:
|
||||
threads:
|
||||
virtual:
|
||||
enabled: true
|
||||
247
使用文档.md
Normal file
247
使用文档.md
Normal file
@@ -0,0 +1,247 @@
|
||||
# Wu-Lazy-Cloud-Network 使用文档
|
||||
|
||||
## 🚀 快速开始
|
||||
|
||||
### 1. 环境准备
|
||||
|
||||
- **Java**: JDK 13+ (推荐 JDK 24)
|
||||
- **内存**: 最小 512MB
|
||||
- **网络**: 服务端需要公网 IP
|
||||
|
||||
### 2. Docker 快速部署
|
||||
|
||||
#### 启动服务端
|
||||
```bash
|
||||
docker run -d -it -p 6001:6001 -p 7001:7001 -p 8001:8001 -p 9001:9001 \
|
||||
--name wlcn-server \
|
||||
registry.cn-hangzhou.aliyuncs.com/wu-lazy/wu-lazy-cloud-heartbeat-server:1.3.1-JDK24
|
||||
```
|
||||
|
||||
#### 启动客户端
|
||||
```bash
|
||||
docker run -d -it --privileged -p 6004:6004 \
|
||||
--name wlcn-client \
|
||||
--restart=always \
|
||||
-e spring.lazy.netty.client.inet-host=YOUR_SERVER_IP \
|
||||
-e spring.lazy.netty.client.inet-port=7001 \
|
||||
-e spring.lazy.netty.client.client-id="your-client-id" \
|
||||
registry.cn-hangzhou.aliyuncs.com/wu-lazy/wu-lazy-cloud-heartbeat-client-start:1.3.1-JDK24
|
||||
```
|
||||
|
||||
### 3. 访问管理界面
|
||||
|
||||
- **服务端管理**: http://127.0.0.1:6001/netty-server-ui/index.html
|
||||
- **客户端管理**: http://127.0.0.1:6004/netty-client-local-ui/index.html
|
||||
|
||||
**默认登录信息**:
|
||||
- 用户名: `admin`
|
||||
- 密码: `admin`
|
||||
|
||||
## 📋 功能使用
|
||||
|
||||
### 内网穿透
|
||||
|
||||
#### 服务端渗透客户端(内网穿透)
|
||||
|
||||
1. **配置端口池**
|
||||
- 进入服务端管理界面
|
||||
- 找到"服务端渗透端口池管理"
|
||||
- 添加需要开放的端口
|
||||
|
||||
2. **配置客户端映射**
|
||||
- 找到"服务端渗透客户端映射"
|
||||
- 设置访客端口 → 客户端真实端口
|
||||
- 例如: 19080 → 18080
|
||||
|
||||
3. **访问测试**
|
||||
- 通过 `http://服务端IP:19080` 访问客户端本地 18080 端口
|
||||
|
||||
#### 客户端渗透服务端
|
||||
|
||||
1. **配置客户端端口池**
|
||||
- 进入客户端管理界面
|
||||
- 找到"客户端渗透端口池管理"
|
||||
- 添加本地端口
|
||||
|
||||
2. **配置渗透映射**
|
||||
- 找到"客户端渗透服务端映射"
|
||||
- 设置本地端口 → 远程端口
|
||||
- 例如: 13306 → 3306
|
||||
|
||||
### 代理功能
|
||||
|
||||
#### HTTP 代理
|
||||
|
||||
**服务端代理**:
|
||||
- 地址: `127.0.0.1:8001`
|
||||
- 用途: 通过服务端访问网络
|
||||
|
||||
**客户端代理**:
|
||||
- 地址: `127.0.0.1:8002`
|
||||
- 用途: 通过客户端访问网络
|
||||
|
||||
#### SOCKS 代理
|
||||
|
||||
**服务端代理**:
|
||||
- 地址: `127.0.0.1:9001`
|
||||
- 协议: SOCKS5
|
||||
|
||||
**客户端代理**:
|
||||
- 地址: `127.0.0.1:9002`
|
||||
- 协议: SOCKS5
|
||||
|
||||
### 路由管理
|
||||
|
||||
#### 虚拟路由
|
||||
|
||||
1. **创建虚拟 IP**
|
||||
- 在路由管理界面创建虚拟 IP
|
||||
- 配置代理目标 IP 和端口
|
||||
|
||||
2. **使用虚拟路由**
|
||||
- 系统自动将虚拟 IP 流量代理到目标地址
|
||||
|
||||
## 🔧 常用配置
|
||||
|
||||
### 服务端配置
|
||||
|
||||
```yaml
|
||||
spring:
|
||||
lazy:
|
||||
netty:
|
||||
server:
|
||||
mode: standalone # standalone/cluster
|
||||
node-id: default
|
||||
node-host: 127.0.0.1
|
||||
node-port: 7001
|
||||
enable-flow-control: true
|
||||
enable-token-verification: false
|
||||
```
|
||||
|
||||
### 客户端配置
|
||||
|
||||
```yaml
|
||||
spring:
|
||||
lazy:
|
||||
netty:
|
||||
client:
|
||||
client-id: your-client-id
|
||||
inet-host: 127.0.0.1
|
||||
inet-port: 7001
|
||||
enable: true
|
||||
```
|
||||
|
||||
### 代理配置
|
||||
|
||||
```yaml
|
||||
spring:
|
||||
lazy:
|
||||
netty:
|
||||
protocol:
|
||||
proxy:
|
||||
authentication: true
|
||||
enable-proxy-log: false
|
||||
socket-protocol-proxy:
|
||||
port: 9001
|
||||
http-protocol-proxy:
|
||||
port: 8001
|
||||
```
|
||||
|
||||
## 📊 监控功能
|
||||
|
||||
### 流量监控
|
||||
|
||||
- **实时流量**: 查看每个客户端的实时流量
|
||||
- **流量统计**: 按日统计流量使用情况
|
||||
- **端口监控**: 监控各端口的使用情况
|
||||
|
||||
### 报表功能
|
||||
|
||||
- **日流量报表**: 查看每日流量统计
|
||||
- **客户端排行**: 按流量使用量排行
|
||||
- **端口分析**: 分析端口使用情况
|
||||
|
||||
## 🐛 常见问题
|
||||
|
||||
### 1. 客户端连接失败
|
||||
|
||||
**检查项**:
|
||||
- 服务端 IP 和端口是否正确
|
||||
- 网络连接是否正常
|
||||
- 防火墙是否阻止连接
|
||||
|
||||
**解决方案**:
|
||||
```bash
|
||||
# 检查网络连接
|
||||
ping YOUR_SERVER_IP
|
||||
|
||||
# 检查端口是否开放
|
||||
telnet YOUR_SERVER_IP 7001
|
||||
|
||||
# 查看客户端日志
|
||||
docker logs wlcn-client
|
||||
```
|
||||
|
||||
### 2. 内网穿透不工作
|
||||
|
||||
**检查项**:
|
||||
- 端口映射配置是否正确
|
||||
- 目标服务是否正在运行
|
||||
- 防火墙规则是否允许
|
||||
|
||||
**解决方案**:
|
||||
- 确认映射配置: 访客端口 → 客户端端口
|
||||
- 检查目标服务状态
|
||||
- 测试本地端口访问
|
||||
|
||||
### 3. 代理连接失败
|
||||
|
||||
**检查项**:
|
||||
- 代理地址和端口是否正确
|
||||
- 代理认证信息是否正确
|
||||
- 网络连接是否正常
|
||||
|
||||
**解决方案**:
|
||||
- 验证代理配置信息
|
||||
- 检查认证设置
|
||||
- 测试网络连接
|
||||
|
||||
## 🔒 安全建议
|
||||
|
||||
### 1. 认证配置
|
||||
|
||||
- 启用 Token 验证
|
||||
- 配置 AppKey/AppSecret
|
||||
- 设置代理认证
|
||||
|
||||
### 2. 网络安全
|
||||
|
||||
- 使用 HTTPS 访问管理界面
|
||||
- 配置防火墙规则
|
||||
- 定期更新密码
|
||||
|
||||
### 3. 数据安全
|
||||
|
||||
- 定期备份配置数据
|
||||
- 监控异常访问
|
||||
- 记录操作日志
|
||||
|
||||
## 📞 获取帮助
|
||||
|
||||
### 联系方式
|
||||
- **作者**: 吴佳伟
|
||||
- **邮箱**: 1207537021@qq.com
|
||||
- **项目地址**:
|
||||
- [Gitee](https://gitee.com/wujiawei1207537021/wu-lazy-cloud-network)
|
||||
- [GitHub](https://github.com/wujiawei1207537021/wu-lazy-cloud-network)
|
||||
|
||||
### 文档资源
|
||||
- [项目说明文档](项目说明文档.md)
|
||||
- [安装指南](install.md)
|
||||
- [代理使用指南](Proxy.md)
|
||||
- [版本更新记录](version.md)
|
||||
|
||||
---
|
||||
|
||||
**版本**: 1.3.1-JDK24
|
||||
**更新时间**: 2024年
|
||||
893
开发指南.md
Normal file
893
开发指南.md
Normal file
@@ -0,0 +1,893 @@
|
||||
# Wu-Lazy-Cloud-Network 开发指南
|
||||
|
||||
## 🛠️ 开发环境搭建
|
||||
|
||||
### 环境要求
|
||||
|
||||
#### 基础环境
|
||||
- **操作系统**: Windows 10+ / macOS 10.15+ / Linux (Ubuntu 18.04+)
|
||||
- **Java**: JDK 24 (推荐) 或 JDK 17+
|
||||
- **Maven**: 3.6+
|
||||
- **IDE**: IntelliJ IDEA 2023.1+ (推荐) 或 Eclipse 2023-03+
|
||||
- **Git**: 2.30+
|
||||
|
||||
#### 数据库环境
|
||||
- **MySQL**: 8.0+ (生产环境)
|
||||
- **H2**: 2.1+ (开发环境)
|
||||
|
||||
#### 可选工具
|
||||
- **Docker**: 20.10+ (容器化部署)
|
||||
- **Docker Compose**: 2.0+ (多容器编排)
|
||||
- **Postman**: API 测试工具
|
||||
|
||||
### 环境配置
|
||||
|
||||
#### 1. Java 环境配置
|
||||
|
||||
```bash
|
||||
# 下载并安装 JDK 24
|
||||
# 设置 JAVA_HOME 环境变量
|
||||
export JAVA_HOME=/path/to/jdk-24
|
||||
export PATH=$JAVA_HOME/bin:$PATH
|
||||
|
||||
# 验证安装
|
||||
java -version
|
||||
javac -version
|
||||
```
|
||||
|
||||
#### 2. Maven 环境配置
|
||||
|
||||
```bash
|
||||
# 下载并安装 Maven
|
||||
# 设置 MAVEN_HOME 环境变量
|
||||
export MAVEN_HOME=/path/to/maven
|
||||
export PATH=$MAVEN_HOME/bin:$PATH
|
||||
|
||||
# 验证安装
|
||||
mvn -version
|
||||
```
|
||||
|
||||
#### 3. IDE 配置
|
||||
|
||||
**IntelliJ IDEA 配置**:
|
||||
1. 安装 JDK 24
|
||||
2. 配置 Maven 设置
|
||||
3. 导入项目为 Maven 项目
|
||||
4. 配置代码风格和格式化规则
|
||||
|
||||
**Eclipse 配置**:
|
||||
1. 安装 Eclipse IDE for Enterprise Java Developers
|
||||
2. 配置 JDK 24
|
||||
3. 导入 Maven 项目
|
||||
4. 配置代码格式化规则
|
||||
|
||||
### 项目克隆
|
||||
|
||||
```bash
|
||||
# 克隆项目
|
||||
git clone https://gitee.com/wujiawei1207537021/wu-lazy-cloud-network.git
|
||||
cd wu-lazy-cloud-network
|
||||
|
||||
# 切换到开发分支
|
||||
git checkout develop
|
||||
```
|
||||
|
||||
## 📁 项目结构
|
||||
|
||||
### 目录结构
|
||||
|
||||
```
|
||||
wu-lazy-cloud-network/
|
||||
├── pom.xml # 父模块 POM
|
||||
├── README.md # 项目说明
|
||||
├── 项目说明文档.md # 详细项目说明
|
||||
├── 使用文档.md # 使用指南
|
||||
├── 架构说明.md # 架构文档
|
||||
├── 开发指南.md # 本文档
|
||||
├── install.md # 安装指南
|
||||
├── Proxy.md # 代理使用指南
|
||||
├── version.md # 版本更新记录
|
||||
├── LICENSE # 许可证
|
||||
├── .gitignore # Git 忽略文件
|
||||
├── wu-lazy-cloud-heartbeat-common/ # 公共模块
|
||||
│ ├── pom.xml
|
||||
│ └── src/main/java/org/framework/lazy/cloud/network/heartbeat/common/
|
||||
│ ├── adapter/ # 适配器
|
||||
│ ├── advanced/ # 高级功能
|
||||
│ ├── allocator/ # 分配器
|
||||
│ ├── constant/ # 常量定义
|
||||
│ ├── context/ # 上下文
|
||||
│ ├── decoder/ # 解码器
|
||||
│ ├── encoder/ # 编码器
|
||||
│ ├── enums/ # 枚举
|
||||
│ ├── factory/ # 工厂类
|
||||
│ ├── filter/ # 过滤器
|
||||
│ ├── pool/ # 连接池
|
||||
│ ├── socket/ # Socket 相关
|
||||
│ ├── state/ # 状态管理
|
||||
│ └── utils/ # 工具类
|
||||
├── wu-lazy-cloud-heartbeat-server/ # 服务端模块
|
||||
│ ├── pom.xml
|
||||
│ └── src/main/java/org/framework/lazy/cloud/network/heartbeat/server/
|
||||
│ ├── cluster/ # 集群功能
|
||||
│ ├── config/ # 配置类
|
||||
│ ├── context/ # 上下文
|
||||
│ ├── init/ # 初始化
|
||||
│ ├── netty/ # Netty 相关
|
||||
│ ├── properties/ # 属性配置
|
||||
│ ├── standalone/ # 单机模式
|
||||
│ └── ui/ # 用户界面
|
||||
├── wu-lazy-cloud-heartbeat-client/ # 客户端模块
|
||||
│ ├── pom.xml
|
||||
│ └── src/main/java/org/framework/lazy/cloud/network/heartbeat/client/
|
||||
│ ├── application/ # 应用层
|
||||
│ ├── config/ # 配置类
|
||||
│ ├── context/ # 上下文
|
||||
│ ├── controller/ # 控制器
|
||||
│ ├── domain/ # 领域层
|
||||
│ ├── infrastructure/ # 基础设施层
|
||||
│ ├── netty/ # Netty 相关
|
||||
│ ├── rpc/ # RPC 相关
|
||||
│ └── ui/ # 用户界面
|
||||
├── wu-lazy-cloud-heartbeat-dns/ # DNS 模块
|
||||
│ ├── pom.xml
|
||||
│ └── src/main/java/org/framework/lazy/cloud/network/heartbeat/protocol/
|
||||
├── wu-lazy-cloud-heartbeat-protocol-proxy/ # 代理协议模块
|
||||
│ ├── pom.xml
|
||||
│ └── src/main/java/org/framework/lazy/cloud/network/heartbeat/protocol/
|
||||
│ ├── actuator/ # 执行器
|
||||
│ ├── advanced/ # 高级功能
|
||||
│ ├── auth/ # 认证
|
||||
│ ├── config/ # 配置
|
||||
│ ├── context/ # 上下文
|
||||
│ ├── demo/ # 示例
|
||||
│ ├── filter/ # 过滤器
|
||||
│ ├── handler/ # 处理器
|
||||
│ ├── init/ # 初始化
|
||||
│ ├── log/ # 日志
|
||||
│ ├── properties/ # 属性
|
||||
│ ├── route/ # 路由
|
||||
│ ├── socket5/ # SOCKS5
|
||||
│ ├── token/ # Token
|
||||
│ └── utils/ # 工具类
|
||||
└── wu-lazy-cloud-heartbeat-start/ # 启动模块
|
||||
├── pom.xml
|
||||
├── wu-lazy-cloud-heartbeat-server-start/ # 服务端启动
|
||||
├── wu-lazy-cloud-heartbeat-client-start/ # 客户端启动
|
||||
└── wu-lazy-cloud-heartbeat-server-cluster-start/ # 集群启动
|
||||
```
|
||||
|
||||
### 核心包结构
|
||||
|
||||
#### 1. Common 模块 (wu-lazy-cloud-heartbeat-common)
|
||||
|
||||
**核心类**:
|
||||
- `NettyMsg`: 网络消息基类
|
||||
- `ChannelContext`: 通道上下文基类
|
||||
- `NettyTransferChannelContext`: 传输通道上下文
|
||||
- `NettyVisitorPortContext`: 访客端口上下文
|
||||
- `NettyRealIdContext`: 真实连接上下文
|
||||
|
||||
**适配器**:
|
||||
- `NettyAdapter`: 网络适配器接口
|
||||
- `ProtocolAdapter`: 协议适配器接口
|
||||
|
||||
**工具类**:
|
||||
- `NettyUtils`: Netty 工具类
|
||||
- `ChannelUtils`: 通道工具类
|
||||
- `ProtocolUtils`: 协议工具类
|
||||
|
||||
#### 2. Server 模块 (wu-lazy-cloud-heartbeat-server)
|
||||
|
||||
**核心类**:
|
||||
- `NettyTcpServerSocketApplicationListener`: TCP 服务监听器
|
||||
- `LazyServerPermeateServerMappingApplication`: 服务端渗透应用
|
||||
- `NettyServerVirtualRouteApplication`: 虚拟路由应用
|
||||
|
||||
**配置类**:
|
||||
- `ServerAutoConfiguration`: 服务端自动配置
|
||||
- `ServerFlowConfiguration`: 流量控制配置
|
||||
|
||||
**初始化类**:
|
||||
- `InitServerSocket`: 服务端 Socket 初始化
|
||||
- `InitServerPermeateSocket`: 渗透 Socket 初始化
|
||||
- `InitServerProxySocket`: 代理 Socket 初始化
|
||||
|
||||
#### 3. Client 模块 (wu-lazy-cloud-heartbeat-client)
|
||||
|
||||
**核心类**:
|
||||
- `NettyClientSocketApplicationListener`: 客户端连接监听器
|
||||
- `LazyClientPermeateClientMappingApplication`: 客户端渗透应用
|
||||
- `NettyClientVirtualRouteApplication`: 客户端虚拟路由
|
||||
|
||||
**应用层**:
|
||||
- `LazyNettyClientApplication`: 客户端应用服务
|
||||
- `LazyNettyClientPermeateApplication`: 客户端渗透服务
|
||||
|
||||
**领域层**:
|
||||
- `LazyNettyClient`: 客户端实体
|
||||
- `LazyNettyClientPermeateMapping`: 客户端渗透映射
|
||||
|
||||
#### 4. Protocol Proxy 模块 (wu-lazy-cloud-heartbeat-protocol-proxy)
|
||||
|
||||
**核心类**:
|
||||
- `NettyHttpProxySocketApplicationListener`: HTTP 代理监听器
|
||||
- `NettySocketProxySocketApplicationListener`: SOCKS 代理监听器
|
||||
- `NettyTcpProxyFilter`: TCP 代理过滤器
|
||||
|
||||
**协议处理**:
|
||||
- `HttpProxyHandler`: HTTP 代理处理器
|
||||
- `SocksProxyHandler`: SOCKS 代理处理器
|
||||
- `ProxyAuthenticationHandler`: 代理认证处理器
|
||||
|
||||
## 🔧 开发规范
|
||||
|
||||
### 代码规范
|
||||
|
||||
#### 1. 命名规范
|
||||
|
||||
**类命名**:
|
||||
- 使用 PascalCase
|
||||
- 类名应该清晰表达其功能
|
||||
- 接口以 `I` 开头,抽象类以 `Abstract` 开头
|
||||
|
||||
```java
|
||||
// 正确示例
|
||||
public class NettyTcpServerSocketApplicationListener
|
||||
public interface INettyAdapter
|
||||
public abstract class AbstractNettyHandler
|
||||
|
||||
// 错误示例
|
||||
public class nettyServer
|
||||
public class NettyServer
|
||||
```
|
||||
|
||||
**方法命名**:
|
||||
- 使用 camelCase
|
||||
- 方法名应该清晰表达其功能
|
||||
- 布尔方法以 `is`、`has`、`can` 开头
|
||||
|
||||
```java
|
||||
// 正确示例
|
||||
public void startServer()
|
||||
public boolean isConnected()
|
||||
public boolean hasPermission()
|
||||
|
||||
// 错误示例
|
||||
public void start_server()
|
||||
public boolean connected()
|
||||
```
|
||||
|
||||
**变量命名**:
|
||||
- 使用 camelCase
|
||||
- 常量使用 UPPER_SNAKE_CASE
|
||||
- 避免使用单字母变量名
|
||||
|
||||
```java
|
||||
// 正确示例
|
||||
private String serverHost;
|
||||
private static final String DEFAULT_PORT = "8080";
|
||||
|
||||
// 错误示例
|
||||
private String host;
|
||||
private static final String port = "8080";
|
||||
```
|
||||
|
||||
#### 2. 代码结构
|
||||
|
||||
**包结构**:
|
||||
```
|
||||
org.framework.lazy.cloud.network.heartbeat.{module}
|
||||
├── application/ # 应用层
|
||||
├── domain/ # 领域层
|
||||
├── infrastructure/ # 基础设施层
|
||||
├── config/ # 配置类
|
||||
├── context/ # 上下文
|
||||
├── handler/ # 处理器
|
||||
├── filter/ # 过滤器
|
||||
└── utils/ # 工具类
|
||||
```
|
||||
|
||||
**类结构**:
|
||||
```java
|
||||
// 1. 包声明
|
||||
package org.framework.lazy.cloud.network.heartbeat.server;
|
||||
|
||||
// 2. 导入语句
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
// 3. 类注释
|
||||
/**
|
||||
* 服务端 TCP Socket 应用监听器
|
||||
*
|
||||
* @author 吴佳伟
|
||||
* @date 2024-01-01
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class NettyTcpServerSocketApplicationListener {
|
||||
|
||||
// 4. 常量定义
|
||||
private static final int DEFAULT_PORT = 7001;
|
||||
|
||||
// 5. 成员变量
|
||||
private final EventLoopGroup bossGroup;
|
||||
private final EventLoopGroup workerGroup;
|
||||
|
||||
// 6. 构造函数
|
||||
public NettyTcpServerSocketApplicationListener() {
|
||||
this.bossGroup = new NioEventLoopGroup();
|
||||
this.workerGroup = new NioEventLoopGroup();
|
||||
}
|
||||
|
||||
// 7. 公共方法
|
||||
public void start() {
|
||||
// 实现逻辑
|
||||
}
|
||||
|
||||
// 8. 私有方法
|
||||
private void initChannel() {
|
||||
// 实现逻辑
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. 注释规范
|
||||
|
||||
**类注释**:
|
||||
```java
|
||||
/**
|
||||
* 服务端 TCP Socket 应用监听器
|
||||
*
|
||||
* 负责启动和管理服务端 TCP Socket 连接,处理客户端连接请求,
|
||||
* 并提供内网穿透和代理功能。
|
||||
*
|
||||
* @author 吴佳伟
|
||||
* @date 2024-01-01
|
||||
* @version 1.3.1
|
||||
*/
|
||||
```
|
||||
|
||||
**方法注释**:
|
||||
```java
|
||||
/**
|
||||
* 启动 TCP 服务器
|
||||
*
|
||||
* 初始化 Netty 服务器,绑定指定端口,开始监听客户端连接。
|
||||
* 如果启动失败,会抛出 RuntimeException。
|
||||
*
|
||||
* @param port 监听端口
|
||||
* @throws RuntimeException 启动失败时抛出
|
||||
*/
|
||||
public void startTcpServer(int port) {
|
||||
// 实现逻辑
|
||||
}
|
||||
```
|
||||
|
||||
**变量注释**:
|
||||
```java
|
||||
/** 服务端端口 */
|
||||
private int serverPort;
|
||||
|
||||
/** 客户端连接池 */
|
||||
private final ConnectionPool connectionPool;
|
||||
```
|
||||
|
||||
### 设计模式
|
||||
|
||||
#### 1. 工厂模式
|
||||
|
||||
```java
|
||||
/**
|
||||
* Netty 处理器工厂
|
||||
*/
|
||||
@Component
|
||||
public class NettyHandlerFactory {
|
||||
|
||||
/**
|
||||
* 创建 HTTP 代理处理器
|
||||
*/
|
||||
public NettyHttpProxyHandler createHttpProxyHandler() {
|
||||
return new NettyHttpProxyHandler();
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建 SOCKS 代理处理器
|
||||
*/
|
||||
public NettySocksProxyHandler createSocksProxyHandler() {
|
||||
return new NettySocksProxyHandler();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 2. 策略模式
|
||||
|
||||
```java
|
||||
/**
|
||||
* 协议处理策略接口
|
||||
*/
|
||||
public interface ProtocolStrategy {
|
||||
void handle(Channel channel, Object message);
|
||||
}
|
||||
|
||||
/**
|
||||
* HTTP 协议处理策略
|
||||
*/
|
||||
@Component
|
||||
public class HttpProtocolStrategy implements ProtocolStrategy {
|
||||
@Override
|
||||
public void handle(Channel channel, Object message) {
|
||||
// HTTP 协议处理逻辑
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* SOCKS 协议处理策略
|
||||
*/
|
||||
@Component
|
||||
public class SocksProtocolStrategy implements ProtocolStrategy {
|
||||
@Override
|
||||
public void handle(Channel channel, Object message) {
|
||||
// SOCKS 协议处理逻辑
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. 观察者模式
|
||||
|
||||
```java
|
||||
/**
|
||||
* 连接事件监听器
|
||||
*/
|
||||
public interface ConnectionEventListener {
|
||||
void onConnect(Channel channel);
|
||||
void onDisconnect(Channel channel);
|
||||
void onError(Channel channel, Throwable cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* 连接事件管理器
|
||||
*/
|
||||
@Component
|
||||
public class ConnectionEventManager {
|
||||
private final List<ConnectionEventListener> listeners = new ArrayList<>();
|
||||
|
||||
public void addListener(ConnectionEventListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
public void notifyConnect(Channel channel) {
|
||||
listeners.forEach(listener -> listener.onConnect(channel));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 异常处理
|
||||
|
||||
#### 1. 自定义异常
|
||||
|
||||
```java
|
||||
/**
|
||||
* 网络连接异常
|
||||
*/
|
||||
public class NetworkConnectionException extends RuntimeException {
|
||||
|
||||
public NetworkConnectionException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public NetworkConnectionException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 协议解析异常
|
||||
*/
|
||||
public class ProtocolParseException extends RuntimeException {
|
||||
|
||||
public ProtocolParseException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public ProtocolParseException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 2. 异常处理规范
|
||||
|
||||
```java
|
||||
/**
|
||||
* 网络连接管理器
|
||||
*/
|
||||
@Component
|
||||
public class NetworkConnectionManager {
|
||||
|
||||
/**
|
||||
* 建立连接
|
||||
*/
|
||||
public Channel connect(String host, int port) {
|
||||
try {
|
||||
// 连接逻辑
|
||||
return establishConnection(host, port);
|
||||
} catch (ConnectException e) {
|
||||
log.error("连接失败: {}:{}", host, port, e);
|
||||
throw new NetworkConnectionException("无法连接到服务器: " + host + ":" + port, e);
|
||||
} catch (Exception e) {
|
||||
log.error("连接过程中发生未知错误: {}:{}", host, port, e);
|
||||
throw new NetworkConnectionException("连接过程中发生未知错误", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全关闭连接
|
||||
*/
|
||||
public void safeClose(Channel channel) {
|
||||
if (channel != null && channel.isActive()) {
|
||||
try {
|
||||
channel.close().sync();
|
||||
} catch (Exception e) {
|
||||
log.warn("关闭连接时发生错误", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🧪 测试规范
|
||||
|
||||
### 单元测试
|
||||
|
||||
#### 1. 测试框架
|
||||
|
||||
```xml
|
||||
<!-- 测试依赖 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-junit-jupiter</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
#### 2. 测试类结构
|
||||
|
||||
```java
|
||||
/**
|
||||
* Netty 客户端连接测试
|
||||
*/
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class NettyClientConnectionTest {
|
||||
|
||||
@Mock
|
||||
private NettyClientProperties properties;
|
||||
|
||||
@Mock
|
||||
private LazyLambdaStream lazyLambdaStream;
|
||||
|
||||
@InjectMocks
|
||||
private NettyClientSocketApplicationListener listener;
|
||||
|
||||
@Test
|
||||
@DisplayName("客户端连接成功")
|
||||
void testClientConnectionSuccess() {
|
||||
// Given
|
||||
when(properties.getInetHost()).thenReturn("127.0.0.1");
|
||||
when(properties.getInetPort()).thenReturn(7001);
|
||||
|
||||
// When
|
||||
listener.doRunning();
|
||||
|
||||
// Then
|
||||
verify(lazyLambdaStream, times(1)).findList(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("客户端连接失败")
|
||||
void testClientConnectionFailure() {
|
||||
// Given
|
||||
when(properties.getInetHost()).thenReturn("invalid-host");
|
||||
|
||||
// When & Then
|
||||
assertThrows(NetworkConnectionException.class, () -> {
|
||||
listener.doRunning();
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. 集成测试
|
||||
|
||||
```java
|
||||
/**
|
||||
* 服务端集成测试
|
||||
*/
|
||||
@SpringBootTest
|
||||
@TestPropertySource(properties = {
|
||||
"spring.lazy.netty.server.mode=standalone",
|
||||
"spring.lazy.netty.server.node-port=7001"
|
||||
})
|
||||
class ServerIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private NettyTcpServerSocketApplicationListener serverListener;
|
||||
|
||||
@Test
|
||||
@DisplayName("服务端启动成功")
|
||||
void testServerStartup() {
|
||||
// Given & When
|
||||
serverListener.doRunning();
|
||||
|
||||
// Then
|
||||
assertTrue(serverListener.isRunning());
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 性能测试
|
||||
|
||||
#### 1. JMH 基准测试
|
||||
|
||||
```java
|
||||
/**
|
||||
* 网络传输性能测试
|
||||
*/
|
||||
@BenchmarkMode(Mode.Throughput)
|
||||
@OutputTimeUnit(TimeUnit.SECONDS)
|
||||
@State(Scope.Benchmark)
|
||||
public class NetworkTransferBenchmark {
|
||||
|
||||
private NettyTransferChannelContext transferContext;
|
||||
|
||||
@Setup
|
||||
public void setup() {
|
||||
transferContext = new NettyTransferChannelContext();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void testDataTransfer() {
|
||||
// 数据传输测试逻辑
|
||||
transferContext.transfer(createTestData());
|
||||
}
|
||||
|
||||
private byte[] createTestData() {
|
||||
return "test data".getBytes();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 📦 构建和部署
|
||||
|
||||
### Maven 构建
|
||||
|
||||
#### 1. 编译项目
|
||||
|
||||
```bash
|
||||
# 清理并编译
|
||||
mvn clean compile
|
||||
|
||||
# 运行测试
|
||||
mvn test
|
||||
|
||||
# 打包
|
||||
mvn package -DskipTests
|
||||
|
||||
# 安装到本地仓库
|
||||
mvn install
|
||||
```
|
||||
|
||||
#### 2. 多模块构建
|
||||
|
||||
```bash
|
||||
# 构建所有模块
|
||||
mvn clean install -DskipTests
|
||||
|
||||
# 构建特定模块
|
||||
mvn clean install -pl wu-lazy-cloud-heartbeat-server -am
|
||||
|
||||
# 跳过测试构建
|
||||
mvn clean package -DskipTests
|
||||
```
|
||||
|
||||
### Docker 构建
|
||||
|
||||
#### 1. 服务端 Dockerfile
|
||||
|
||||
```dockerfile
|
||||
FROM registry.cn-hangzhou.aliyuncs.com/wu-lazy/wu-framework-parent:jdk-24-x64
|
||||
MAINTAINER wujiawei <1207537021@qq.com>
|
||||
|
||||
RUN echo "Asia/Shanghai" > /etc/timezone
|
||||
|
||||
ENV APP_JAR_NAME=$APP_NAME \
|
||||
JAVA_OPTS="-Xms512m -Xmx1024m -XX:+UseContainerSupport -XX:InitialRAMPercentage=50.0 -XX:MaxRAMPercentage=80.0 -Djdk.management.jfr.VmFlagRepository.useCgroups=false -Djava.security.egd=file:/dev/./urandom" \
|
||||
PARAMS=""
|
||||
|
||||
COPY target/*.jar /app.jar
|
||||
|
||||
ENTRYPOINT exec java -server $JAVA_OPTS -jar /app.jar $PARAMS
|
||||
```
|
||||
|
||||
#### 2. 客户端 Dockerfile
|
||||
|
||||
```dockerfile
|
||||
FROM registry.cn-hangzhou.aliyuncs.com/wu-lazy/wu-framework-parent:jdk-24-x64
|
||||
MAINTAINER wujiawei <1207537021@qq.com>
|
||||
|
||||
RUN echo "Asia/Shanghai" > /etc/timezone
|
||||
|
||||
ENV APP_JAR_NAME=$APP_NAME \
|
||||
JAVA_OPTS="-Xms512m -Xmx1024m -XX:+UseContainerSupport -XX:InitialRAMPercentage=50.0 -XX:MaxRAMPercentage=80.0 -Djdk.management.jfr.VmFlagRepository.useCgroups=false -Djava.security.egd=file:/dev/./urandom" \
|
||||
PARAMS=""
|
||||
|
||||
COPY target/*.jar /app.jar
|
||||
|
||||
ENTRYPOINT exec java -server $JAVA_OPTS -jar /app.jar $PARAMS
|
||||
```
|
||||
|
||||
### 部署脚本
|
||||
|
||||
#### 1. 开发环境部署
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# deploy-dev.sh
|
||||
|
||||
echo "开始部署开发环境..."
|
||||
|
||||
# 编译项目
|
||||
mvn clean package -DskipTests
|
||||
|
||||
# 启动服务端
|
||||
cd wu-lazy-cloud-heartbeat-start/wu-lazy-cloud-heartbeat-server-start
|
||||
nohup java -jar target/wu-lazy-cloud-heartbeat-server-start-1.3.1-JDK24.jar > server.log 2>&1 &
|
||||
|
||||
# 启动客户端
|
||||
cd ../wu-lazy-cloud-heartbeat-client-start
|
||||
nohup java -jar target/wu-lazy-cloud-heartbeat-client-start-1.3.1-JDK24.jar > client.log 2>&1 &
|
||||
|
||||
echo "部署完成!"
|
||||
```
|
||||
|
||||
#### 2. 生产环境部署
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# deploy-prod.sh
|
||||
|
||||
echo "开始部署生产环境..."
|
||||
|
||||
# 构建 Docker 镜像
|
||||
docker build -t wlcn-server:latest wu-lazy-cloud-heartbeat-start/wu-lazy-cloud-heartbeat-server-start/
|
||||
docker build -t wlcn-client:latest wu-lazy-cloud-heartbeat-start/wu-lazy-cloud-heartbeat-client-start/
|
||||
|
||||
# 停止旧容器
|
||||
docker stop wlcn-server wlcn-client || true
|
||||
docker rm wlcn-server wlcn-client || true
|
||||
|
||||
# 启动新容器
|
||||
docker run -d --name wlcn-server -p 6001:6001 -p 7001:7001 -p 8001:8001 -p 9001:9001 wlcn-server:latest
|
||||
docker run -d --name wlcn-client --privileged -p 6004:6004 wlcn-client:latest
|
||||
|
||||
echo "部署完成!"
|
||||
```
|
||||
|
||||
## 🔍 调试技巧
|
||||
|
||||
### 日志配置
|
||||
|
||||
#### 1. 开发环境日志
|
||||
|
||||
```yaml
|
||||
# application-dev.yml
|
||||
logging:
|
||||
level:
|
||||
org.framework.lazy.cloud.network.heartbeat: DEBUG
|
||||
io.netty: DEBUG
|
||||
root: INFO
|
||||
pattern:
|
||||
console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"
|
||||
file: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"
|
||||
file:
|
||||
name: logs/wlcn-dev.log
|
||||
```
|
||||
|
||||
#### 2. 生产环境日志
|
||||
|
||||
```yaml
|
||||
# application-prod.yml
|
||||
logging:
|
||||
level:
|
||||
org.framework.lazy.cloud.network.heartbeat: INFO
|
||||
io.netty: WARN
|
||||
root: WARN
|
||||
pattern:
|
||||
console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"
|
||||
file: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"
|
||||
file:
|
||||
name: logs/wlcn-prod.log
|
||||
max-size: 100MB
|
||||
max-history: 30
|
||||
```
|
||||
|
||||
### 远程调试
|
||||
|
||||
#### 1. JVM 调试参数
|
||||
|
||||
```bash
|
||||
# 服务端调试
|
||||
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 \
|
||||
-jar wu-lazy-cloud-heartbeat-server-start-1.3.1-JDK24.jar
|
||||
|
||||
# 客户端调试
|
||||
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5006 \
|
||||
-jar wu-lazy-cloud-heartbeat-client-start-1.3.1-JDK24.jar
|
||||
```
|
||||
|
||||
#### 2. Docker 调试
|
||||
|
||||
```bash
|
||||
# 启动带调试端口的容器
|
||||
docker run -d -p 6001:6001 -p 7001:7001 -p 5005:5005 \
|
||||
-e JAVA_OPTS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005" \
|
||||
--name wlcn-server-debug wlcn-server:latest
|
||||
```
|
||||
|
||||
### 性能分析
|
||||
|
||||
#### 1. JProfiler 集成
|
||||
|
||||
```xml
|
||||
<!-- 添加 JProfiler 依赖 -->
|
||||
<dependency>
|
||||
<groupId>com.jprofiler</groupId>
|
||||
<artifactId>jprofiler</artifactId>
|
||||
<version>13.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
#### 2. 内存分析
|
||||
|
||||
```bash
|
||||
# 生成堆转储
|
||||
jmap -dump:format=b,file=heap.hprof <pid>
|
||||
|
||||
# 分析堆转储
|
||||
jhat heap.hprof
|
||||
```
|
||||
|
||||
## 📚 学习资源
|
||||
|
||||
### 官方文档
|
||||
- [Spring Boot 官方文档](https://spring.io/projects/spring-boot)
|
||||
- [Netty 官方文档](https://netty.io/)
|
||||
- [Lazy ORM 文档](https://gitee.com/wujiawei1207537021/wu-framework-parent)
|
||||
|
||||
### 推荐书籍
|
||||
- 《Spring Boot 实战》
|
||||
- 《Netty 实战》
|
||||
- 《Java 并发编程实战》
|
||||
|
||||
### 在线资源
|
||||
- [Spring Boot 教程](https://spring.io/guides)
|
||||
- [Netty 教程](https://netty.io/wiki/)
|
||||
- [Java 并发编程](https://docs.oracle.com/javase/tutorial/essential/concurrency/)
|
||||
|
||||
---
|
||||
|
||||
**版本**: 1.3.1-JDK24
|
||||
**更新时间**: 2024年
|
||||
**维护者**: 吴佳伟
|
||||
414
架构说明.md
Normal file
414
架构说明.md
Normal file
@@ -0,0 +1,414 @@
|
||||
# Wu-Lazy-Cloud-Network 架构说明
|
||||
|
||||
## 🏗️ 整体架构
|
||||
|
||||
### 系统架构图
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Wu-Lazy-Cloud-Network │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ 客户端 (Client) 服务端 (Server) │
|
||||
│ ┌─────────────────┐ ┌─────────────────┐ │
|
||||
│ │ Web UI │ │ Web UI │ │
|
||||
│ │ (6004) │ │ (6001) │ │
|
||||
│ └─────────────────┘ └─────────────────┘ │
|
||||
│ ┌─────────────────┐ ┌─────────────────┐ │
|
||||
│ │ Netty Client │◄────────────►│ Netty Server │ │
|
||||
│ │ (7001) │ │ (7001) │ │
|
||||
│ └─────────────────┘ └─────────────────┘ │
|
||||
│ ┌─────────────────┐ ┌─────────────────┐ │
|
||||
│ │ HTTP Proxy │ │ HTTP Proxy │ │
|
||||
│ │ (8002) │ │ (8001) │ │
|
||||
│ └─────────────────┘ └─────────────────┘ │
|
||||
│ ┌─────────────────┐ ┌─────────────────┐ │
|
||||
│ │ SOCKS Proxy │ │ SOCKS Proxy │ │
|
||||
│ │ (9002) │ │ (9001) │ │
|
||||
│ └─────────────────┘ └─────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 核心组件
|
||||
|
||||
#### 1. 通信层 (Communication Layer)
|
||||
- **Netty Framework**: 基于 Netty 的高性能网络通信
|
||||
- **TCP/UDP 支持**: 支持多种传输协议
|
||||
- **心跳机制**: 保持客户端与服务端的连接
|
||||
|
||||
#### 2. 协议层 (Protocol Layer)
|
||||
- **HTTP 代理**: 支持 HTTP/HTTPS 代理
|
||||
- **SOCKS 代理**: 支持 SOCKS4/SOCKS5 代理
|
||||
- **自定义协议**: 支持扩展自定义协议
|
||||
|
||||
#### 3. 业务层 (Business Layer)
|
||||
- **内网穿透**: 网络端口映射功能
|
||||
- **流量监控**: 实时流量统计和分析
|
||||
- **路由管理**: 虚拟路由和流量转发
|
||||
|
||||
#### 4. 数据层 (Data Layer)
|
||||
- **MySQL**: 主数据库,存储配置和监控数据
|
||||
- **H2**: 开发环境数据库
|
||||
- **Lazy ORM**: 数据库操作框架
|
||||
|
||||
## 📦 模块架构
|
||||
|
||||
### 模块依赖关系
|
||||
|
||||
```
|
||||
wu-lazy-cloud-network (父模块)
|
||||
├── wu-lazy-cloud-heartbeat-common (公共模块)
|
||||
│ ├── 接口定义
|
||||
│ ├── 枚举常量
|
||||
│ ├── 适配器
|
||||
│ └── 工具类
|
||||
├── wu-lazy-cloud-heartbeat-server (服务端核心)
|
||||
│ ├── 服务端业务逻辑
|
||||
│ ├── 网络处理
|
||||
│ └── 管理界面
|
||||
├── wu-lazy-cloud-heartbeat-client (客户端核心)
|
||||
│ ├── 客户端业务逻辑
|
||||
│ ├── 连接管理
|
||||
│ └── 本地界面
|
||||
├── wu-lazy-cloud-heartbeat-dns (DNS模块)
|
||||
│ └── DNS解析功能
|
||||
├── wu-lazy-cloud-heartbeat-protocol-proxy (代理协议)
|
||||
│ ├── HTTP代理
|
||||
│ └── SOCKS代理
|
||||
└── wu-lazy-cloud-heartbeat-start (启动模块)
|
||||
├── wu-lazy-cloud-heartbeat-server-start
|
||||
├── wu-lazy-cloud-heartbeat-client-start
|
||||
└── wu-lazy-cloud-heartbeat-server-cluster-start
|
||||
```
|
||||
|
||||
### 模块功能说明
|
||||
|
||||
#### 1. wu-lazy-cloud-heartbeat-common
|
||||
**功能**: 公共基础模块
|
||||
- **接口定义**: 定义系统核心接口
|
||||
- **枚举常量**: 系统常量定义
|
||||
- **适配器**: 协议适配器
|
||||
- **工具类**: 通用工具方法
|
||||
|
||||
**核心类**:
|
||||
- `NettyMsg`: 网络消息基类
|
||||
- `ChannelContext`: 通道上下文
|
||||
- `NettyTransferChannelContext`: 传输通道上下文
|
||||
|
||||
#### 2. wu-lazy-cloud-heartbeat-server
|
||||
**功能**: 服务端核心模块
|
||||
- **网络服务**: 提供 TCP/UDP 服务
|
||||
- **客户端管理**: 管理连接的客户端
|
||||
- **端口映射**: 处理端口映射逻辑
|
||||
- **流量监控**: 监控网络流量
|
||||
|
||||
**核心类**:
|
||||
- `NettyTcpServerSocketApplicationListener`: TCP服务监听器
|
||||
- `LazyServerPermeateServerMappingApplication`: 服务端渗透应用
|
||||
- `NettyServerVirtualRouteApplication`: 虚拟路由应用
|
||||
|
||||
#### 3. wu-lazy-cloud-heartbeat-client
|
||||
**功能**: 客户端核心模块
|
||||
- **连接管理**: 管理与服务端的连接
|
||||
- **本地服务**: 提供本地服务接口
|
||||
- **端口转发**: 处理端口转发逻辑
|
||||
|
||||
**核心类**:
|
||||
- `NettyClientSocketApplicationListener`: 客户端连接监听器
|
||||
- `LazyClientPermeateClientMappingApplication`: 客户端渗透应用
|
||||
- `NettyClientVirtualRouteApplication`: 客户端虚拟路由
|
||||
|
||||
#### 4. wu-lazy-cloud-heartbeat-protocol-proxy
|
||||
**功能**: 代理协议模块
|
||||
- **HTTP代理**: HTTP/HTTPS 代理服务
|
||||
- **SOCKS代理**: SOCKS4/SOCKS5 代理服务
|
||||
- **协议处理**: 处理各种代理协议
|
||||
|
||||
**核心类**:
|
||||
- `NettyHttpProxySocketApplicationListener`: HTTP代理监听器
|
||||
- `NettySocketProxySocketApplicationListener`: SOCKS代理监听器
|
||||
- `NettyTcpProxyFilter`: TCP代理过滤器
|
||||
|
||||
## 🔄 数据流架构
|
||||
|
||||
### 内网穿透数据流
|
||||
|
||||
```
|
||||
访客请求 → 服务端 → 心跳通道 → 客户端 → 本地服务
|
||||
↑ ↓
|
||||
访客响应 ← 服务端 ← 心跳通道 ← 客户端 ← 本地服务
|
||||
```
|
||||
|
||||
#### 详细流程
|
||||
|
||||
1. **访客连接**
|
||||
- 访客连接到服务端的访客端口
|
||||
- 服务端创建访客通道
|
||||
|
||||
2. **数据转发**
|
||||
- 服务端通过心跳通道将数据发送给客户端
|
||||
- 客户端接收数据并转发给本地服务
|
||||
|
||||
3. **响应返回**
|
||||
- 本地服务响应数据
|
||||
- 客户端通过心跳通道返回给服务端
|
||||
- 服务端通过访客通道返回给访客
|
||||
|
||||
### 代理数据流
|
||||
|
||||
```
|
||||
客户端应用 → 代理客户端 → 心跳通道 → 代理服务端 → 目标服务器
|
||||
↑ ↓
|
||||
客户端应用 ← 代理客户端 ← 心跳通道 ← 代理服务端 ← 目标服务器
|
||||
```
|
||||
|
||||
#### 代理类型
|
||||
|
||||
1. **HTTP代理**
|
||||
- 支持 HTTP/HTTPS 协议
|
||||
- 可配置认证机制
|
||||
- 支持流量监控
|
||||
|
||||
2. **SOCKS代理**
|
||||
- 支持 SOCKS4/SOCKS5 协议
|
||||
- 支持 TCP/UDP 代理
|
||||
- 支持多种认证方式
|
||||
|
||||
## 🗄️ 数据库架构
|
||||
|
||||
### 数据库设计
|
||||
|
||||
#### 核心表结构
|
||||
|
||||
1. **客户端管理表**
|
||||
```sql
|
||||
-- 客户端信息表
|
||||
CREATE TABLE lazy_netty_client (
|
||||
id BIGINT PRIMARY KEY,
|
||||
client_id VARCHAR(100),
|
||||
client_name VARCHAR(200),
|
||||
client_ip VARCHAR(50),
|
||||
client_port INT,
|
||||
is_deleted TINYINT,
|
||||
create_time DATETIME,
|
||||
update_time DATETIME
|
||||
);
|
||||
```
|
||||
|
||||
2. **端口映射表**
|
||||
```sql
|
||||
-- 服务端渗透客户端映射表
|
||||
CREATE TABLE lazy_server_permeate_client_mapping (
|
||||
id BIGINT PRIMARY KEY,
|
||||
client_id VARCHAR(100),
|
||||
visitor_port INT,
|
||||
real_host VARCHAR(100),
|
||||
real_port INT,
|
||||
is_deleted TINYINT,
|
||||
create_time DATETIME,
|
||||
update_time DATETIME
|
||||
);
|
||||
```
|
||||
|
||||
3. **流量统计表**
|
||||
```sql
|
||||
-- 流量统计表
|
||||
CREATE TABLE lazy_netty_flow_statistics (
|
||||
id BIGINT PRIMARY KEY,
|
||||
client_id VARCHAR(100),
|
||||
port INT,
|
||||
upload_bytes BIGINT,
|
||||
download_bytes BIGINT,
|
||||
create_time DATETIME
|
||||
);
|
||||
```
|
||||
|
||||
### 数据关系
|
||||
|
||||
```
|
||||
客户端表 (lazy_netty_client)
|
||||
↓ (1:N)
|
||||
端口映射表 (lazy_server_permeate_client_mapping)
|
||||
↓ (1:N)
|
||||
流量统计表 (lazy_netty_flow_statistics)
|
||||
```
|
||||
|
||||
## 🔧 配置架构
|
||||
|
||||
### 配置层次结构
|
||||
|
||||
```
|
||||
application.yml (主配置)
|
||||
├── spring.lazy.netty.server (服务端配置)
|
||||
│ ├── mode: standalone/cluster
|
||||
│ ├── node-id: 节点ID
|
||||
│ ├── node-host: 节点主机
|
||||
│ └── node-port: 节点端口
|
||||
├── spring.lazy.netty.client (客户端配置)
|
||||
│ ├── client-id: 客户端ID
|
||||
│ ├── inet-host: 服务端地址
|
||||
│ └── inet-port: 服务端端口
|
||||
└── spring.lazy.netty.protocol.proxy (代理配置)
|
||||
├── authentication: 认证开关
|
||||
├── socket-protocol-proxy: SOCKS代理
|
||||
└── http-protocol-proxy: HTTP代理
|
||||
```
|
||||
|
||||
### 配置优先级
|
||||
|
||||
1. **环境变量**: 最高优先级
|
||||
2. **命令行参数**: 次高优先级
|
||||
3. **配置文件**: 默认优先级
|
||||
4. **默认值**: 最低优先级
|
||||
|
||||
## 🔒 安全架构
|
||||
|
||||
### 认证机制
|
||||
|
||||
1. **Token认证**
|
||||
- 基于 JWT 的 Token 认证
|
||||
- 支持 Token 过期和刷新
|
||||
- 可配置 Token 验证开关
|
||||
|
||||
2. **AppKey/AppSecret认证**
|
||||
- 客户端和服务端之间的认证
|
||||
- 支持动态密钥管理
|
||||
- 防止未授权访问
|
||||
|
||||
3. **代理认证**
|
||||
- HTTP代理认证
|
||||
- SOCKS代理认证
|
||||
- 支持用户名密码认证
|
||||
|
||||
### 网络安全
|
||||
|
||||
1. **SSL/TLS加密**
|
||||
- 支持 HTTPS 访问管理界面
|
||||
- 可配置 SSL 证书
|
||||
- 支持强制 HTTPS 访问
|
||||
|
||||
2. **流量加密**
|
||||
- 支持客户端与服务端之间的流量加密
|
||||
- 可配置加密算法
|
||||
- 防止数据泄露
|
||||
|
||||
3. **访问控制**
|
||||
- 基于角色的访问控制 (RBAC)
|
||||
- 支持细粒度权限控制
|
||||
- 记录访问日志
|
||||
|
||||
## 📊 监控架构
|
||||
|
||||
### 监控指标
|
||||
|
||||
1. **系统监控**
|
||||
- CPU 使用率
|
||||
- 内存使用率
|
||||
- 磁盘 I/O
|
||||
- 网络 I/O
|
||||
|
||||
2. **应用监控**
|
||||
- 连接数统计
|
||||
- 流量统计
|
||||
- 响应时间
|
||||
- 错误率
|
||||
|
||||
3. **业务监控**
|
||||
- 客户端在线状态
|
||||
- 端口映射状态
|
||||
- 代理连接状态
|
||||
- 流量使用情况
|
||||
|
||||
### 监控数据流
|
||||
|
||||
```
|
||||
应用指标 → 监控收集器 → 数据存储 → 监控界面
|
||||
↑ ↓
|
||||
告警规则 ← 告警引擎 ← 数据分析 ← 监控数据
|
||||
```
|
||||
|
||||
## 🚀 部署架构
|
||||
|
||||
### 单机部署
|
||||
|
||||
```
|
||||
┌─────────────────────────────────┐
|
||||
│ 单机服务端 │
|
||||
│ ┌─────────────────────────┐ │
|
||||
│ │ Web UI (6001) │ │
|
||||
│ │ TCP Server (7001) │ │
|
||||
│ │ HTTP Proxy (8001) │ │
|
||||
│ │ SOCKS Proxy (9001) │ │
|
||||
│ └─────────────────────────┘ │
|
||||
└─────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 集群部署
|
||||
|
||||
```
|
||||
┌─────────────────────────────────┐
|
||||
│ 负载均衡器 │
|
||||
│ ┌─────────┬─────────┬─────────┐ │
|
||||
│ │ 节点1 │ 节点2 │ 节点3 │ │
|
||||
│ │ 6001 │ 6001 │ 6001 │ │
|
||||
│ │ 7001 │ 7001 │ 7001 │ │
|
||||
│ └─────────┴─────────┴─────────┘ │
|
||||
└─────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Docker部署
|
||||
|
||||
```
|
||||
┌─────────────────────────────────┐
|
||||
│ Docker Host │
|
||||
│ ┌─────────────────────────┐ │
|
||||
│ │ wlcn-server │ │
|
||||
│ │ (6001,7001,8001,9001)│ │
|
||||
│ └─────────────────────────┘ │
|
||||
│ ┌─────────────────────────┐ │
|
||||
│ │ wlcn-client │ │
|
||||
│ │ (6004,8002,9002) │ │
|
||||
│ └─────────────────────────┘ │
|
||||
└─────────────────────────────────┘
|
||||
```
|
||||
|
||||
## 🔄 扩展架构
|
||||
|
||||
### 插件机制
|
||||
|
||||
1. **协议插件**
|
||||
- 支持自定义协议扩展
|
||||
- 插件热加载
|
||||
- 协议版本兼容
|
||||
|
||||
2. **过滤器插件**
|
||||
- 支持自定义过滤器
|
||||
- 过滤器链式处理
|
||||
- 动态过滤器配置
|
||||
|
||||
3. **监控插件**
|
||||
- 支持自定义监控指标
|
||||
- 监控数据导出
|
||||
- 告警规则自定义
|
||||
|
||||
### API扩展
|
||||
|
||||
1. **RESTful API**
|
||||
- 提供标准的 REST API
|
||||
- 支持 JSON 数据格式
|
||||
- 支持 API 版本控制
|
||||
|
||||
2. **WebSocket API**
|
||||
- 实时数据推送
|
||||
- 双向通信支持
|
||||
- 连接状态管理
|
||||
|
||||
3. **gRPC API**
|
||||
- 高性能 RPC 调用
|
||||
- 支持流式传输
|
||||
- 跨语言支持
|
||||
|
||||
---
|
||||
|
||||
**版本**: 1.3.1-JDK24
|
||||
**更新时间**: 2024年
|
||||
**维护者**: 吴佳伟
|
||||
357
项目总结.md
Normal file
357
项目总结.md
Normal file
@@ -0,0 +1,357 @@
|
||||
# Wu-Lazy-Cloud-Network 项目总结
|
||||
|
||||
## 📋 项目概述
|
||||
|
||||
**Wu-Lazy-Cloud-Network (WLCN)** 是一款基于 Spring Boot 3.5.0 和 JDK 24 开发的高性能网络穿透和代理工具。该项目采用模块化设计,支持多种网络协议,提供完整的内网穿透、网络代理、流量监控等功能。
|
||||
|
||||
## 🎯 项目特点
|
||||
|
||||
### 1. 高性能架构
|
||||
- **基于 Netty**: 采用 Netty 异步非阻塞 I/O 框架,支持高并发连接
|
||||
- **多协议支持**: 支持 TCP、HTTP、SOCKS 等多种协议
|
||||
- **连接池管理**: 智能连接池,提高资源利用率
|
||||
- **流量控制**: 内置流量控制机制,防止系统过载
|
||||
|
||||
### 2. 模块化设计
|
||||
- **松耦合架构**: 各模块独立,便于维护和扩展
|
||||
- **插件化支持**: 支持自定义协议和过滤器插件
|
||||
- **配置灵活**: 支持多种配置方式,适应不同部署环境
|
||||
|
||||
### 3. 功能完整
|
||||
- **内网穿透**: 支持多种穿透模式,满足不同场景需求
|
||||
- **网络代理**: 提供 HTTP 和 SOCKS 代理服务
|
||||
- **流量监控**: 实时监控网络流量,提供详细统计报表
|
||||
- **路由管理**: 支持虚拟路由,实现灵活的网络配置
|
||||
|
||||
### 4. 安全可靠
|
||||
- **多重认证**: 支持 Token、AppKey/AppSecret 等多种认证方式
|
||||
- **流量加密**: 支持 SSL/TLS 加密传输
|
||||
- **访问控制**: 基于角色的权限控制
|
||||
- **审计日志**: 完整的操作日志记录
|
||||
|
||||
## 🔧 技术亮点
|
||||
|
||||
### 1. 网络通信架构
|
||||
|
||||
#### 心跳机制
|
||||
```java
|
||||
/**
|
||||
* 客户端与服务端保持长连接的心跳机制
|
||||
* 通过定时发送心跳包,检测连接状态
|
||||
*/
|
||||
public class HeartbeatManager {
|
||||
private final ScheduledExecutorService scheduler;
|
||||
private final Channel channel;
|
||||
|
||||
public void startHeartbeat() {
|
||||
scheduler.scheduleAtFixedRate(() -> {
|
||||
if (channel.isActive()) {
|
||||
channel.writeAndFlush(createHeartbeatMessage());
|
||||
}
|
||||
}, 0, 30, TimeUnit.SECONDS);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 通道管理
|
||||
```java
|
||||
/**
|
||||
* 智能通道管理,支持多种通道类型
|
||||
* 包括心跳通道、访客通道、真实通道等
|
||||
*/
|
||||
public class ChannelManager {
|
||||
private final Map<String, ChannelContext> channelMap;
|
||||
|
||||
public void registerChannel(String id, ChannelContext context) {
|
||||
channelMap.put(id, context);
|
||||
}
|
||||
|
||||
public ChannelContext getChannel(String id) {
|
||||
return channelMap.get(id);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 协议处理
|
||||
|
||||
#### 协议适配器
|
||||
```java
|
||||
/**
|
||||
* 协议适配器,支持多种协议的统一处理
|
||||
*/
|
||||
public interface ProtocolAdapter {
|
||||
void handle(Channel channel, Object message);
|
||||
boolean supports(ProtocolType type);
|
||||
}
|
||||
|
||||
@Component
|
||||
public class HttpProtocolAdapter implements ProtocolAdapter {
|
||||
@Override
|
||||
public void handle(Channel channel, Object message) {
|
||||
// HTTP 协议处理逻辑
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supports(ProtocolType type) {
|
||||
return type == ProtocolType.HTTP;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 过滤器链
|
||||
```java
|
||||
/**
|
||||
* 过滤器链,支持请求的链式处理
|
||||
*/
|
||||
public class FilterChain {
|
||||
private final List<NettyFilter> filters;
|
||||
|
||||
public void doFilter(Channel channel, Object message) {
|
||||
for (NettyFilter filter : filters) {
|
||||
if (!filter.filter(channel, message)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 数据持久化
|
||||
|
||||
#### Lazy ORM 集成
|
||||
```java
|
||||
/**
|
||||
* 基于 Lazy ORM 的数据访问层
|
||||
* 提供类型安全的数据库操作
|
||||
*/
|
||||
@Repository
|
||||
public class ClientRepository {
|
||||
|
||||
public List<LazyNettyClient> findOnlineClients() {
|
||||
return lazyLambdaStream.findList(LazyNettyClient.class)
|
||||
.where(LazyNettyClient::getIsDeleted, false)
|
||||
.where(LazyNettyClient::getIsOnline, true)
|
||||
.getData();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 流量统计
|
||||
```java
|
||||
/**
|
||||
* 实时流量统计,支持按客户端、端口等维度统计
|
||||
*/
|
||||
@Component
|
||||
public class FlowStatisticsService {
|
||||
|
||||
public void recordFlow(String clientId, int port, long uploadBytes, long downloadBytes) {
|
||||
LazyNettyFlowStatistics statistics = new LazyNettyFlowStatistics();
|
||||
statistics.setClientId(clientId);
|
||||
statistics.setPort(port);
|
||||
statistics.setUploadBytes(uploadBytes);
|
||||
statistics.setDownloadBytes(downloadBytes);
|
||||
statistics.setCreateTime(LocalDateTime.now());
|
||||
|
||||
lazyLambdaStream.save(statistics);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 监控和告警
|
||||
|
||||
#### 实时监控
|
||||
```java
|
||||
/**
|
||||
* 实时监控系统状态
|
||||
* 包括连接数、流量、响应时间等指标
|
||||
*/
|
||||
@Component
|
||||
public class MonitoringService {
|
||||
|
||||
public void recordMetrics(String metricName, double value) {
|
||||
// 记录监控指标
|
||||
metricsRegistry.record(metricName, value);
|
||||
}
|
||||
|
||||
public void checkAlerts() {
|
||||
// 检查告警条件
|
||||
if (getConnectionCount() > maxConnections) {
|
||||
alertService.sendAlert("连接数超限");
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🚀 应用场景
|
||||
|
||||
### 1. 内网穿透
|
||||
|
||||
#### 远程办公
|
||||
- **场景**: 员工在家访问公司内网资源
|
||||
- **方案**: 通过服务端渗透客户端模式,将内网服务映射到公网
|
||||
- **优势**: 安全可靠,支持多种协议
|
||||
|
||||
#### 开发调试
|
||||
- **场景**: 开发人员需要远程调试内网服务
|
||||
- **方案**: 使用客户端渗透服务端模式,实现远程端口映射
|
||||
- **优势**: 配置简单,支持动态端口分配
|
||||
|
||||
### 2. 网络代理
|
||||
|
||||
#### 异地组网
|
||||
- **场景**: 多个办公地点需要统一网络访问
|
||||
- **方案**: 使用代理功能,实现异地网络互联
|
||||
- **优势**: 支持 HTTP 和 SOCKS 代理,兼容性好
|
||||
|
||||
#### 网络加速
|
||||
- **场景**: 需要优化网络访问速度
|
||||
- **方案**: 通过代理服务器优化网络路径
|
||||
- **优势**: 智能路由,自动选择最优路径
|
||||
|
||||
### 3. 流量监控
|
||||
|
||||
#### 网络审计
|
||||
- **场景**: 需要监控网络使用情况
|
||||
- **方案**: 利用内置流量监控功能
|
||||
- **优势**: 实时监控,详细报表
|
||||
|
||||
#### 成本控制
|
||||
- **场景**: 控制网络使用成本
|
||||
- **方案**: 设置流量限制和告警
|
||||
- **优势**: 精确控制,及时告警
|
||||
|
||||
## 📊 性能指标
|
||||
|
||||
### 1. 并发性能
|
||||
- **最大连接数**: 10,000+ 并发连接
|
||||
- **响应时间**: 平均 < 10ms
|
||||
- **吞吐量**: 10,000+ 请求/秒
|
||||
|
||||
### 2. 资源使用
|
||||
- **内存使用**: 512MB - 2GB (可配置)
|
||||
- **CPU 使用**: 低负载,支持高并发
|
||||
- **网络带宽**: 支持千兆网络
|
||||
|
||||
### 3. 可用性
|
||||
- **系统稳定性**: 99.9% 可用性
|
||||
- **故障恢复**: 自动故障转移
|
||||
- **数据一致性**: 强一致性保证
|
||||
|
||||
## 🔄 版本演进
|
||||
|
||||
### 1.3.1-JDK24 (当前版本)
|
||||
- **新增功能**: 代理流量监控
|
||||
- **技术升级**: 升级到 JDK 24 和 Spring Boot 3.5.0
|
||||
- **安全增强**: 添加 SOCKS 授权验证
|
||||
|
||||
### 1.3.1-JDK17
|
||||
- **新增功能**: 代理流量监控
|
||||
- **部署优化**: Docker 仓库上架
|
||||
- **性能优化**: 优化网络传输性能
|
||||
|
||||
### 1.2.9-JDK17
|
||||
- **安全增强**: 添加 AppKey/AppSecret 验证
|
||||
- **功能优化**: 支持同一客户端 ID 多次注册
|
||||
- **兼容性**: 大版本更新,协议不向下兼容
|
||||
|
||||
## 🛠️ 部署方案
|
||||
|
||||
### 1. 单机部署
|
||||
- **适用场景**: 小规模使用,测试环境
|
||||
- **部署方式**: Docker 或 JAR 包部署
|
||||
- **资源配置**: 最小 1GB 内存
|
||||
|
||||
### 2. 集群部署
|
||||
- **适用场景**: 大规模生产环境
|
||||
- **部署方式**: 多节点集群部署
|
||||
- **资源配置**: 每节点 2GB+ 内存
|
||||
|
||||
### 3. 云原生部署
|
||||
- **适用场景**: 云环境部署
|
||||
- **部署方式**: Kubernetes 部署
|
||||
- **资源配置**: 弹性伸缩,按需分配
|
||||
|
||||
## 🔒 安全特性
|
||||
|
||||
### 1. 认证机制
|
||||
- **Token 认证**: 基于 JWT 的 Token 认证
|
||||
- **AppKey/AppSecret**: 客户端服务端认证
|
||||
- **代理认证**: HTTP/SOCKS 代理认证
|
||||
|
||||
### 2. 网络安全
|
||||
- **SSL/TLS 加密**: 支持 HTTPS 访问
|
||||
- **流量加密**: 客户端服务端通信加密
|
||||
- **防火墙友好**: 支持防火墙穿透
|
||||
|
||||
### 3. 数据安全
|
||||
- **敏感信息加密**: 数据库敏感信息加密存储
|
||||
- **访问日志**: 完整的操作审计日志
|
||||
- **数据备份**: 支持配置数据备份
|
||||
|
||||
## 📈 未来规划
|
||||
|
||||
### 短期目标 (3-6个月)
|
||||
- **性能优化**: 进一步提升并发性能
|
||||
- **功能增强**: 添加更多协议支持
|
||||
- **监控完善**: 增强监控和告警功能
|
||||
|
||||
### 中期目标 (6-12个月)
|
||||
- **云原生**: 完善 Kubernetes 部署支持
|
||||
- **API 网关**: 集成 API 网关功能
|
||||
- **微服务**: 支持微服务架构
|
||||
|
||||
### 长期目标 (1-2年)
|
||||
- **AI 集成**: 集成 AI 智能路由
|
||||
- **边缘计算**: 支持边缘节点部署
|
||||
- **生态建设**: 构建完整的生态系统
|
||||
|
||||
## 💡 技术贡献
|
||||
|
||||
### 1. 开源贡献
|
||||
- **代码质量**: 遵循最佳实践,代码质量高
|
||||
- **文档完善**: 提供详细的技术文档
|
||||
- **社区活跃**: 积极参与开源社区
|
||||
|
||||
### 2. 技术创新
|
||||
- **协议扩展**: 创新的协议扩展机制
|
||||
- **架构设计**: 优秀的模块化架构设计
|
||||
- **性能优化**: 高效的网络性能优化
|
||||
|
||||
### 3. 实用价值
|
||||
- **解决痛点**: 解决内网穿透和网络代理的实际问题
|
||||
- **易于使用**: 提供简单易用的 Web 界面
|
||||
- **稳定可靠**: 经过生产环境验证
|
||||
|
||||
## 🎉 项目总结
|
||||
|
||||
Wu-Lazy-Cloud-Network 项目是一个技术先进、功能完整、实用价值高的网络工具。项目采用现代化的技术栈,具有良好的架构设计和代码质量,能够有效解决内网穿透、网络代理等实际问题。
|
||||
|
||||
### 项目优势
|
||||
1. **技术先进**: 采用最新的 JDK 24 和 Spring Boot 3.5.0
|
||||
2. **功能完整**: 提供内网穿透、代理、监控等完整功能
|
||||
3. **性能优秀**: 基于 Netty 的高性能网络框架
|
||||
4. **易于使用**: 提供友好的 Web 管理界面
|
||||
5. **安全可靠**: 多重安全机制,生产环境验证
|
||||
|
||||
### 应用价值
|
||||
1. **远程办公**: 支持安全的远程办公解决方案
|
||||
2. **开发调试**: 提供便捷的远程开发调试工具
|
||||
3. **网络优化**: 实现网络加速和优化
|
||||
4. **监控审计**: 提供完整的网络监控和审计功能
|
||||
|
||||
### 发展前景
|
||||
项目具有良好的发展前景,随着远程办公和云原生技术的普及,内网穿透和网络代理的需求将持续增长。项目将继续完善功能,提升性能,为用户提供更好的服务。
|
||||
|
||||
---
|
||||
|
||||
**项目地址**:
|
||||
- [Gitee](https://gitee.com/wujiawei1207537021/wu-lazy-cloud-network)
|
||||
- [GitHub](https://github.com/wujiawei1207537021/wu-lazy-cloud-network)
|
||||
|
||||
**联系方式**:
|
||||
- **作者**: 吴佳伟 (Jia Wei Wu)
|
||||
- **邮箱**: 1207537021@qq.com
|
||||
|
||||
**版本**: 1.3.1-JDK24
|
||||
**更新时间**: 2024年
|
||||
**维护者**: 吴佳伟
|
||||
452
项目说明文档.md
Normal file
452
项目说明文档.md
Normal file
@@ -0,0 +1,452 @@
|
||||
# Wu-Lazy-Cloud-Network 项目说明文档
|
||||
|
||||
## 📋 项目概述
|
||||
|
||||
**Wu-Lazy-Cloud-Network (WLCN)** 是一款基于 Spring Boot 3.5.0 和 JDK 24 开发的网络穿透、渗透工具,支持 TCP、HTTP、SOCKS 协议。该项目是 [wu-framework-parent](https://gitee.com/wujiawei1207537021/wu-framework-parent) 框架孵化的网络解决方案。
|
||||
|
||||
### 🎯 主要功能
|
||||
|
||||
- **内网穿透**:将局域网服务映射到公网,实现远程访问
|
||||
- **网络代理**:支持 HTTP 和 SOCKS 代理,实现异地组网
|
||||
- **流量监控**:实时监控网络流量使用情况
|
||||
- **多协议支持**:支持 TCP、HTTP、SOCKS 等多种协议
|
||||
- **集群部署**:支持单机版和集群模式部署
|
||||
|
||||
## 🏗️ 系统架构
|
||||
|
||||
### 核心模块
|
||||
|
||||
| 模块 | 版本 | 描述 | 端口 |
|
||||
|------|------|------|------|
|
||||
| `wu-lazy-cloud-heartbeat-common` | 1.3.1-JDK24 | 公共模块(接口、枚举、常量、适配器) | - |
|
||||
| `wu-lazy-cloud-heartbeat-server` | 1.3.1-JDK24 | 服务端核心组件 | 6001(Web), 7001(TCP) |
|
||||
| `wu-lazy-cloud-heartbeat-client` | 1.3.1-JDK24 | 客户端核心组件 | 6004(Web) |
|
||||
| `wu-lazy-cloud-heartbeat-dns` | 1.3.1-JDK24 | DNS 解析模块 | - |
|
||||
| `wu-lazy-cloud-heartbeat-protocol-proxy` | 1.3.1-JDK24 | 代理协议模块 | 8001(HTTP), 9001(SOCKS) |
|
||||
|
||||
### 启动模块
|
||||
|
||||
| 模块 | 版本 | 描述 | 用途 |
|
||||
|------|------|------|------|
|
||||
| `wu-lazy-cloud-heartbeat-server-start` | 1.3.1-JDK24 | 服务端启动模块 | 生产部署 |
|
||||
| `wu-lazy-cloud-heartbeat-client-start` | 1.3.1-JDK24 | 客户端启动模块 | 生产部署 |
|
||||
| `wu-lazy-cloud-heartbeat-server-cluster-start` | 1.3.1-JDK24 | 集群服务端启动模块 | 集群部署 |
|
||||
|
||||
## 🔧 技术栈
|
||||
|
||||
### 核心框架
|
||||
- **Spring Boot**: 3.5.3
|
||||
- **JDK**: 24
|
||||
- **Netty**: 网络通信框架
|
||||
- **Lazy ORM**: 数据库操作框架
|
||||
|
||||
### 数据库
|
||||
- **MySQL**: 8.0.33
|
||||
- **H2**: 开发环境数据库
|
||||
|
||||
### 其他依赖
|
||||
- **Lombok**: 代码生成
|
||||
- **MapStruct**: 对象映射
|
||||
- **wu-framework-web**: Web 容器
|
||||
- **wu-authorization-server-platform-starter**: 用户授权体系
|
||||
|
||||
## 🚀 快速开始
|
||||
|
||||
### 环境要求
|
||||
|
||||
- **操作系统**: Windows、Mac、Linux
|
||||
- **Java**: JDK 13+ (推荐 JDK 24)
|
||||
- **内存**: 最小 512MB,推荐 1GB+
|
||||
- **网络**: 需要公网 IP(服务端)
|
||||
|
||||
### Docker 部署
|
||||
|
||||
#### 1. 启动服务端
|
||||
|
||||
```bash
|
||||
docker run -d -it -p 6001:6001 -p 7001:7001 -p 8001:8001 -p 9001:9001 \
|
||||
--name wlcn-server \
|
||||
registry.cn-hangzhou.aliyuncs.com/wu-lazy/wu-lazy-cloud-heartbeat-server:1.3.1-JDK24
|
||||
```
|
||||
|
||||
**端口说明**:
|
||||
- `6001`: Web 管理界面
|
||||
- `7001`: TCP 连接端口
|
||||
- `8001`: HTTP 代理端口
|
||||
- `9001`: SOCKS 代理端口
|
||||
|
||||
#### 2. 启动客户端
|
||||
|
||||
```bash
|
||||
docker run -d -it --privileged -p 6004:6004 \
|
||||
--name wlcn-client \
|
||||
--restart=always \
|
||||
-e spring.lazy.netty.client.inet-host=YOUR_SERVER_IP \
|
||||
-e spring.lazy.netty.client.inet-port=7001 \
|
||||
-e spring.lazy.netty.client.client-id="your-client-id" \
|
||||
registry.cn-hangzhou.aliyuncs.com/wu-lazy/wu-lazy-cloud-heartbeat-client-start:1.3.1-JDK24
|
||||
```
|
||||
|
||||
**环境变量说明**:
|
||||
- `spring.lazy.netty.client.inet-host`: 服务端 IP 地址
|
||||
- `spring.lazy.netty.client.inet-port`: 服务端 TCP 端口
|
||||
- `spring.lazy.netty.client.client-id`: 客户端唯一标识
|
||||
|
||||
### 源码部署
|
||||
|
||||
#### 1. 克隆项目
|
||||
|
||||
```bash
|
||||
git clone https://gitee.com/wujiawei1207537021/wu-lazy-cloud-network.git
|
||||
cd wu-lazy-cloud-network
|
||||
```
|
||||
|
||||
#### 2. 编译项目
|
||||
|
||||
```bash
|
||||
mvn clean package -DskipTests
|
||||
```
|
||||
|
||||
#### 3. 启动服务端
|
||||
|
||||
```bash
|
||||
cd wu-lazy-cloud-heartbeat-start/wu-lazy-cloud-heartbeat-server-start
|
||||
java -jar target/wu-lazy-cloud-heartbeat-server-start-1.3.1-JDK24.jar
|
||||
```
|
||||
|
||||
#### 4. 启动客户端
|
||||
|
||||
```bash
|
||||
cd wu-lazy-cloud-heartbeat-start/wu-lazy-cloud-heartbeat-client-start
|
||||
java -jar target/wu-lazy-cloud-heartbeat-client-start-1.3.1-JDK24.jar
|
||||
```
|
||||
|
||||
## 📖 使用指南
|
||||
|
||||
### Web 管理界面
|
||||
|
||||
#### 1. 访问管理界面
|
||||
|
||||
- **服务端**: http://127.0.0.1:6001/netty-server-ui/index.html
|
||||
- **客户端**: http://127.0.0.1:6004/netty-client-local-ui/index.html
|
||||
|
||||
#### 2. 初始配置
|
||||
|
||||
1. **登录系统**
|
||||
- 默认账号: `admin`
|
||||
- 默认密码: `admin`
|
||||
|
||||
2. **初始化项目**
|
||||
- 添加角色
|
||||
- 为用户授权
|
||||
- 配置客户端映射
|
||||
|
||||
### 内网穿透配置
|
||||
|
||||
#### 服务端渗透客户端(内网穿透)
|
||||
|
||||
1. **配置端口池**
|
||||
- 在服务端管理界面配置需要开放的端口
|
||||
|
||||
2. **配置客户端映射**
|
||||
- 设置访客端口与客户端真实端口的映射关系
|
||||
- 例如:访客端口 19080 → 客户端本地端口 18080
|
||||
|
||||
#### 客户端渗透服务端
|
||||
|
||||
1. **配置客户端端口池**
|
||||
- 在客户端管理界面配置本地端口池
|
||||
|
||||
2. **配置渗透映射**
|
||||
- 设置本地端口到远程端口的映射关系
|
||||
|
||||
### 代理功能使用
|
||||
|
||||
#### HTTP 代理
|
||||
|
||||
1. **获取代理信息**
|
||||
- 服务端: `127.0.0.1:8001`
|
||||
- 客户端: `127.0.0.1:8002`
|
||||
|
||||
2. **配置代理**
|
||||
- 在系统设置中配置 HTTP 代理
|
||||
- 或使用第三方代理软件
|
||||
|
||||
#### SOCKS 代理
|
||||
|
||||
1. **获取代理信息**
|
||||
- 服务端: `127.0.0.1:9001`
|
||||
- 客户端: `127.0.0.1:9002`
|
||||
|
||||
2. **使用代理软件**
|
||||
- 推荐使用 Proxifier 等专业代理软件
|
||||
- 支持全局代理和应用程序代理
|
||||
|
||||
### 路由管理
|
||||
|
||||
#### 虚拟路由
|
||||
|
||||
1. **创建虚拟 IP**
|
||||
- 在路由管理界面创建虚拟 IP 地址
|
||||
- 配置代理目标 IP 和端口
|
||||
|
||||
2. **应用路由规则**
|
||||
- 系统会自动将虚拟 IP 的流量代理到目标地址
|
||||
|
||||
## 🔍 功能详解
|
||||
|
||||
### 网络穿透模式
|
||||
|
||||
#### 1. 服务端渗透客户端
|
||||
- **用途**: 将内网服务暴露到公网
|
||||
- **场景**: 远程访问内网 Web 服务、数据库等
|
||||
- **配置**: 在服务端配置访客端口与客户端端口的映射
|
||||
|
||||
#### 2. 服务端渗透服务端
|
||||
- **用途**: 同局域网内端口映射
|
||||
- **场景**: 在同一网络环境下的服务间通信
|
||||
- **配置**: 配置服务端端口池和映射关系
|
||||
|
||||
#### 3. 客户端渗透服务端
|
||||
- **用途**: 本地端口映射到远程服务端端口
|
||||
- **场景**: 访问远程服务器上的服务
|
||||
- **配置**: 在客户端配置本地端口到远程端口的映射
|
||||
|
||||
#### 4. 客户端渗透客户端
|
||||
- **用途**: 不同网络间的端口映射
|
||||
- **场景**: 异地组网,跨网络访问
|
||||
- **配置**: 配置两个客户端之间的端口映射
|
||||
|
||||
### 代理功能
|
||||
|
||||
#### HTTP 代理
|
||||
- 支持 HTTP/HTTPS 协议代理
|
||||
- 可配置代理认证
|
||||
- 支持流量监控
|
||||
|
||||
#### SOCKS 代理
|
||||
- 支持 SOCKS4/SOCKS5 协议
|
||||
- 支持 TCP/UDP 代理
|
||||
- 可配置认证机制
|
||||
|
||||
### 流量监控
|
||||
|
||||
#### 实时监控
|
||||
- 监控每个客户端的流量使用情况
|
||||
- 支持按端口统计流量
|
||||
- 提供流量趋势图表
|
||||
|
||||
#### 报表功能
|
||||
- 日流量统计报表
|
||||
- 客户端流量排行
|
||||
- 端口使用情况分析
|
||||
|
||||
## ⚙️ 配置说明
|
||||
|
||||
### 服务端配置
|
||||
|
||||
```yaml
|
||||
spring:
|
||||
lazy:
|
||||
netty:
|
||||
server:
|
||||
mode: standalone # 模式:standalone/cluster
|
||||
node-id: default # 节点ID
|
||||
node-host: 127.0.0.1 # 节点主机
|
||||
node-port: 7001 # 节点端口
|
||||
enable-flow-control: true # 启用流量控制
|
||||
enable-token-verification: false # 启用Token验证
|
||||
tcp:
|
||||
port: 7001 # TCP端口
|
||||
udp:
|
||||
port: 7001 # UDP端口
|
||||
```
|
||||
|
||||
### 客户端配置
|
||||
|
||||
```yaml
|
||||
spring:
|
||||
lazy:
|
||||
netty:
|
||||
client:
|
||||
client-id: your-client-id # 客户端ID
|
||||
inet-host: 127.0.0.1 # 服务端地址
|
||||
inet-port: 7001 # 服务端端口
|
||||
enable: true # 启用客户端连接
|
||||
```
|
||||
|
||||
### 代理配置
|
||||
|
||||
```yaml
|
||||
spring:
|
||||
lazy:
|
||||
netty:
|
||||
protocol:
|
||||
proxy:
|
||||
authentication: true # 启用代理认证
|
||||
enable-proxy-log: false # 启用代理日志
|
||||
socket-protocol-proxy:
|
||||
port: 9001 # SOCKS代理端口
|
||||
http-protocol-proxy:
|
||||
port: 8001 # HTTP代理端口
|
||||
```
|
||||
|
||||
## 🔧 开发指南
|
||||
|
||||
### 项目结构
|
||||
|
||||
```
|
||||
wu-lazy-cloud-network/
|
||||
├── wu-lazy-cloud-heartbeat-common/ # 公共模块
|
||||
├── wu-lazy-cloud-heartbeat-server/ # 服务端核心
|
||||
├── wu-lazy-cloud-heartbeat-client/ # 客户端核心
|
||||
├── wu-lazy-cloud-heartbeat-dns/ # DNS模块
|
||||
├── wu-lazy-cloud-heartbeat-protocol-proxy/ # 代理协议模块
|
||||
└── wu-lazy-cloud-heartbeat-start/ # 启动模块
|
||||
├── wu-lazy-cloud-heartbeat-server-start/ # 服务端启动
|
||||
├── wu-lazy-cloud-heartbeat-client-start/ # 客户端启动
|
||||
└── wu-lazy-cloud-heartbeat-server-cluster-start/ # 集群启动
|
||||
```
|
||||
|
||||
### 核心概念
|
||||
|
||||
#### 1. 通道(Channel)
|
||||
- **心跳通道**: 客户端与服务端建立的持久连接
|
||||
- **访客通道**: 外部访问者建立的连接
|
||||
- **真实通道**: 客户端本地服务的连接
|
||||
|
||||
#### 2. 渗透(Permeate)
|
||||
- **服务端渗透**: 由服务端发起的网络穿透
|
||||
- **客户端渗透**: 由客户端发起的网络穿透
|
||||
|
||||
#### 3. 代理(Proxy)
|
||||
- **HTTP代理**: 基于HTTP协议的代理服务
|
||||
- **SOCKS代理**: 基于SOCKS协议的代理服务
|
||||
|
||||
### 扩展开发
|
||||
|
||||
#### 自定义协议
|
||||
1. 实现 `NettyMsg` 接口
|
||||
2. 注册到协议处理器
|
||||
3. 配置协议路由
|
||||
|
||||
#### 自定义过滤器
|
||||
1. 继承 `NettyFilter` 接口
|
||||
2. 实现过滤逻辑
|
||||
3. 注册到过滤器链
|
||||
|
||||
## 🐛 故障排除
|
||||
|
||||
### 常见问题
|
||||
|
||||
#### 1. 客户端连接失败
|
||||
- **检查网络**: 确保客户端能访问服务端
|
||||
- **检查端口**: 确认服务端端口已开放
|
||||
- **检查配置**: 验证客户端配置参数
|
||||
|
||||
#### 2. 内网穿透不工作
|
||||
- **检查映射**: 确认端口映射配置正确
|
||||
- **检查服务**: 确认目标服务正在运行
|
||||
- **检查防火墙**: 确认防火墙规则允许
|
||||
|
||||
#### 3. 代理连接失败
|
||||
- **检查代理配置**: 确认代理地址和端口正确
|
||||
- **检查认证**: 确认代理认证信息正确
|
||||
- **检查网络**: 确认网络连接正常
|
||||
|
||||
### 日志分析
|
||||
|
||||
#### 服务端日志
|
||||
```bash
|
||||
# 查看服务端日志
|
||||
docker logs wlcn-server
|
||||
|
||||
# 查看详细日志
|
||||
docker logs wlcn-server --tail 100 -f
|
||||
```
|
||||
|
||||
#### 客户端日志
|
||||
```bash
|
||||
# 查看客户端日志
|
||||
docker logs wlcn-client
|
||||
|
||||
# 查看详细日志
|
||||
docker logs wlcn-client --tail 100 -f
|
||||
```
|
||||
|
||||
## 📈 性能优化
|
||||
|
||||
### 系统调优
|
||||
|
||||
#### 1. 网络缓冲区优化
|
||||
```bash
|
||||
# Linux系统
|
||||
sudo sysctl -w net.core.rmem_default=4194304
|
||||
sudo sysctl -w net.core.rmem_max=4194304
|
||||
sudo sysctl -w net.core.wmem_default=4194304
|
||||
sudo sysctl -w net.core.wmem_max=4194304
|
||||
```
|
||||
|
||||
#### 2. JVM 参数优化
|
||||
```bash
|
||||
# 生产环境推荐配置
|
||||
-Xms2g -Xmx4g -XX:+UseG1GC -XX:MaxGCPauseMillis=200
|
||||
```
|
||||
|
||||
#### 3. 连接池优化
|
||||
- 调整 Netty 连接池大小
|
||||
- 优化线程池配置
|
||||
- 调整缓冲区大小
|
||||
|
||||
### 监控指标
|
||||
|
||||
#### 1. 系统监控
|
||||
- CPU 使用率
|
||||
- 内存使用率
|
||||
- 网络 I/O
|
||||
|
||||
#### 2. 应用监控
|
||||
- 连接数
|
||||
- 流量统计
|
||||
- 响应时间
|
||||
|
||||
## 🔒 安全说明
|
||||
|
||||
### 认证机制
|
||||
- 支持 Token 认证
|
||||
- 支持 AppKey/AppSecret 认证
|
||||
- 支持代理认证
|
||||
|
||||
### 网络安全
|
||||
- 支持 SSL/TLS 加密
|
||||
- 支持流量加密传输
|
||||
- 支持访问控制
|
||||
|
||||
### 数据安全
|
||||
- 敏感信息加密存储
|
||||
- 支持数据备份
|
||||
- 支持审计日志
|
||||
|
||||
## 📞 技术支持
|
||||
|
||||
### 联系方式
|
||||
- **作者**: 吴佳伟 (Jia Wei Wu)
|
||||
- **邮箱**: 1207537021@qq.com
|
||||
- **项目地址**:
|
||||
- [Gitee](https://gitee.com/wujiawei1207537021/wu-lazy-cloud-network)
|
||||
- [GitHub](https://github.com/wujiawei1207537021/wu-lazy-cloud-network)
|
||||
|
||||
### 社区支持
|
||||
- **Issues**: 通过 Git 平台提交问题
|
||||
- **讨论**: 参与项目讨论
|
||||
- **贡献**: 欢迎提交 Pull Request
|
||||
|
||||
## 📄 许可证
|
||||
|
||||
本项目采用 [Apache License 2.0](LICENSE) 许可证。
|
||||
|
||||
---
|
||||
|
||||
**版本**: 1.3.1-JDK24
|
||||
**更新时间**: 2024年
|
||||
**维护者**: 吴佳伟
|
||||
Reference in New Issue
Block a user