Compare commits
229 Commits
1.2.8-JDK1
...
b834241859
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b834241859 | ||
|
|
d01c905752 | ||
|
|
aaf22634bd | ||
|
|
38ca56dbba | ||
|
|
ec35d1c296 | ||
|
|
3754ee8701 | ||
|
|
49f9e96c29 | ||
|
|
ac38d8dfd7 | ||
|
|
6142105ac3 | ||
|
|
ff3681fc46 | ||
|
|
9e1a47f4e9 | ||
|
|
13858a0b7c | ||
|
|
caff71be87 | ||
|
|
04c683cb9a | ||
|
|
e5f53b520b | ||
|
|
50b2b1866c | ||
|
|
841c24a6ed | ||
|
|
e387a43437 | ||
|
|
438198bcc5 | ||
|
|
afe1a1417f | ||
|
|
d9d82a99d5 | ||
|
|
c5aeb6f0f7 | ||
|
|
f8f485a14a | ||
|
|
7178974abb | ||
|
|
f2fede4a96 | ||
|
|
74eab26478 | ||
|
|
faabae3d19 | ||
|
|
6c86a41359 | ||
|
|
3353e4bd83 | ||
|
|
2f0f4270d3 | ||
|
|
61f639c51d | ||
|
|
46e657535b | ||
|
|
ea296da78e | ||
|
|
aafa684525 | ||
|
|
e41c293c31 | ||
|
|
c8b4238d90 | ||
|
|
32eaace9c1 | ||
|
|
21136284c7 | ||
|
|
7c640816aa | ||
|
|
aba3e2acc9 | ||
|
|
25f81ca271 | ||
|
|
a1f764f1cc | ||
|
|
1699130f14 | ||
|
|
6b16ff7065 | ||
|
|
87435b85d4 | ||
|
|
2fc0187f43 | ||
|
|
513c8ba095 | ||
|
|
2add2ddfa7 | ||
|
|
f791b36d24 | ||
|
|
bebb67395e | ||
|
|
ad1c5b1b36 | ||
|
|
4c76635292 | ||
|
|
ffdd593113 | ||
|
|
5616abafd0 | ||
|
|
6d0bcd2f63 | ||
|
|
da7d55c266 | ||
|
|
30403d1da8 | ||
|
|
58026465ad | ||
|
|
3b7bf3d983 | ||
|
|
7838f7a88d | ||
|
|
9c13074e5c | ||
|
|
08c0194733 | ||
|
|
e3deb4cdfe | ||
|
|
229e273b7d | ||
|
|
3163987ef7 | ||
|
|
51b603a6c5 | ||
|
|
c34f1239d8 | ||
|
|
edaa4b84d7 | ||
|
|
6c6584fdb9 | ||
|
|
221623e9c0 | ||
|
|
ff150eb31c | ||
|
|
e1de673b52 | ||
|
|
01a2937414 | ||
|
|
e8383c78ad | ||
|
|
1a08fe64e9 | ||
|
|
ca87968469 | ||
|
|
903ba88787 | ||
|
|
0505d6d201 | ||
|
|
556cb3fd1b | ||
|
|
ddb709c3a8 | ||
|
|
9cd85abe1d | ||
|
|
664bafdc86 | ||
|
|
3b9379a7aa | ||
|
|
17306c348a | ||
|
|
e518e20cc1 | ||
|
|
a27506299e | ||
|
|
40de2dbe4d | ||
|
|
06869dcd2f | ||
|
|
c9b866885a | ||
|
|
f496f12fe3 | ||
|
|
6e6ce666b8 | ||
|
|
f82e9e5f0a | ||
|
|
26e4990f0a | ||
|
|
833e97a89d | ||
|
|
dab44fc1a2 | ||
|
|
200a636379 | ||
|
|
08b8e2dbb8 | ||
|
|
e7df027d65 | ||
|
|
071b844d68 | ||
|
|
afa4d5c360 | ||
|
|
c057d7b2d5 | ||
|
|
7f9cebec8a | ||
|
|
32a641ce99 | ||
|
|
a3c88ffa9f | ||
|
|
466faacb93 | ||
|
|
687770e086 | ||
|
|
32c757ef5e | ||
|
|
68f4c92366 | ||
|
|
ad7fa61067 | ||
|
|
fe3adeee03 | ||
|
|
2e40988ef4 | ||
|
|
5528ef6ebd | ||
|
|
9401c27572 | ||
|
|
c852e3b351 | ||
|
|
17b220a76a | ||
|
|
191e23fc83 | ||
|
|
96929044fa | ||
|
|
965142793c | ||
|
|
9a44a598ef | ||
|
|
c2c350a28a | ||
|
|
8cc3b4858a | ||
|
|
3c32a5d157 | ||
|
|
578429777a | ||
|
|
5eba201979 | ||
|
|
f8a9ca4264 | ||
|
|
7af14b4251 | ||
|
|
24fe9e4bc9 | ||
|
|
2adf5e4749 | ||
|
|
b7f099d3a4 | ||
|
|
f0fd22ccd4 | ||
|
|
7b26e9cb60 | ||
|
|
6e79901be3 | ||
|
|
f88e0e2b7f | ||
|
|
9324b516fd | ||
|
|
a6c46c3cba | ||
|
|
66956636b9 | ||
|
|
9dc36fe8e9 | ||
|
|
f2a22c177e | ||
|
|
98587b442c | ||
|
|
e51ad201de | ||
|
|
d8a8b630ae | ||
|
|
e0f461460a | ||
|
|
75acddadca | ||
|
|
50e67f54e3 | ||
|
|
3444e90d3d | ||
|
|
b1b329aae1 | ||
|
|
26283de998 | ||
|
|
9c5000f995 | ||
|
|
532d05d4a8 | ||
|
|
402f6f0ac1 | ||
|
|
a5a3d7d6f2 | ||
|
|
e4c33f34c1 | ||
|
|
394dfdf337 | ||
|
|
9b44a199be | ||
|
|
fe8a2c865a | ||
|
|
ba8ca7bcd9 | ||
|
|
9a211ad200 | ||
|
|
40ab82de35 | ||
|
|
8728cd5d54 | ||
|
|
3f7f10bcd5 | ||
|
|
269a0f2ba2 | ||
|
|
8f02c03d42 | ||
|
|
9e1da9649e | ||
|
|
074ab4f217 | ||
|
|
07e8b20449 | ||
|
|
2a98ec0589 | ||
|
|
3321e0dd7b | ||
|
|
cf9438a7da | ||
|
|
4690bc85b3 | ||
|
|
2389a25e11 | ||
|
|
cf10347939 | ||
|
|
98b4701978 | ||
|
|
7da5f58263 | ||
|
|
a019561c06 | ||
|
|
f985cdac8f | ||
|
|
7429cff23a | ||
|
|
9fa3359569 | ||
|
|
fac28c4fc8 | ||
|
|
f9188037a0 | ||
|
|
f19b1cae68 | ||
|
|
0df0a42b2c | ||
|
|
2b3c7cb7c2 | ||
|
|
daeba59a43 | ||
|
|
cb4c9c0b41 | ||
|
|
0ceb88bfe3 | ||
|
|
42bc37c712 | ||
|
|
41a81133f1 | ||
|
|
ddaa5568e0 | ||
|
|
9b64c622cc | ||
|
|
f11200cee9 | ||
|
|
0f04f29cd0 | ||
|
|
3568292ac2 | ||
|
|
1924e87c7d | ||
|
|
30e1141ecf | ||
|
|
79b09ecfea | ||
|
|
5a079fcba8 | ||
|
|
20bb29350c | ||
|
|
ea2fb01b7e | ||
|
|
ba960a70ab | ||
|
|
4de7cdb6be | ||
|
|
1c6f56d31e | ||
|
|
8952d2277f | ||
|
|
dab6e580e4 | ||
|
|
9edb6f3d4d | ||
|
|
3740a4f4ea | ||
|
|
3b57ee1c23 | ||
|
|
b76f7a8f62 | ||
|
|
aa056dbe07 | ||
|
|
810579178f | ||
|
|
240de53888 | ||
|
|
2eb6dc2775 | ||
|
|
c665bf687d | ||
|
|
1e2f58b5a3 | ||
|
|
381f8a6960 | ||
|
|
a04499ab4b | ||
|
|
477d8cfaac | ||
|
|
b2cd1eee0a | ||
|
|
b7d571ccc1 | ||
|
|
55ce3ff359 | ||
|
|
42e8e5afec | ||
|
|
4977348113 | ||
|
|
89f9207367 | ||
|
|
70cf9fe3ac | ||
|
|
ecd5288929 | ||
|
|
571fe7893d | ||
|
|
1e89813793 | ||
|
|
0dd5b986a2 | ||
|
|
67c2537823 | ||
|
|
8dc1272109 |
25
ClientPermeateClient.md
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
### 背景:国庆期间的问题,如何在老家访问杭州办公室的网络呢
|
||||||
|
#### 实现方案:异地组网
|
||||||
|
#### 实现语言:Java
|
||||||
|
#### 环境:三个网络,一台拥有公网IP的服务器、一台杭州本地机房内服务器、你老家所在网络中的一台电脑(用你自己的就好了)
|
||||||
|
#### 实现原理:
|
||||||
|
|
||||||
|
#### 操作步骤:拥有公网ip的服务器开发6001(web)、7001端口(tcp),然后执行命令启动服务端
|
||||||
|
```shell
|
||||||
|
docker run -d -it -p 6001:6001 -p 7001:7001 -e spring.profiles.active=prod -e MAIN_DB_HOST=localhost:3306 -e MAIN_DB_PASSWORD=root -e MAIN_DB_PASSWORD=root --name wu-lazy-cloud-heartbeat-server-start registry.cn-hangzhou.aliyuncs.com/wu-lazy/wu-lazy-cloud-heartbeat-server-start:1.3.1-JDK24
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 操作步骤:杭州本地机房所在网络服务器启动客户端、你老家所在网络中启动客户端,命令如下
|
||||||
|
```shell
|
||||||
|
docker run -d -it --privileged --name hangzhou-client --restart=always -e spring.lazy.netty.client.inet-host=公网IP -e spring.lazy.netty.client.inet-port=7001 -e spring.lazy.netty.client.client-id="hangzhou-jifang" registry.cn-hangzhou.aliyuncs.com/wu-lazy/wu-lazy-cloud-heartbeat-client-start:1.3.1-JDK24
|
||||||
|
```
|
||||||
|
```shell
|
||||||
|
docker run -d -it --privileged --name my-home-client --restart=always -e spring.lazy.netty.client.inet-host=公网IP -e spring.lazy.netty.client.inet-port=7001 -e spring.lazy.netty.client.client-id="my-home" registry.cn-hangzhou.aliyuncs.com/wu-lazy/wu-lazy-cloud-heartbeat-client-start:1.3.1-JDK24
|
||||||
|
```
|
||||||
|
#### 操作步骤:配置端口
|
||||||
|

|
||||||
|
#### 操作步骤:打开页面配置菜单看到如下界面(源客户端ID:你老家网络中的电脑,目标客户端ID)
|
||||||
|

|
||||||
|
|
||||||
|
#### 连接使用:在你老家使用my-home这个客户端所在机器上的ip+13306 即可访问杭州机房内的数据库的服务3306
|
||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
#### 模块说明
|
#### 模块说明
|
||||||
|
|
||||||
| 模块 | 所属层级 | 描述 | 端口 |
|
| 模块 | 所属层级 | 描述 | 端口 |
|
||||||
|------------------------------------------------------------------------------------|------|------------------------|----------------------------------------------------------------|
|
|------------------------------------------------------------------|------|------------------------|----------------------------------------------------------------|
|
||||||
| [wu-lazy-cloud-heartbeat-common](wu-lazy-cloud-heartbeat-common) | 基础模块 | 基于Netty数据解码、编码、通道处理器声明 | 无 |
|
| [wu-lazy-cloud-heartbeat-common](wu-lazy-cloud-heartbeat-common) | 基础模块 | 基于Netty数据解码、编码、通道处理器声明 | 无 |
|
||||||
| [wu-lazy-cloud-heartbeat-server](wu-lazy-cloud-heartbeat-server) | 启动模块 | 内网穿透服务端 | http端口:6001、tcp端口:7001 (默认tcp端口=http端口+1000 如:6001+1000=7001) |
|
| [wu-lazy-cloud-heartbeat-server](wu-lazy-cloud-heartbeat-server) | 启动模块 | 内网穿透服务端 | http端口:6001、tcp端口:7001 (默认tcp端口=http端口+1000 如:6001+1000=7001) |
|
||||||
| [wu-lazy-cloud-heartbeat-client](wu-lazy-cloud-heartbeat-client) | 启动模块 | 内网穿透客户端 | 6004 |
|
| [wu-lazy-cloud-heartbeat-client](wu-lazy-cloud-heartbeat-client) | 启动模块 | 内网穿透客户端 | 6004 |
|
||||||
|
|||||||
61
LazyDNS.puml
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
|
||||||
|
|
||||||
|
@startuml
|
||||||
|
|
||||||
|
title 动态DNS
|
||||||
|
|
||||||
|
actor 访客 as User
|
||||||
|
|
||||||
|
package "服务端(公网)" as dns_server_{
|
||||||
|
component [服务端私有网络A]{
|
||||||
|
[mysql:(172.1.1.4:3306)] as dns_server_remote_local_
|
||||||
|
[clickhouse:(172.1.1.5:3306)]
|
||||||
|
}
|
||||||
|
component [服务端私有网络B]{
|
||||||
|
[mysql:(172.1.2.4:3306)]
|
||||||
|
[clickhouse:(172.1.2.5:3306)]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
package "客户端(私有网络)" as dns_remote_local_{
|
||||||
|
|
||||||
|
component [客户端私有网络A]{
|
||||||
|
[mysql:(162.1.1.4:3306)] as dns_client_remote_local_
|
||||||
|
[clickhouse:(162.1.1.5:3306)]
|
||||||
|
}
|
||||||
|
component [客户端私有网络B]{
|
||||||
|
[mysql:(162.1.2.4:3306)]
|
||||||
|
[clickhouse:(162.1.2.5:3306)]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
package "客户端(用户本地)" as dns_local_ {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
note "用户本地网络" as local_net_
|
||||||
|
note "服务端网络" as server_net_
|
||||||
|
note "客户端私有网络" as remote_net_
|
||||||
|
|
||||||
|
'(User) .... local_condition_
|
||||||
|
'local_condition_ ... (target)
|
||||||
|
|
||||||
|
[User] ...right...> dns_local_: DNS连接到本地
|
||||||
|
dns_local_ ...right...> local_net_: 访问本地网络(本地DNS)
|
||||||
|
dns_local_ ...up...> dns_server_remote_local_: 远程DNS解析
|
||||||
|
|
||||||
|
dns_server_ ...up...> server_net_: server本地的网络
|
||||||
|
dns_server_ ...down...> dns_remote_local_: 访问的地址在远程的客户端中
|
||||||
|
dns_remote_local_ ...down...> dns_client_remote_local_: 远程客户端所在的私有网络
|
||||||
|
dns_remote_local_ ...down...> remote_net_: 远程客户端中的其他网络
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@enduml
|
||||||
|
|
||||||
BIN
Proxies_Config_1.png
Normal file
|
After Width: | Height: | Size: 542 KiB |
BIN
Proxies_Config_2.png
Normal file
|
After Width: | Height: | Size: 528 KiB |
BIN
Proxies_Config_3.png
Normal file
|
After Width: | Height: | Size: 547 KiB |
BIN
Proxies_Config_4.png
Normal file
|
After Width: | Height: | Size: 553 KiB |
BIN
Proxifier3.8.0.dmg
Normal file
33
Proxy.md
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
### 使用手册
|
||||||
|
#### Mac 使用方式
|
||||||
|
##### 获取socks或者http代理服务器信息
|
||||||
|
如:ip:127.0.0.1 port:9001(socks)、8001(http)
|
||||||
|
##### 使用Wi-Fi代理
|
||||||
|
注意如下方式只能代理浏览器请求,无法代理其他应用请求
|
||||||
|

|
||||||
|

|
||||||
|
|
||||||
|
##### 使用第三方软件全局代理[Proxifier3.8.0.dmg](Proxifier3.8.0.dmg)
|
||||||
|
注册码
|
||||||
|
# Proxifier Mac
|
||||||
|
cracked@macked.app
|
||||||
|
8TB85-UWT64-AKK2R-XGBDY-F2UP5
|
||||||
|
# Proxifier Standard Edition
|
||||||
|
cracked@macked.app
|
||||||
|
4JB8X-9YMEZ-BD332-PPNN3-46P48
|
||||||
|
# Proxifier Portable Edition
|
||||||
|
cracked@macked.app
|
||||||
|
FXBZZ-U2FPK-G5KW9-KAANW-TLGPL
|
||||||
|
- Proxifier配置
|
||||||
|

|
||||||
|
- 配置socks服务器地址
|
||||||
|

|
||||||
|

|
||||||
|
- 配置代理路由
|
||||||
|

|
||||||
|
- 展示效果
|
||||||
|

|
||||||
|
|
||||||
|
#### Windows 使用方式
|
||||||
|
##### 使用Wi-Fi代理
|
||||||
|

|
||||||
261
README.md
@@ -14,6 +14,9 @@
|
|||||||
<a target="_blank" href="https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html">
|
<a target="_blank" href="https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html">
|
||||||
<img src="https://img.shields.io/badge/JDK-17-green.svg" alt="jdk-17" />
|
<img src="https://img.shields.io/badge/JDK-17-green.svg" alt="jdk-17" />
|
||||||
</a>
|
</a>
|
||||||
|
<a target="_blank" href="https://www.oracle.com/java/technologies/javase/jdk24-archive-downloads.html">
|
||||||
|
<img src="https://img.shields.io/badge/JDK-24-green.svg" alt="jdk-24" />
|
||||||
|
</a>
|
||||||
<br />
|
<br />
|
||||||
<img src="https://img.shields.io/badge/SpringBoot-v3.x-blue">
|
<img src="https://img.shields.io/badge/SpringBoot-v3.x-blue">
|
||||||
<br />
|
<br />
|
||||||
@@ -30,10 +33,12 @@
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
#### 项目介绍
|
#### 项目介绍
|
||||||
|
[官网](http://wlcn.wu-framework.cn/)
|
||||||
|
[体验地址](http://demo-wlcn.wu-framework.cn/wlcn/index.html#/login)
|
||||||
|
|
||||||
wu-lazy-cloud-network
|
wu-lazy-cloud-network
|
||||||
是一款基于([wu-framework-parent](https://gitee.com/wujiawei1207537021/wu-framework-parent))孵化出的项目,内部使用Lazy
|
是一款基于([wu-framework-parent](https://gitee.com/wujiawei1207537021/wu-framework-parent))孵化出的项目,内部使用Lazy
|
||||||
ORM操作数据库,使用环境JDK17 Spring Boot 3.0.2。
|
ORM操作数据库,使用环境JDK24 Spring Boot 3.5.0。的网络穿透、渗透工具支持Tcp、Http、Socks
|
||||||
主要功能:
|
主要功能:
|
||||||
- 服务端渗透客户端(网络穿透),对于没有公网IP的服务进行公网IP映射
|
- 服务端渗透客户端(网络穿透),对于没有公网IP的服务进行公网IP映射
|
||||||
- 
|
- 
|
||||||
@@ -43,10 +48,23 @@ ORM操作数据库,使用环境JDK17 Spring Boot 3.0.2。
|
|||||||
- 
|
- 
|
||||||
- 客户端渗透客户端----本地端口映射到另一个局域网端口
|
- 客户端渗透客户端----本地端口映射到另一个局域网端口
|
||||||
- 
|
- 
|
||||||
|
- 客户端代理服务端、客户端代理客户端、服务端代理服务端、服务端代理客户端(VPN)----异地组网搭建代理
|
||||||
|
- 
|
||||||
|
|
||||||
[UI](https://gitee.com/wujiawei1207537021/wu-lazy-cloud-network-server-ui)
|
[UI](https://gitee.com/wujiawei1207537021/wu-lazy-cloud-network-server-ui)
|
||||||
|
|
||||||
|
|
||||||
|
### 内网穿透
|
||||||
|
|
||||||
|
| 模块 | 所属层级 | 描述 | 快照版本 | 发布版本 |
|
||||||
|
|--------------------------------------|------|------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
|
| wu-lazy-cloud-heartbeat-common | 组件 | 内网穿透公共模块(声明接口、枚举、常量、适配器、解析器) | <a target="_blank" href="https://search.maven.org/search?q=wu-lazy-cloud-heartbeat-common%20wu-bionic-parent"><img src="https://img.shields.io/nexus/s/top.wu2020/wu-bionic-parent?server=https%3A%2F%2Foss.sonatype.org&style=flat&logo=log" alt="Maven" /></a> | <a target="_blank" href="https://search.maven.org/search?q=wu-lazy-cloud-heartbeat-common%20wu-lazy-cloud-heartbeat-common"><img src="https://img.shields.io/maven-central/v/top.wu2020/wu-lazy-cloud-heartbeat-common" alt="Maven" /></a> |
|
||||||
|
| wu-lazy-cloud-heartbeat-client | 组件 | 客户端(支持二次开发) | <a target="_blank" href="https://search.maven.org/search?q=wu-lazy-cloud-heartbeat-client%20wu-lazy-cloud-heartbeat-client"><img src="https://img.shields.io/nexus/s/top.wu2020/wu-lazy-cloud-heartbeat-client?server=https%3A%2F%2Foss.sonatype.org&style=flat&logo=log" alt="Maven" /></a> | <a target="_blank" href="https://search.maven.org/search?q=wu-lazy-cloud-heartbeat-client%20wu-lazy-cloud-heartbeat-client"><img src="https://img.shields.io/maven-central/v/top.wu2020/wu-lazy-cloud-heartbeat-client" alt="Maven" /></a> |
|
||||||
|
| wu-lazy-cloud-heartbeat-server | 组件 | 服务端(支持二次开发) | <a target="_blank" href="https://search.maven.org/search?q=wu-lazy-cloud-heartbeat-server%20wu-lazy-cloud-heartbeat-server"><img src="https://img.shields.io/nexus/s/top.wu2020/wu-lazy-cloud-heartbeat-server?server=https%3A%2F%2Foss.sonatype.org&style=flat&logo=log" alt="Maven" /></a> | <a target="_blank" href="https://search.maven.org/search?q=wu-lazy-cloud-heartbeat-server%20wu-lazy-cloud-heartbeat-server"><img src="https://img.shields.io/maven-central/v/top.wu2020/wu-lazy-cloud-heartbeat-server" alt="Maven" /></a> |
|
||||||
|
| wu-lazy-cloud-ui | ui | 服务端页面 | | |
|
||||||
|
| wu-lazy-cloud-heartbeat-client-start | 客户端 | 客户端 | <a target="_blank" href="https://search.maven.org/search?q=wu-lazy-cloud-heartbeat-client-start%20wu-lazy-cloud-heartbeat-client-start"><img src="https://img.shields.io/nexus/s/top.wu2020/wu-lazy-cloud-heartbeat-client-start?server=https%3A%2F%2Foss.sonatype.org&style=flat&logo=log" alt="Maven" /></a> | <a target="_blank" href="https://search.maven.org/search?q=wu-lazy-cloud-heartbeat-client-start%20wu-lazy-cloud-heartbeat-client-start"><img src="https://img.shields.io/maven-central/v/top.wu2020/wu-lazy-cloud-heartbeat-client-start" alt="Maven" /></a> |
|
||||||
|
| wu-lazy-cloud-heartbeat-server-start | 服务端 | 服务端 | <a target="_blank" href="https://search.maven.org/search?q=wu-lazy-cloud-heartbeat-server-start%20wu-lazy-cloud-heartbeat-server-start"><img src="https://img.shields.io/nexus/s/top.wu2020/wu-lazy-cloud-heartbeat-server-start?server=https%3A%2F%2Foss.sonatype.org&style=flat&logo=log" alt="Maven" /></a> | <a target="_blank" href="https://search.maven.org/search?q=wu-lazy-cloud-heartbeat-server-start%20wu-lazy-cloud-heartbeat-server-start"><img src="https://img.shields.io/maven-central/v/top.wu2020/wu-lazy-cloud-heartbeat-server-start" alt="Maven" /></a> |
|
||||||
|
|
||||||
#### 项目地址
|
#### 项目地址
|
||||||
|
|
||||||
[Gitee](https://gitee.com/wujiawei1207537021/wu-lazy-cloud-network)
|
[Gitee](https://gitee.com/wujiawei1207537021/wu-lazy-cloud-network)
|
||||||
@@ -57,191 +75,6 @@ ORM操作数据库,使用环境JDK17 Spring Boot 3.0.2。
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
#### 实现原理
|
|
||||||
|
|
||||||
##### 服务端创建socket服务端绑定本地端口(用于客户端连接)
|
|
||||||
|
|
||||||
```java
|
|
||||||
package org.framework.lazy.cloud.network.heartbeat.server.netty.socket;
|
|
||||||
|
|
||||||
|
|
||||||
import io.netty.bootstrap.ServerBootstrap;
|
|
||||||
import io.netty.channel.ChannelFuture;
|
|
||||||
import io.netty.channel.ChannelFutureListener;
|
|
||||||
import io.netty.channel.ChannelOption;
|
|
||||||
import io.netty.channel.EventLoopGroup;
|
|
||||||
import io.netty.channel.nio.NioEventLoopGroup;
|
|
||||||
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
|
||||||
import filter.netty.org.framework.lazy.cloud.network.heartbeat.server.NettyServerFilter;
|
|
||||||
|
|
||||||
public class NettyOnCloudNettyServerSocket {
|
|
||||||
private final EventLoopGroup bossGroup = new NioEventLoopGroup();
|
|
||||||
private final EventLoopGroup workerGroup = new NioEventLoopGroup();
|
|
||||||
private final NettyServerFilter nettyServerFilter;// 通道业务处理
|
|
||||||
private ChannelFuture channelFuture;
|
|
||||||
|
|
||||||
public NettyOnCloudNettyServerSocket(NettyServerFilter nettyServerFilter) {
|
|
||||||
this.nettyServerFilter = nettyServerFilter;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 启动服务端
|
|
||||||
*
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
public void startServer(int serverPort) throws Exception {
|
|
||||||
try {
|
|
||||||
|
|
||||||
ServerBootstrap b = new ServerBootstrap();
|
|
||||||
b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
|
|
||||||
// 给服务端channel设置属性
|
|
||||||
.option(ChannelOption.SO_BACKLOG, 128)
|
|
||||||
|
|
||||||
.childOption(ChannelOption.SO_KEEPALIVE, true)
|
|
||||||
.childHandler(nettyServerFilter)
|
|
||||||
;
|
|
||||||
channelFuture = b.bind(serverPort).sync();
|
|
||||||
|
|
||||||
channelFuture.addListener((ChannelFutureListener) channelFuture -> {
|
|
||||||
// 服务器已启动
|
|
||||||
});
|
|
||||||
channelFuture.channel().closeFuture().sync();
|
|
||||||
} finally {
|
|
||||||
shutdown();
|
|
||||||
// 服务器已关闭
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void shutdown() {
|
|
||||||
if (channelFuture != null) {
|
|
||||||
channelFuture.channel().close().syncUninterruptibly();
|
|
||||||
}
|
|
||||||
if ((bossGroup != null) && (!bossGroup.isShutdown())) {
|
|
||||||
bossGroup.shutdownGracefully();
|
|
||||||
}
|
|
||||||
if ((workerGroup != null) && (!workerGroup.isShutdown())) {
|
|
||||||
workerGroup.shutdownGracefully();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
##### 客户端通过class NettyClientSocket 连接服务端
|
|
||||||
|
|
||||||
```java
|
|
||||||
package org.framework.lazy.cloud.network.heartbeat.client.netty.socket;
|
|
||||||
|
|
||||||
|
|
||||||
import io.netty.bootstrap.Bootstrap;
|
|
||||||
import io.netty.channel.Channel;
|
|
||||||
import io.netty.channel.ChannelFuture;
|
|
||||||
import io.netty.channel.ChannelFutureListener;
|
|
||||||
import io.netty.channel.EventLoopGroup;
|
|
||||||
import io.netty.channel.nio.NioEventLoopGroup;
|
|
||||||
import io.netty.channel.socket.nio.NioSocketChannel;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.client.application.ClientChangeEvent;
|
|
||||||
import filter.netty.org.framework.lazy.cloud.heartbeat.client.NettyClientFilter;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.MessageType;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.NettyProxyMsg;
|
|
||||||
import adapter.org.framework.lazy.cloud.network.heartbeat.common.ChannelTypeAdapter;
|
|
||||||
import advanced.org.framework.lazy.cloud.network.heartbeat.common.HandleChannelTypeAdvanced;
|
|
||||||
import utils.org.framework.lazy.cloud.network.heartbeat.common.ChannelAttributeKeyUtils;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 客户端连接服务端
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
public class NettyClientSocket {
|
|
||||||
private static final EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
|
|
||||||
/**
|
|
||||||
* 服务端host
|
|
||||||
*/
|
|
||||||
private final String inetHost;
|
|
||||||
/**
|
|
||||||
* 服务端端口
|
|
||||||
*/
|
|
||||||
private final int inetPort;
|
|
||||||
/**
|
|
||||||
* 当前客户端id
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
private final String clientId;
|
|
||||||
/**
|
|
||||||
* nacos配置信息处理应用
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
private final ClientNettyConfigApplication clientChangeEvent;
|
|
||||||
private final List<HandleChannelTypeAdvanced> handleChannelTypeAdvancedList; // 处理服务端发送过来的数据类型
|
|
||||||
|
|
||||||
public NettyClientSocket(String inetHost, int inetPort, String clientId, ClientNettyConfigApplication clientChangeEvent, List<HandleChannelTypeAdvanced> handleChannelTypeAdvancedList) {
|
|
||||||
this.inetHost = inetHost;
|
|
||||||
this.inetPort = inetPort;
|
|
||||||
this.clientId = clientId;
|
|
||||||
this.clientChangeEvent = clientChangeEvent;
|
|
||||||
this.handleChannelTypeAdvancedList = handleChannelTypeAdvancedList;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void newConnect2Server() throws InterruptedException {
|
|
||||||
newConnect2Server(inetHost, inetPort, clientId, clientChangeEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void newConnect2Server(String inetHost, int inetPort, String clientId, ClientNettyConfigApplication clientChangeEvent) throws InterruptedException {
|
|
||||||
Bootstrap bootstrap = new Bootstrap();
|
|
||||||
bootstrap.group(eventLoopGroup)
|
|
||||||
.channel(NioSocketChannel.class)
|
|
||||||
.handler(new NettyClientFilter(new ChannelTypeAdapter(handleChannelTypeAdvancedList), this))
|
|
||||||
;
|
|
||||||
|
|
||||||
log.info("连接服务端IP:{},连接服务端端口:{}", inetHost, inetPort);
|
|
||||||
ChannelFuture future = bootstrap.connect(inetHost, inetPort);
|
|
||||||
Channel channel = future.channel();
|
|
||||||
|
|
||||||
log.info("使用的客户端ID:" + clientId);
|
|
||||||
future.addListener((ChannelFutureListener) futureListener -> {
|
|
||||||
if (futureListener.isSuccess()) {
|
|
||||||
|
|
||||||
log.info("连接服务端成功");
|
|
||||||
// 告诉服务端这条连接是client的连接
|
|
||||||
NettyProxyMsg nettyMsg = new NettyProxyMsg();
|
|
||||||
nettyMsg.setType(MessageType.REPORT_CLIENT_CONNECT_SUCCESS);
|
|
||||||
nettyMsg.setClientId(clientId);
|
|
||||||
nettyMsg.setData((clientId).getBytes());
|
|
||||||
ChannelAttributeKeyUtils.buildClientId(channel, clientId);
|
|
||||||
channel.writeAndFlush(nettyMsg);
|
|
||||||
// 在线
|
|
||||||
clientChangeEvent.clientOnLine(clientId);
|
|
||||||
} else {
|
|
||||||
log.info("每隔2s重连....");
|
|
||||||
// 离线
|
|
||||||
clientChangeEvent.clientOffLine(clientId);
|
|
||||||
futureListener.channel().eventLoop().schedule(() -> {
|
|
||||||
try {
|
|
||||||
newConnect2Server(inetHost, inetPort, clientId, clientChangeEvent);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}, 2, TimeUnit.SECONDS);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 关闭连接
|
|
||||||
*/
|
|
||||||
|
|
||||||
public void shutdown() {
|
|
||||||
if ((eventLoopGroup != null) && (!eventLoopGroup.isShutdown())) {
|
|
||||||
eventLoopGroup.shutdownGracefully();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
##### 通过客户端与服务端建立的连接进行访客端口绑定
|
##### 通过客户端与服务端建立的连接进行访客端口绑定
|
||||||
|
|
||||||
@@ -255,43 +88,45 @@ public class NettyClientSocket {
|
|||||||
1.内网穿透
|
1.内网穿透
|
||||||
2.服务端自主下发数据到客户端
|
2.服务端自主下发数据到客户端
|
||||||
3.流量监控
|
3.流量监控
|
||||||
|
4.网络代理(socks、http)
|
||||||
|
|
||||||
### 项目结构
|
### 项目结构
|
||||||
|
|
||||||
| 模块 | 版本 | 描述 |
|
| 模块 | 版本 | 描述 |
|
||||||
|------------------------------------------------------------------------------------------------------------|----------------------|------------------------------|
|
|------------------------------------------------------------------------------------------------------------|-------------|------------------------------|
|
||||||
| [wu-lazy-cloud-heartbeat-common](wu-lazy-cloud-heartbeat-common) | 1.2.8-JDK17-SNAPSHOT | 内网穿透公共模块(声明接口、枚举、常量、适配器、解析器) |
|
| [wu-lazy-cloud-heartbeat-common](wu-lazy-cloud-heartbeat-common) | 1.3.1-JDK24 | 内网穿透公共模块(声明接口、枚举、常量、适配器、解析器) |
|
||||||
| [wu-lazy-cloud-heartbeat-client](wu-lazy-cloud-heartbeat-client) | 1.2.8-JDK17-SNAPSHOT | 客户端(支持二次开发) |
|
| [wu-lazy-cloud-heartbeat-client](wu-lazy-cloud-heartbeat-client) | 1.3.1-JDK24 | 客户端(支持二次开发) |
|
||||||
| [wu-lazy-cloud-heartbeat-server](wu-lazy-cloud-heartbeat-server) | 1.2.8-JDK17-SNAPSHOT | 服务端(支持二次开发) |
|
| [wu-lazy-cloud-heartbeat-server](wu-lazy-cloud-heartbeat-server) | 1.3.1-JDK24 | 服务端(支持二次开发) |
|
||||||
| [wu-lazy-cloud-heartbeat-client-start](wu-lazy-cloud-heartbeat-start/wu-lazy-cloud-heartbeat-server-start) | 1.2.8-JDK17-SNAPSHOT | 客户端样例 |
|
| [wu-lazy-cloud-heartbeat-client-start](wu-lazy-cloud-heartbeat-start/wu-lazy-cloud-heartbeat-server-start) | 1.3.1-JDK24 | 客户端样例 |
|
||||||
| [wu-lazy-cloud-heartbeat-server-start](wu-lazy-cloud-heartbeat-start/wu-lazy-cloud-heartbeat-client-start) | 1.2.8-JDK17-SNAPSHOT | 服务端样例 |
|
| [wu-lazy-cloud-heartbeat-server-start](wu-lazy-cloud-heartbeat-start/wu-lazy-cloud-heartbeat-client-start) | 1.3.1-JDK24 | 服务端样例 |
|
||||||
|
|
||||||
### 使用技术
|
### 使用技术
|
||||||
|
|
||||||
| 框架 | 版本 | 描述 |
|
| 框架 | 版本 | 描述 |
|
||||||
|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------|--------------|
|
|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------|--------------|
|
||||||
| spring-boot | 3.0.7 | springboot框架 |
|
| spring-boot | 3.0.7 | springboot框架 |
|
||||||
| [wu-framework-web](https://gitee.com/wujiawei1207537021/wu-framework-parent/tree/master/wu-framework-web) | 1.2.8-JDK17-SNAPSHOT | web容器 |
|
| [wu-framework-web](https://gitee.com/wujiawei1207537021/wu-framework-parent/tree/master/wu-framework-web) | 1.3.1-JDK24 | web容器 |
|
||||||
| [Lazy -ORM](https://gitee.com/wujiawei1207537021/wu-framework-parent/tree/master/wu-inner-intergration/wu-database-parent) | 1.2.8-JDK17-SNAPSHOT | ORM |
|
| [Lazy -ORM](https://gitee.com/wujiawei1207537021/wu-framework-parent/tree/master/wu-inner-intergration/wu-database-parent) | 1.3.1-JDK24 | ORM |
|
||||||
| mysql-connector-j | 8.0.33 | mysql驱动 |
|
| mysql-connector-j | 8.0.33 | mysql驱动 |
|
||||||
| [wu-authorization-server-platform-starter](https://gitee.com/wujiawei1207537021/wu-framework-parent/tree/master/wu-smart-platform/wu-authorization-server-platform-starter) | 1.2.8-JDK17-SNAPSHOT | 用户授权体系 |
|
| [wu-authorization-server-platform-starter](https://gitee.com/wujiawei1207537021/wu-framework-parent/tree/master/wu-smart-platform/wu-authorization-server-platform-starter) | 1.3.1-JDK24 | 用户授权体系 |
|
||||||
|
|
||||||
### 使用环境
|
### 使用环境
|
||||||
|
|
||||||
IDEA
|
IDEA
|
||||||
Mac、Windows
|
Mac、Windows
|
||||||
JAVA >=13
|
JAVA >=17
|
||||||
MAVEN
|
MAVEN
|
||||||
|
|
||||||
### 启动
|
### 启动[install.md](install.md)
|
||||||
|
|
||||||
docker启动
|
docker启动
|
||||||
|
|
||||||
docker run -d -it -p 18080:18080 --name wu-lazy-cloud-heartbeat-server registry.cn-hangzhou.aliyuncs.com/wu-lazy/wu-lazy-cloud-heartbeat-server:1.2.8-JDK17-SNAPSHOT
|
docker run -d -it -p 18080:18080 --name wu-lazy-cloud-heartbeat-server registry.cn-hangzhou.aliyuncs.com/wu-lazy/wu-lazy-cloud-heartbeat-server:1.3.1-JDK24
|
||||||
|
|
||||||
http://127.0.0.1:18080/swagger-ui/index.html
|
http://127.0.0.1:18080/swagger-ui/index.html
|
||||||
|
|
||||||
源码启动
|
源码启动
|
||||||
|
### 代理工具使用[Proxy.md](Proxy.md)
|
||||||
|
|
||||||
#### 页面操作
|
#### 页面操作
|
||||||
|
|
||||||
@@ -341,4 +176,20 @@ public class NettyClientSocket {
|
|||||||

|

|
||||||
|
|
||||||
客户端近七天使用流量
|
客户端近七天使用流量
|
||||||

|

|
||||||
|
|
||||||
|
## 路由
|
||||||
|
- 客户端路由管理
|
||||||
|

|
||||||
|
- 客户端虚拟路由管理
|
||||||
|
- 创建一个虚拟的不存在的IP,代理到指定的IP
|
||||||
|

|
||||||
|
|
||||||
|
- 服务端路由管理
|
||||||
|

|
||||||
|
- 服务端虚拟路由管理
|
||||||
|
- 创建一个虚拟的不存在的IP,代理到指定的IP
|
||||||
|

|
||||||
|
-
|
||||||
|
- 代理流量管理
|
||||||
|

|
||||||
489
client-k8s.yaml
Normal file
@@ -0,0 +1,489 @@
|
|||||||
|
|
||||||
|
---
|
||||||
|
kind: Deployment
|
||||||
|
apiVersion: apps/v1
|
||||||
|
metadata:
|
||||||
|
name: wu-lazy-cloud-heartbeat-local-client-start
|
||||||
|
namespace: default
|
||||||
|
labels:
|
||||||
|
k8s.kuboard.cn/layer: monitor
|
||||||
|
k8s.kuboard.cn/name: wu-lazy-cloud-heartbeat-local-client-start
|
||||||
|
annotations:
|
||||||
|
k8s.kuboard.cn/displayName: 内网穿透服务端(云下)
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
k8s.kuboard.cn/layer: monitor
|
||||||
|
k8s.kuboard.cn/name: wu-lazy-cloud-heartbeat-local-client-start
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
creationTimestamp: null
|
||||||
|
labels:
|
||||||
|
k8s.kuboard.cn/layer: monitor
|
||||||
|
k8s.kuboard.cn/name: wu-lazy-cloud-heartbeat-local-client-start
|
||||||
|
annotations:
|
||||||
|
kubectl.kubernetes.io/restartedAt: '2025-01-16T22:39:39+08:00'
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: wu-lazy-cloud-heartbeat-local-client-start
|
||||||
|
image: >-
|
||||||
|
registry.cn-hangzhou.aliyuncs.com/wu-lazy/wu-lazy-cloud-heartbeat-client-start:1.3.1-JDK24
|
||||||
|
env:
|
||||||
|
- name: spring.lazy.netty.client.inet-host
|
||||||
|
value: 124.222.48.62
|
||||||
|
- name: spring.lazy.netty.client.inet-port
|
||||||
|
value: '30560'
|
||||||
|
- name: spring.lazy.netty.client.client-id
|
||||||
|
value: tencent
|
||||||
|
- name: JAVA_OPTS
|
||||||
|
value: '-Xms32m -Xmx64m'
|
||||||
|
- name: logging1.level.root
|
||||||
|
value: DEBUG
|
||||||
|
resources: {}
|
||||||
|
terminationMessagePath: /dev/termination-log
|
||||||
|
terminationMessagePolicy: File
|
||||||
|
imagePullPolicy: Always
|
||||||
|
securityContext:
|
||||||
|
privileged: true
|
||||||
|
runAsUser: 0
|
||||||
|
restartPolicy: Always
|
||||||
|
terminationGracePeriodSeconds: 30
|
||||||
|
dnsPolicy: ClusterFirst
|
||||||
|
securityContext: {}
|
||||||
|
schedulerName: default-scheduler
|
||||||
|
strategy:
|
||||||
|
type: RollingUpdate
|
||||||
|
rollingUpdate:
|
||||||
|
maxUnavailable: 25%
|
||||||
|
maxSurge: 25%
|
||||||
|
revisionHistoryLimit: 10
|
||||||
|
progressDeadlineSeconds: 600
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: StatefulSet
|
||||||
|
apiVersion: apps/v1
|
||||||
|
metadata:
|
||||||
|
name: cloud-mysql
|
||||||
|
namespace: default
|
||||||
|
labels:
|
||||||
|
k8s.eip.work/layer: db
|
||||||
|
k8s.eip.work/name: cloud-mysql
|
||||||
|
k8s.kuboard.cn/name: cloud-mysql
|
||||||
|
annotations:
|
||||||
|
analysis.crane.io/replicas-recommendation: |
|
||||||
|
replicas: 1
|
||||||
|
analysis.crane.io/resource-recommendation: |
|
||||||
|
containers:
|
||||||
|
- containerName: mysql
|
||||||
|
target:
|
||||||
|
cpu: 229m
|
||||||
|
memory: 2070Mi
|
||||||
|
k8s.eip.work/displayName: 数据库
|
||||||
|
k8s.eip.work/ingress: 'false'
|
||||||
|
k8s.eip.work/service: NodePort
|
||||||
|
k8s.eip.work/workload: cloud-mysql
|
||||||
|
k8s.kuboard.cn/workload: cloud-mysql
|
||||||
|
spec:
|
||||||
|
replicas: 0
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
k8s.eip.work/layer: db
|
||||||
|
k8s.eip.work/name: cloud-mysql
|
||||||
|
k8s.kuboard.cn/name: cloud-mysql
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
creationTimestamp: null
|
||||||
|
labels:
|
||||||
|
k8s.eip.work/layer: db
|
||||||
|
k8s.eip.work/name: cloud-mysql
|
||||||
|
k8s.kuboard.cn/name: cloud-mysql
|
||||||
|
annotations:
|
||||||
|
kubectl.kubernetes.io/restartedAt: '2023-10-07T09:38:51+08:00'
|
||||||
|
spec:
|
||||||
|
volumes:
|
||||||
|
- name: mysql-cnf-map
|
||||||
|
configMap:
|
||||||
|
name: mysql-cnf
|
||||||
|
items:
|
||||||
|
- key: cnf
|
||||||
|
path: custom.cnf
|
||||||
|
defaultMode: 420
|
||||||
|
- name: tz
|
||||||
|
hostPath:
|
||||||
|
path: /usr/share/zoneinfo/Asia/Shanghai
|
||||||
|
type: File
|
||||||
|
containers:
|
||||||
|
- name: mysql
|
||||||
|
image: 'mysql:8.0.28'
|
||||||
|
env:
|
||||||
|
- name: MYSQL_ROOT_PASSWORD
|
||||||
|
value: wujiawei
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpu: 500m
|
||||||
|
memory: 256Mi
|
||||||
|
requests:
|
||||||
|
cpu: 500m
|
||||||
|
memory: 256Mi
|
||||||
|
volumeMounts:
|
||||||
|
- name: mysql-data
|
||||||
|
mountPath: /var/lib/mysql
|
||||||
|
- name: mysql-cnf-map
|
||||||
|
mountPath: /etc/mysql/conf.d/custom.cnf
|
||||||
|
subPath: custom.cnf
|
||||||
|
- name: tz
|
||||||
|
mountPath: /etc/localtime
|
||||||
|
terminationMessagePath: /dev/termination-log
|
||||||
|
terminationMessagePolicy: File
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
restartPolicy: Always
|
||||||
|
terminationGracePeriodSeconds: 30
|
||||||
|
dnsPolicy: ClusterFirst
|
||||||
|
securityContext: {}
|
||||||
|
schedulerName: default-scheduler
|
||||||
|
volumeClaimTemplates:
|
||||||
|
- kind: PersistentVolumeClaim
|
||||||
|
apiVersion: v1
|
||||||
|
metadata:
|
||||||
|
name: mysql-data
|
||||||
|
creationTimestamp: null
|
||||||
|
annotations:
|
||||||
|
k8s.eip.work/pvcType: Dynamic
|
||||||
|
spec:
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteMany
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: 10Gi
|
||||||
|
storageClassName: nfs-storage
|
||||||
|
volumeMode: Filesystem
|
||||||
|
status:
|
||||||
|
phase: Pending
|
||||||
|
serviceName: cloud-mysql
|
||||||
|
podManagementPolicy: OrderedReady
|
||||||
|
updateStrategy:
|
||||||
|
type: RollingUpdate
|
||||||
|
rollingUpdate:
|
||||||
|
partition: 0
|
||||||
|
revisionHistoryLimit: 10
|
||||||
|
persistentVolumeClaimRetentionPolicy:
|
||||||
|
whenDeleted: Retain
|
||||||
|
whenScaled: Retain
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: Service
|
||||||
|
apiVersion: v1
|
||||||
|
metadata:
|
||||||
|
name: cloud-mysql
|
||||||
|
namespace: default
|
||||||
|
labels:
|
||||||
|
k8s.eip.work/layer: db
|
||||||
|
k8s.eip.work/name: cloud-mysql
|
||||||
|
k8s.kuboard.cn/name: cloud-mysql
|
||||||
|
spec:
|
||||||
|
ports:
|
||||||
|
- name: zmac2s
|
||||||
|
protocol: TCP
|
||||||
|
port: 3306
|
||||||
|
targetPort: 3306
|
||||||
|
nodePort: 30512
|
||||||
|
selector:
|
||||||
|
k8s.eip.work/layer: db
|
||||||
|
k8s.eip.work/name: cloud-mysql
|
||||||
|
type: NodePort
|
||||||
|
sessionAffinity: None
|
||||||
|
externalTrafficPolicy: Cluster
|
||||||
|
ipFamilies:
|
||||||
|
- IPv4
|
||||||
|
ipFamilyPolicy: SingleStack
|
||||||
|
internalTrafficPolicy: Cluster
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: Service
|
||||||
|
apiVersion: v1
|
||||||
|
metadata:
|
||||||
|
name: wu-lazy-cloud-heartbeat-local-client-start
|
||||||
|
namespace: default
|
||||||
|
labels:
|
||||||
|
k8s.kuboard.cn/layer: monitor
|
||||||
|
k8s.kuboard.cn/name: wu-lazy-cloud-heartbeat-local-client-start
|
||||||
|
spec:
|
||||||
|
ports:
|
||||||
|
- name: net
|
||||||
|
protocol: TCP
|
||||||
|
port: 6001
|
||||||
|
targetPort: 6001
|
||||||
|
- name: nas
|
||||||
|
protocol: TCP
|
||||||
|
port: 100
|
||||||
|
targetPort: 100
|
||||||
|
- name: kuboard
|
||||||
|
protocol: TCP
|
||||||
|
port: 101
|
||||||
|
targetPort: 101
|
||||||
|
- name: netty-client
|
||||||
|
protocol: TCP
|
||||||
|
port: 6004
|
||||||
|
targetPort: 6004
|
||||||
|
- name: nas-web-dav
|
||||||
|
protocol: TCP
|
||||||
|
port: 102
|
||||||
|
targetPort: 102
|
||||||
|
- name: rustdesk
|
||||||
|
protocol: TCP
|
||||||
|
port: 103
|
||||||
|
targetPort: 103
|
||||||
|
- name: nastool
|
||||||
|
protocol: TCP
|
||||||
|
port: 104
|
||||||
|
targetPort: 104
|
||||||
|
- name: jellyfin
|
||||||
|
protocol: TCP
|
||||||
|
port: 105
|
||||||
|
targetPort: 105
|
||||||
|
- name: qb
|
||||||
|
protocol: TCP
|
||||||
|
port: 106
|
||||||
|
targetPort: 106
|
||||||
|
- name: jackett
|
||||||
|
protocol: TCP
|
||||||
|
port: 107
|
||||||
|
targetPort: 107
|
||||||
|
- name: rustdesk-tcp
|
||||||
|
protocol: TCP
|
||||||
|
port: 108
|
||||||
|
targetPort: 108
|
||||||
|
- name: rustdesk-ip-tcp
|
||||||
|
protocol: TCP
|
||||||
|
port: 109
|
||||||
|
targetPort: 109
|
||||||
|
- name: rustdesk-ip-udp
|
||||||
|
protocol: UDP
|
||||||
|
port: 109
|
||||||
|
targetPort: 109
|
||||||
|
- name: nas-ssh
|
||||||
|
protocol: TCP
|
||||||
|
port: 110
|
||||||
|
targetPort: 110
|
||||||
|
selector:
|
||||||
|
k8s.kuboard.cn/layer: monitor
|
||||||
|
k8s.kuboard.cn/name: wu-lazy-cloud-heartbeat-local-client-start
|
||||||
|
type: ClusterIP
|
||||||
|
sessionAffinity: None
|
||||||
|
ipFamilies:
|
||||||
|
- IPv4
|
||||||
|
ipFamilyPolicy: SingleStack
|
||||||
|
internalTrafficPolicy: Cluster
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: Ingress
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
metadata:
|
||||||
|
name: wu-lazy-cloud-heartbeat-local-client-start
|
||||||
|
namespace: default
|
||||||
|
labels:
|
||||||
|
k8s.kuboard.cn/layer: monitor
|
||||||
|
k8s.kuboard.cn/name: wu-lazy-cloud-heartbeat-local-client-start
|
||||||
|
spec:
|
||||||
|
ingressClassName: traefik
|
||||||
|
rules:
|
||||||
|
- host: net.wu-framework.cn
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: wu-lazy-cloud-heartbeat-local-client-start
|
||||||
|
port:
|
||||||
|
number: 6001
|
||||||
|
- host: nas.wu-framework.cn
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: wu-lazy-cloud-heartbeat-local-client-start
|
||||||
|
port:
|
||||||
|
number: 100
|
||||||
|
- host: kuboard.wu-framework.cn
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: wu-lazy-cloud-heartbeat-local-client-start
|
||||||
|
port:
|
||||||
|
number: 101
|
||||||
|
- host: client.wu-framework.cn
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: wu-lazy-cloud-heartbeat-local-client-start
|
||||||
|
port:
|
||||||
|
number: 6004
|
||||||
|
- host: nas-dav.wu-framework.cn
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: wu-lazy-cloud-heartbeat-local-client-start
|
||||||
|
port:
|
||||||
|
number: 102
|
||||||
|
- host: rustdesk.wu-framework.cn
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: wu-lazy-cloud-heartbeat-local-client-start
|
||||||
|
port:
|
||||||
|
number: 103
|
||||||
|
- host: nastool.wu-framework.cn
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: wu-lazy-cloud-heartbeat-local-client-start
|
||||||
|
port:
|
||||||
|
number: 104
|
||||||
|
- host: jellyfin.wu-framework.cn
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: wu-lazy-cloud-heartbeat-local-client-start
|
||||||
|
port:
|
||||||
|
number: 105
|
||||||
|
- host: qb.wu-framework.cn
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: wu-lazy-cloud-heartbeat-local-client-start
|
||||||
|
port:
|
||||||
|
number: 106
|
||||||
|
- host: jackett.wu-framework.cn
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: wu-lazy-cloud-heartbeat-local-client-start
|
||||||
|
port:
|
||||||
|
number: 107
|
||||||
|
- host: rustdesk-tcp.wu-framework.cn
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: wu-lazy-cloud-heartbeat-local-client-start
|
||||||
|
port:
|
||||||
|
number: 108
|
||||||
|
- host: rustdesk-ip.wu-framework.cn
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: wu-lazy-cloud-heartbeat-local-client-start
|
||||||
|
port:
|
||||||
|
number: 109
|
||||||
|
- host: nas-ssh.wu-framework.cn
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: wu-lazy-cloud-heartbeat-local-client-start
|
||||||
|
port:
|
||||||
|
number: 110
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: ConfigMap
|
||||||
|
apiVersion: v1
|
||||||
|
metadata:
|
||||||
|
name: mysql-cnf
|
||||||
|
namespace: default
|
||||||
|
data:
|
||||||
|
cnf: >-
|
||||||
|
[mysql]
|
||||||
|
|
||||||
|
no-auto-rehash
|
||||||
|
|
||||||
|
[mysqld]
|
||||||
|
|
||||||
|
skip-host-cache
|
||||||
|
|
||||||
|
skip-name-resolve
|
||||||
|
|
||||||
|
max_connections=100
|
||||||
|
|
||||||
|
lower_case_table_names=0
|
||||||
|
|
||||||
|
table_open_cache=64
|
||||||
|
|
||||||
|
default-time-zone='+08:00'
|
||||||
|
|
||||||
|
sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'
|
||||||
|
|
||||||
|
log_timestamps='SYSTEM'
|
||||||
|
|
||||||
|
performance_schema_max_table_instances=400 #设置效果不明显
|
||||||
|
|
||||||
|
performance_schema=off #效果明显
|
||||||
|
|
||||||
|
table_definition_cache=400
|
||||||
|
|
||||||
|
slow_query_log=ON
|
||||||
|
|
||||||
|
binlog_expire_logs_seconds = 2
|
||||||
|
|
||||||
|
innodb_flush_log_at_trx_commit=2
|
||||||
|
|
||||||
|
group_concat_max_len=512
|
||||||
|
|
||||||
|
# 全局参数
|
||||||
|
|
||||||
|
innodb_buffer_pool_size = 20M
|
||||||
|
|
||||||
|
innodb_buffer_pool_chunk_size=20M #效果不明显
|
||||||
|
|
||||||
|
key_buffer_size = 1M
|
||||||
|
|
||||||
|
# 排序和连接参数
|
||||||
|
|
||||||
|
sort_buffer_size = 256K
|
||||||
|
|
||||||
|
join_buffer_size = 256K
|
||||||
|
|
||||||
|
# 线程缓存参数
|
||||||
|
|
||||||
|
thread_cache_size = 4
|
||||||
|
|
||||||
|
# 日志参数
|
||||||
|
|
||||||
|
innodb_log_file_size = 5M
|
||||||
|
|
||||||
|
innodb_log_buffer_size = 1M
|
||||||
|
|
||||||
|
Before Width: | Height: | Size: 115 KiB After Width: | Height: | Size: 130 KiB |
|
Before Width: | Height: | Size: 90 KiB After Width: | Height: | Size: 114 KiB |
BIN
client_proxy_flow_manager.png
Normal file
|
After Width: | Height: | Size: 206 KiB |
BIN
client_route.png
Normal file
|
After Width: | Height: | Size: 108 KiB |
BIN
client_virtual_route.png
Normal file
|
After Width: | Height: | Size: 115 KiB |
31
install.md
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
#### docker环境安装wlcn
|
||||||
|
|
||||||
|
##### 启动服务端
|
||||||
|
- 6001端口 webui
|
||||||
|
- 7001端口 tcp连接端口
|
||||||
|
- 8001端口 http代理端口
|
||||||
|
- 9001端口 socks代理端口
|
||||||
|
- 1001端口 自定义需要代理到客户端端口
|
||||||
|
- 打开浏览器访问界面 http://127.0.0.1:6001/netty-server-ui/index.html
|
||||||
|
|
||||||
|
|
||||||
|
```shell
|
||||||
|
|
||||||
|
docker run -d -it -p 6001:6001 -p 7001:7001 -p 8001:8001 -p 9001:9001 --name wlcn-s registry.cn-hangzhou.aliyuncs.com/wu-lazy/wu-lazy-cloud-heartbeat-server:1.3.1-JDK24
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
##### 启动客户端
|
||||||
|
|
||||||
|
- 6004端口 webui
|
||||||
|
- 8001端口 http代理端口
|
||||||
|
- 9001端口 socks代理端口
|
||||||
|
- 环境变量
|
||||||
|
- spring.lazy.netty.client.inet-host 服务端IP
|
||||||
|
- spring.lazy.netty.client.inet-port 服务端tcp端口
|
||||||
|
- spring.lazy.netty.client.client-id 客户端ID
|
||||||
|
- 打开浏览器访问界面 http://127.0.0.1:6004/netty-client-local-ui/index.html
|
||||||
|
|
||||||
|
```shell
|
||||||
|
docker run -d -it --privileged -p 6004:6004 --name wlcn-c --restart=always -e spring.lazy.netty.client.inet-host=192.168.xx.xx -e spring.lazy.netty.client.inet-port=7001 -e spring.lazy.netty.client.client-id="wlcn-c" registry.cn-hangzhou.aliyuncs.com/wu-lazy/wu-lazy-cloud-heartbeat-client-start:1.3.1-JDK24
|
||||||
|
```
|
||||||
BIN
mac_http_proxy.png
Normal file
|
After Width: | Height: | Size: 46 KiB |
BIN
mac_socks_proxy.png
Normal file
|
After Width: | Height: | Size: 46 KiB |
190
pom.xml
@@ -8,14 +8,33 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>wu-framework-parent</artifactId>
|
<artifactId>wu-framework-parent</artifactId>
|
||||||
<groupId>top.wu2020</groupId>
|
<groupId>top.wu2020</groupId>
|
||||||
<version>1.2.8-JDK17-SNAPSHOT</version>
|
<version>1.3.4-JDK24-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>wu-lazy-cloud-network</artifactId>
|
<artifactId>wu-lazy-cloud-network</artifactId>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
<version>1.2.8-JDK17-SNAPSHOT</version>
|
<version>1.3.4-JDK24-SNAPSHOT</version>
|
||||||
<description>云上云下</description>
|
<description>云上云下</description>
|
||||||
|
<name>wlcn项目</name>
|
||||||
|
<url>https://gitee.com/wujiawei1207537021/wu-lazy-cloud-network</url>
|
||||||
|
<!-->开发者的信息<-->
|
||||||
|
<developers>
|
||||||
|
<developer>
|
||||||
|
<name>Jia Wei Wu</name>
|
||||||
|
<email>1207537021@qq.com</email>
|
||||||
|
</developer>
|
||||||
|
</developers>
|
||||||
|
<licenses>
|
||||||
|
<license>
|
||||||
|
<name>Apache License, Version 2.0</name>
|
||||||
|
<url>https://www.apache.org/licenses/LICENSE-2.0</url>
|
||||||
|
<distribution>repo</distribution>
|
||||||
|
</license>
|
||||||
|
</licenses>
|
||||||
|
<!-->项目的版本管理地址<-->
|
||||||
|
<scm>
|
||||||
|
<url>https://gitee.com/wujiawei1207537021/wu-lazy-cloud-network</url>
|
||||||
|
</scm>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
<!-- 云上服务组件 -->
|
<!-- 云上服务组件 -->
|
||||||
@@ -23,6 +42,8 @@
|
|||||||
<module>wu-lazy-cloud-heartbeat-server-cluster</module>
|
<module>wu-lazy-cloud-heartbeat-server-cluster</module>
|
||||||
<module>wu-lazy-cloud-heartbeat-client</module>
|
<module>wu-lazy-cloud-heartbeat-client</module>
|
||||||
<module>wu-lazy-cloud-heartbeat-common</module>
|
<module>wu-lazy-cloud-heartbeat-common</module>
|
||||||
|
<module>wu-lazy-cloud-heartbeat-dns</module>
|
||||||
|
<module>wu-lazy-cloud-heartbeat-protocol-proxy</module>
|
||||||
|
|
||||||
<!-- 样例 -->
|
<!-- 样例 -->
|
||||||
<module>wu-lazy-cloud-heartbeat-start</module>
|
<module>wu-lazy-cloud-heartbeat-start</module>
|
||||||
@@ -36,7 +57,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.projectlombok</groupId>
|
<groupId>org.projectlombok</groupId>
|
||||||
<artifactId>lombok</artifactId>
|
<artifactId>lombok</artifactId>
|
||||||
<version>1.18.32</version>
|
<version>1.18.38</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.projectlombok</groupId>
|
<groupId>org.projectlombok</groupId>
|
||||||
@@ -46,22 +67,24 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.mapstruct</groupId>
|
<groupId>org.mapstruct</groupId>
|
||||||
<artifactId>mapstruct</artifactId>
|
<artifactId>mapstruct</artifactId>
|
||||||
<version>1.6.0.Beta1</version>
|
<version>1.6.3</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.mapstruct</groupId>
|
<groupId>org.mapstruct</groupId>
|
||||||
<artifactId>mapstruct-processor</artifactId>
|
<artifactId>mapstruct-processor</artifactId>
|
||||||
<version>1.6.0.Beta1</version>
|
<version>1.6.3</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||||
|
<version>3.5.3</version>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||||
|
<version>${spring-boot-starter.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
@@ -70,7 +93,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>top.wu2020</groupId>
|
<groupId>top.wu2020</groupId>
|
||||||
<artifactId>wu-framework-dependencies</artifactId>
|
<artifactId>wu-framework-dependencies</artifactId>
|
||||||
<version>1.2.8-JDK17-SNAPSHOT</version>
|
<version>1.3.4-JDK24-SNAPSHOT</version>
|
||||||
<type>pom</type>
|
<type>pom</type>
|
||||||
<scope>import</scope>
|
<scope>import</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
@@ -78,159 +101,6 @@
|
|||||||
</dependencyManagement>
|
</dependencyManagement>
|
||||||
|
|
||||||
|
|
||||||
<profiles>
|
|
||||||
<profile>
|
|
||||||
<id>oss</id>
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<!-- Source -->
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-source-plugin</artifactId>
|
|
||||||
<version>3.2.1</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<phase>package</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>jar-no-fork</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
<!-- Javadoc -->
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-javadoc-plugin</artifactId>
|
|
||||||
<version>3.2.0</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<phase>package</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>jar</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<locale>en_US</locale>
|
|
||||||
<encoding>UTF-8</encoding>
|
|
||||||
<charset>UTF-8</charset>
|
|
||||||
<doclint>none</doclint>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
<!-- GPG -->
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-gpg-plugin</artifactId>
|
|
||||||
<version>${maven-gpg-plugin.version}</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<phase>verify</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>sign</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
<!-- flatten -->
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.codehaus.mojo</groupId>
|
|
||||||
<artifactId>flatten-maven-plugin</artifactId>
|
|
||||||
<version>${flatten-maven-plugin.version}</version>
|
|
||||||
<configuration>
|
|
||||||
<updatePomFile>true</updatePomFile>
|
|
||||||
<flattenMode>resolveCiFriendliesOnly</flattenMode>
|
|
||||||
</configuration>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>flatten</id>
|
|
||||||
<phase>process-resources</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>flatten</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
<execution>
|
|
||||||
<id>flatten.clean</id>
|
|
||||||
<phase>clean</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>clean</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
<!-->发布的地址<-->
|
|
||||||
<distributionManagement>
|
|
||||||
<snapshotRepository>
|
|
||||||
<id>oss-snapshots</id>
|
|
||||||
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
|
|
||||||
</snapshotRepository>
|
|
||||||
<repository>
|
|
||||||
<id>oss-snapshots</id>
|
|
||||||
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
|
|
||||||
</repository>
|
|
||||||
</distributionManagement>
|
|
||||||
</profile>
|
|
||||||
|
|
||||||
|
|
||||||
<profile>
|
|
||||||
<id>native</id>
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.graalvm.buildtools</groupId>
|
|
||||||
<artifactId>native-maven-plugin</artifactId>
|
|
||||||
<version>0.9.28</version>
|
|
||||||
<!-- 使用graalvm提供的可达性元数据,很多第三方库就直接可以构建成可执行文件了 -->
|
|
||||||
<configuration>
|
|
||||||
<!-- for agent -->
|
|
||||||
<agent>
|
|
||||||
<defaultMode>Standard</defaultMode>
|
|
||||||
<options>
|
|
||||||
<builtinCallerFilter>true</builtinCallerFilter>
|
|
||||||
<builtinHeuristicFilter>true</builtinHeuristicFilter>
|
|
||||||
<enableExperimentalPredefinedClasses>true
|
|
||||||
</enableExperimentalPredefinedClasses>
|
|
||||||
<enableExperimentalUnsafeAllocationTracing>true
|
|
||||||
</enableExperimentalUnsafeAllocationTracing>
|
|
||||||
<trackReflectionMetadata>true</trackReflectionMetadata>
|
|
||||||
</options>
|
|
||||||
<metadataCopy>
|
|
||||||
<merge>true</merge>
|
|
||||||
</metadataCopy>
|
|
||||||
</agent>
|
|
||||||
<!-- for metadata repository -->
|
|
||||||
<metadataRepository>
|
|
||||||
<enabled>true</enabled>
|
|
||||||
</metadataRepository>
|
|
||||||
</configuration>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>add-reachability-metadata</id>
|
|
||||||
<goals>
|
|
||||||
<goal>add-reachability-metadata</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
<execution>
|
|
||||||
<id>test-native</id>
|
|
||||||
<goals>
|
|
||||||
<goal>test</goal>
|
|
||||||
</goals>
|
|
||||||
<phase>test</phase>
|
|
||||||
</execution>
|
|
||||||
<execution>
|
|
||||||
<id>build-native</id>
|
|
||||||
<goals>
|
|
||||||
<goal>compile-no-fork</goal>
|
|
||||||
</goals>
|
|
||||||
<phase>package</phase>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
</profile>
|
|
||||||
</profiles>
|
|
||||||
|
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
BIN
proxy_inner_net_ui.png
Normal file
|
After Width: | Height: | Size: 71 KiB |
BIN
server_route.png
Normal file
|
After Width: | Height: | Size: 122 KiB |
BIN
server_virtual_route.png
Normal file
|
After Width: | Height: | Size: 119 KiB |
25
version.md
@@ -24,5 +24,28 @@
|
|||||||
[change] 新增服务端渗透服务端----本地同局域网内端口映射
|
[change] 新增服务端渗透服务端----本地同局域网内端口映射
|
||||||
[change] 新增客户端渗透服务端----本地端口映射到另一个服务端中的局域网端口
|
[change] 新增客户端渗透服务端----本地端口映射到另一个服务端中的局域网端口
|
||||||
[change] 新增客户端渗透客户端----本地端口映射到另一个局域网端口
|
[change] 新增客户端渗透客户端----本地端口映射到另一个局域网端口
|
||||||
|
#### 1.2.9-JDK17-SNAPSHOT
|
||||||
|
[change] 添加appkey&appsecret 验证
|
||||||
|
[change] 支持同一个客户端ID多次注册
|
||||||
|
[change] 修复通道关闭导致调度线程池submit异常问题
|
||||||
|
[change] 添加记录客户端IP
|
||||||
|
[change] 1.2.9为大版本,报文中添加数据无法向下兼容,建议服务端与客户端保持版本一致
|
||||||
|
#### 1.3.1-JDK17-SNAPSHOT
|
||||||
|
[add] 新增http代理(客户端代理服务端、客户端代理客户杜安、服务端代理客户端、服务端代理服务端)
|
||||||
|
[add] 新增socks代理(客户端代理服务端、客户端代理客户杜安、服务端代理客户端、服务端代理服务端)
|
||||||
|
[add] 新增客户端路由管理、新增服务端路由管理
|
||||||
|
[add] 支持新增虚拟IP,代理到指定的IP
|
||||||
|
[add] 通过页面配置,代理支持控制端口代理控制
|
||||||
|
#### 1.3.1-JDK17
|
||||||
|
[add] 新增代理流量监控
|
||||||
|
[add] docker仓库上架dockerhub,搜索https://hub.docker.com/search?q=wlcn
|
||||||
|
|
||||||
#### 下一版本计划https
|
#### 1.3.2-JDK24
|
||||||
|
[add] 新增代理请求日志、代理返回日志 通过配置:spring.lazy.netty.protocol.proxy.enableProxyLog=true
|
||||||
|
[add] 升级使用jdk24、springboot 3.5.0
|
||||||
|
[add] 添加socks授权验证。通过配置:spring.lazy.netty.protocol.proxy.authentication=true
|
||||||
|
|
||||||
|
#### 1.3.3-JDK24
|
||||||
|
[fix] 优化代理日志记录性能影响,支持自定义spring.lazy.netty.protocol.proxy.sendMsgQueue、sendMsgQueue
|
||||||
|
[add] 服务上架dockerhub
|
||||||
|
#### 下一版本计划
|
||||||
12
website/BuildDocker.md
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
### 构建docker镜像
|
||||||
|
|
||||||
|
|
||||||
|
```shell
|
||||||
|
|
||||||
|
#docker login --username=1207537021@qq.com registry.cn-hangzhou.aliyuncs.com
|
||||||
|
|
||||||
|
|
||||||
|
docker build -t registry.cn-hangzhou.aliyuncs.com/wu-lazy/wlcn-website:1.3.1-JDK24 .
|
||||||
|
docker push registry.cn-hangzhou.aliyuncs.com/wu-lazy/wlcn-website:1.3.1-JDK24
|
||||||
|
|
||||||
|
```
|
||||||
2
website/Dockerfile
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
FROM registry.cn-hangzhou.aliyuncs.com/wu-library/nginx:1.13.0-alpine
|
||||||
|
COPY dist /usr/share/nginx/html/
|
||||||
241
website/README.md
Normal file
@@ -0,0 +1,241 @@
|
|||||||
|
# Wu-Lazy-Cloud-Network 官方网站
|
||||||
|
|
||||||
|
这是 Wu-Lazy-Cloud-Network 项目的官方网站,基于 Vue 3 + Element Plus 构建。
|
||||||
|
|
||||||
|
## 🚀 快速开始
|
||||||
|
|
||||||
|
### 环境要求
|
||||||
|
|
||||||
|
- Node.js 16.0+
|
||||||
|
- npm 8.0+ 或 yarn 1.22+
|
||||||
|
|
||||||
|
### 安装依赖
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 使用 npm
|
||||||
|
npm install
|
||||||
|
|
||||||
|
# 或使用 yarn
|
||||||
|
yarn install
|
||||||
|
```
|
||||||
|
|
||||||
|
### 开发模式
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 启动开发服务器
|
||||||
|
npm run dev
|
||||||
|
|
||||||
|
# 或使用 yarn
|
||||||
|
yarn dev
|
||||||
|
```
|
||||||
|
|
||||||
|
开发服务器将在 `http://localhost:3000` 启动。
|
||||||
|
|
||||||
|
### 构建生产版本
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 构建生产版本
|
||||||
|
npm run build
|
||||||
|
|
||||||
|
# 或使用 yarn
|
||||||
|
yarn build
|
||||||
|
```
|
||||||
|
|
||||||
|
构建文件将输出到 `dist` 目录。
|
||||||
|
|
||||||
|
### 预览生产版本
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 预览生产版本
|
||||||
|
npm run preview
|
||||||
|
|
||||||
|
# 或使用 yarn
|
||||||
|
yarn preview
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📁 项目结构
|
||||||
|
|
||||||
|
```
|
||||||
|
website/
|
||||||
|
├── public/ # 静态资源
|
||||||
|
├── src/
|
||||||
|
│ ├── assets/ # 资源文件
|
||||||
|
│ │ ├── images/ # 图片资源
|
||||||
|
│ │ └── styles/ # 样式文件
|
||||||
|
│ ├── components/ # 公共组件
|
||||||
|
│ │ ├── Header.vue # 头部导航
|
||||||
|
│ │ └── Footer.vue # 底部组件
|
||||||
|
│ ├── router/ # 路由配置
|
||||||
|
│ │ └── index.js
|
||||||
|
│ ├── stores/ # 状态管理
|
||||||
|
│ ├── utils/ # 工具函数
|
||||||
|
│ │ └── index.js
|
||||||
|
│ ├── views/ # 页面组件
|
||||||
|
│ │ ├── Home.vue # 首页
|
||||||
|
│ │ ├── Features.vue # 功能特性
|
||||||
|
│ │ ├── Architecture.vue # 系统架构
|
||||||
|
│ │ ├── Docs.vue # 使用文档
|
||||||
|
│ │ ├── Download.vue # 下载安装
|
||||||
|
│ │ └── About.vue # 关于我们
|
||||||
|
│ ├── App.vue # 根组件
|
||||||
|
│ └── main.js # 入口文件
|
||||||
|
├── index.html # HTML 模板
|
||||||
|
├── package.json # 项目配置
|
||||||
|
├── vite.config.js # Vite 配置
|
||||||
|
└── README.md # 项目说明
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🎨 页面说明
|
||||||
|
|
||||||
|
### 首页 (Home.vue)
|
||||||
|
- 项目介绍和核心功能展示
|
||||||
|
- 技术栈和快速开始指南
|
||||||
|
- 统计数据展示
|
||||||
|
|
||||||
|
### 功能特性 (Features.vue)
|
||||||
|
- 详细的功能介绍
|
||||||
|
- 内网穿透、网络代理、流量监控等功能说明
|
||||||
|
- 安全特性展示
|
||||||
|
|
||||||
|
### 系统架构 (Architecture.vue)
|
||||||
|
- 整体架构图
|
||||||
|
- 模块架构说明
|
||||||
|
- 数据流架构
|
||||||
|
- 技术栈介绍
|
||||||
|
|
||||||
|
### 使用文档 (Docs.vue)
|
||||||
|
- 快速开始指南
|
||||||
|
- 安装部署说明
|
||||||
|
- 配置参数详解
|
||||||
|
- 使用指南和故障排除
|
||||||
|
|
||||||
|
### 下载安装 (Download.vue)
|
||||||
|
- 版本信息
|
||||||
|
- 多种下载方式
|
||||||
|
- 部署指南
|
||||||
|
- 系统要求
|
||||||
|
|
||||||
|
### 关于我们 (About.vue)
|
||||||
|
- 项目背景和核心价值
|
||||||
|
- 开发团队介绍
|
||||||
|
- 技术栈详情
|
||||||
|
- 发展路线图
|
||||||
|
- 联系方式
|
||||||
|
|
||||||
|
## 🛠️ 技术栈
|
||||||
|
|
||||||
|
- **Vue 3**: 渐进式 JavaScript 框架
|
||||||
|
- **Vue Router**: 官方路由管理器
|
||||||
|
- **Pinia**: 状态管理库
|
||||||
|
- **Element Plus**: Vue 3 组件库
|
||||||
|
- **Vite**: 下一代前端构建工具
|
||||||
|
- **SCSS**: CSS 预处理器
|
||||||
|
- **Prism.js**: 代码高亮
|
||||||
|
- **Marked**: Markdown 解析器
|
||||||
|
|
||||||
|
## 🎯 主要功能
|
||||||
|
|
||||||
|
### 响应式设计
|
||||||
|
- 支持桌面端和移动端
|
||||||
|
- 自适应布局
|
||||||
|
- 触摸友好的交互
|
||||||
|
|
||||||
|
### 代码高亮
|
||||||
|
- 支持多种编程语言
|
||||||
|
- 语法高亮显示
|
||||||
|
- 复制代码功能
|
||||||
|
|
||||||
|
### 性能优化
|
||||||
|
- 路由懒加载
|
||||||
|
- 组件按需加载
|
||||||
|
- 图片懒加载
|
||||||
|
- 代码分割
|
||||||
|
|
||||||
|
### SEO 友好
|
||||||
|
- 语义化 HTML
|
||||||
|
- Meta 标签优化
|
||||||
|
- 结构化数据
|
||||||
|
|
||||||
|
## 🔧 开发指南
|
||||||
|
|
||||||
|
### 添加新页面
|
||||||
|
|
||||||
|
1. 在 `src/views/` 目录下创建新的 Vue 组件
|
||||||
|
2. 在 `src/router/index.js` 中添加路由配置
|
||||||
|
3. 在 `src/components/Header.vue` 中添加导航链接
|
||||||
|
|
||||||
|
### 添加新组件
|
||||||
|
|
||||||
|
1. 在 `src/components/` 目录下创建组件
|
||||||
|
2. 在需要使用的页面中导入并使用
|
||||||
|
|
||||||
|
### 样式开发
|
||||||
|
|
||||||
|
- 使用 SCSS 编写样式
|
||||||
|
- 遵循 BEM 命名规范
|
||||||
|
- 使用 CSS 变量管理主题色彩
|
||||||
|
- 响应式设计使用媒体查询
|
||||||
|
|
||||||
|
### 代码规范
|
||||||
|
|
||||||
|
- 使用 ESLint 进行代码检查
|
||||||
|
- 使用 Prettier 进行代码格式化
|
||||||
|
- 遵循 Vue 3 组合式 API 规范
|
||||||
|
- 组件命名使用 PascalCase
|
||||||
|
- 文件名使用 kebab-case
|
||||||
|
|
||||||
|
## 📦 构建部署
|
||||||
|
|
||||||
|
### 构建生产版本
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run build
|
||||||
|
```
|
||||||
|
|
||||||
|
### 部署到静态服务器
|
||||||
|
|
||||||
|
构建完成后,将 `dist` 目录的内容部署到 Web 服务器即可。
|
||||||
|
|
||||||
|
### Docker 部署
|
||||||
|
|
||||||
|
```dockerfile
|
||||||
|
# 使用 nginx 镜像
|
||||||
|
FROM nginx:alpine
|
||||||
|
|
||||||
|
# 复制构建文件
|
||||||
|
COPY dist/ /usr/share/nginx/html/
|
||||||
|
|
||||||
|
# 复制 nginx 配置
|
||||||
|
COPY nginx.conf /etc/nginx/nginx.conf
|
||||||
|
|
||||||
|
# 暴露端口
|
||||||
|
EXPOSE 80
|
||||||
|
|
||||||
|
# 启动 nginx
|
||||||
|
CMD ["nginx", "-g", "daemon off;"]
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🤝 贡献指南
|
||||||
|
|
||||||
|
1. Fork 本仓库
|
||||||
|
2. 创建特性分支 (`git checkout -b feature/AmazingFeature`)
|
||||||
|
3. 提交更改 (`git commit -m 'Add some AmazingFeature'`)
|
||||||
|
4. 推送到分支 (`git push origin feature/AmazingFeature`)
|
||||||
|
5. 打开 Pull Request
|
||||||
|
|
||||||
|
## 📄 许可证
|
||||||
|
|
||||||
|
本项目采用 [Apache License 2.0](LICENSE) 许可证。
|
||||||
|
|
||||||
|
## 📞 联系我们
|
||||||
|
|
||||||
|
- **邮箱**: 1207537021@qq.com
|
||||||
|
- **项目地址**:
|
||||||
|
- [Gitee](https://gitee.com/wujiawei1207537021/wu-lazy-cloud-network)
|
||||||
|
- [GitHub](https://github.com/wujiawei1207537021/wu-lazy-cloud-network)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**版本**: 1.0.0
|
||||||
|
**更新时间**: 2024年12月
|
||||||
|
**维护者**: 吴佳伟
|
||||||
16
website/index.html
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/favicon.ico" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<meta name="description" content="Wu-Lazy-Cloud-Network 是一款基于 Spring Boot 3.5.0 和 JDK 24 开发的高性能网络穿透和代理工具,支持 TCP、HTTP、SOCKS 协议。" />
|
||||||
|
<meta name="keywords" content="内网穿透,网络代理,Spring Boot,Netty,Vue3" />
|
||||||
|
<meta name="author" content="吴佳伟" />
|
||||||
|
<title>Wu-Lazy-Cloud-Network - 高性能网络穿透和代理工具</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<script type="module" src="/src/main.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
42
website/package.json
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"name": "wu-lazy-cloud-network-website",
|
||||||
|
"version": "1.3.1",
|
||||||
|
"description": "Wu-Lazy-Cloud-Network 官方网站",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "vite build",
|
||||||
|
"preview": "vite preview",
|
||||||
|
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@element-plus/icons-vue": "^2.3.1",
|
||||||
|
"@vueuse/core": "^10.7.0",
|
||||||
|
"element-plus": "^2.4.4",
|
||||||
|
"marked": "^9.1.6",
|
||||||
|
"pinia": "^2.1.7",
|
||||||
|
"prismjs": "^1.29.0",
|
||||||
|
"vue": "^3.4.0",
|
||||||
|
"vue-router": "^4.2.5"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@vitejs/plugin-vue": "^4.5.2",
|
||||||
|
"@vue/eslint-config-prettier": "^8.0.0",
|
||||||
|
"eslint": "^8.56.0",
|
||||||
|
"eslint-plugin-vue": "^9.19.2",
|
||||||
|
"prettier": "^3.1.1",
|
||||||
|
"sass": "^1.69.5",
|
||||||
|
"vite": "^5.0.8",
|
||||||
|
"vite-plugin-compression": "^0.5.1"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"vue3",
|
||||||
|
"vite",
|
||||||
|
"element-plus",
|
||||||
|
"wu-lazy-cloud-network",
|
||||||
|
"内网穿透",
|
||||||
|
"网络代理"
|
||||||
|
],
|
||||||
|
"author": "吴佳伟 <1207537021@qq.com>",
|
||||||
|
"license": "Apache-2.0"
|
||||||
|
}
|
||||||
1
website/public/favicon.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><circle cx="16" cy="16" r="14" fill="#409eff"/><path d="M8 16l6 6 10-10" stroke="white" stroke-width="2" fill="none"/></svg>
|
||||||
|
After Width: | Height: | Size: 185 B |
58
website/src/App.vue
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
<template>
|
||||||
|
<div id="app">
|
||||||
|
<router-view />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { onMounted } from 'vue'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
// 页面加载完成后的初始化逻辑
|
||||||
|
console.log('Wu-Lazy-Cloud-Network 官网已加载')
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
#app {
|
||||||
|
font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', '微软雅黑', Arial, sans-serif;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
color: #2c3e50;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
html, body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 滚动条样式
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-track {
|
||||||
|
background: #f1f1f1;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
background: #c1c1c1;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-thumb:hover {
|
||||||
|
background: #a8a8a8;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
417
website/src/assets/styles/components.scss
Normal file
@@ -0,0 +1,417 @@
|
|||||||
|
// 组件样式
|
||||||
|
|
||||||
|
// 按钮样式
|
||||||
|
.btn {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 12px 24px;
|
||||||
|
border-radius: 6px;
|
||||||
|
font-weight: 500;
|
||||||
|
text-decoration: none;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 14px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
transform: translateY(-1px);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.btn-primary {
|
||||||
|
background: var(--primary-color);
|
||||||
|
color: white;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: #337ecc;
|
||||||
|
box-shadow: 0 4px 12px rgba(64, 158, 255, 0.4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.btn-outline {
|
||||||
|
background: transparent;
|
||||||
|
color: var(--primary-color);
|
||||||
|
border: 2px solid var(--primary-color);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: var(--primary-color);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.btn-large {
|
||||||
|
padding: 16px 32px;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.btn-small {
|
||||||
|
padding: 8px 16px;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 卡片样式
|
||||||
|
.card {
|
||||||
|
background: white;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: var(--shadow-light);
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
|
||||||
|
&.card-hover {
|
||||||
|
&:hover {
|
||||||
|
transform: translateY(-4px);
|
||||||
|
box-shadow: var(--shadow-dark);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 代码块样式
|
||||||
|
.code-block {
|
||||||
|
background: #f8f9fa;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 16px;
|
||||||
|
margin: 16px 0;
|
||||||
|
overflow-x: auto;
|
||||||
|
|
||||||
|
pre {
|
||||||
|
margin: 0;
|
||||||
|
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.5;
|
||||||
|
|
||||||
|
code {
|
||||||
|
background: none;
|
||||||
|
padding: 0;
|
||||||
|
border-radius: 0;
|
||||||
|
font-size: inherit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 容器样式
|
||||||
|
.container {
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 20px;
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
padding: 0 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 网格布局
|
||||||
|
.grid {
|
||||||
|
display: grid;
|
||||||
|
gap: 20px;
|
||||||
|
|
||||||
|
&.grid-2 {
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.grid-3 {
|
||||||
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.grid-4 {
|
||||||
|
grid-template-columns: repeat(4, 1fr);
|
||||||
|
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 弹性布局
|
||||||
|
.flex {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
&.flex-center {
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.flex-between {
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.flex-column {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.flex-wrap {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.flex-1 {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 间距工具类
|
||||||
|
.mt-0 { margin-top: 0; }
|
||||||
|
.mt-1 { margin-top: 8px; }
|
||||||
|
.mt-2 { margin-top: 16px; }
|
||||||
|
.mt-3 { margin-top: 24px; }
|
||||||
|
.mt-4 { margin-top: 32px; }
|
||||||
|
.mt-5 { margin-top: 40px; }
|
||||||
|
|
||||||
|
.mb-0 { margin-bottom: 0; }
|
||||||
|
.mb-1 { margin-bottom: 8px; }
|
||||||
|
.mb-2 { margin-bottom: 16px; }
|
||||||
|
.mb-3 { margin-bottom: 24px; }
|
||||||
|
.mb-4 { margin-bottom: 32px; }
|
||||||
|
.mb-5 { margin-bottom: 40px; }
|
||||||
|
|
||||||
|
.ml-0 { margin-left: 0; }
|
||||||
|
.ml-1 { margin-left: 8px; }
|
||||||
|
.ml-2 { margin-left: 16px; }
|
||||||
|
.ml-3 { margin-left: 24px; }
|
||||||
|
.ml-4 { margin-left: 32px; }
|
||||||
|
.ml-5 { margin-left: 40px; }
|
||||||
|
|
||||||
|
.mr-0 { margin-right: 0; }
|
||||||
|
.mr-1 { margin-right: 8px; }
|
||||||
|
.mr-2 { margin-right: 16px; }
|
||||||
|
.mr-3 { margin-right: 24px; }
|
||||||
|
.mr-4 { margin-right: 32px; }
|
||||||
|
.mr-5 { margin-right: 40px; }
|
||||||
|
|
||||||
|
.pt-0 { padding-top: 0; }
|
||||||
|
.pt-1 { padding-top: 8px; }
|
||||||
|
.pt-2 { padding-top: 16px; }
|
||||||
|
.pt-3 { padding-top: 24px; }
|
||||||
|
.pt-4 { padding-top: 32px; }
|
||||||
|
.pt-5 { padding-top: 40px; }
|
||||||
|
|
||||||
|
.pb-0 { padding-bottom: 0; }
|
||||||
|
.pb-1 { padding-bottom: 8px; }
|
||||||
|
.pb-2 { padding-bottom: 16px; }
|
||||||
|
.pb-3 { padding-bottom: 24px; }
|
||||||
|
.pb-4 { padding-bottom: 32px; }
|
||||||
|
.pb-5 { padding-bottom: 40px; }
|
||||||
|
|
||||||
|
.pl-0 { padding-left: 0; }
|
||||||
|
.pl-1 { padding-left: 8px; }
|
||||||
|
.pl-2 { padding-left: 16px; }
|
||||||
|
.pl-3 { padding-left: 24px; }
|
||||||
|
.pl-4 { padding-left: 32px; }
|
||||||
|
.pl-5 { padding-left: 40px; }
|
||||||
|
|
||||||
|
.pr-0 { padding-right: 0; }
|
||||||
|
.pr-1 { padding-right: 8px; }
|
||||||
|
.pr-2 { padding-right: 16px; }
|
||||||
|
.pr-3 { padding-right: 24px; }
|
||||||
|
.pr-4 { padding-right: 32px; }
|
||||||
|
.pr-5 { padding-right: 40px; }
|
||||||
|
|
||||||
|
// 文本工具类
|
||||||
|
.text-center { text-align: center; }
|
||||||
|
.text-left { text-align: left; }
|
||||||
|
.text-right { text-align: right; }
|
||||||
|
|
||||||
|
.text-primary { color: var(--text-primary); }
|
||||||
|
.text-regular { color: var(--text-regular); }
|
||||||
|
.text-secondary { color: var(--text-secondary); }
|
||||||
|
.text-placeholder { color: var(--text-placeholder); }
|
||||||
|
|
||||||
|
.text-success { color: var(--success-color); }
|
||||||
|
.text-warning { color: var(--warning-color); }
|
||||||
|
.text-danger { color: var(--danger-color); }
|
||||||
|
.text-info { color: var(--info-color); }
|
||||||
|
|
||||||
|
.font-bold { font-weight: bold; }
|
||||||
|
.font-normal { font-weight: normal; }
|
||||||
|
.font-light { font-weight: 300; }
|
||||||
|
|
||||||
|
.text-sm { font-size: 12px; }
|
||||||
|
.text-base { font-size: 14px; }
|
||||||
|
.text-lg { font-size: 16px; }
|
||||||
|
.text-xl { font-size: 18px; }
|
||||||
|
.text-2xl { font-size: 20px; }
|
||||||
|
.text-3xl { font-size: 24px; }
|
||||||
|
.text-4xl { font-size: 28px; }
|
||||||
|
|
||||||
|
// 显示工具类
|
||||||
|
.d-none { display: none; }
|
||||||
|
.d-block { display: block; }
|
||||||
|
.d-inline { display: inline; }
|
||||||
|
.d-inline-block { display: inline-block; }
|
||||||
|
.d-flex { display: flex; }
|
||||||
|
.d-grid { display: grid; }
|
||||||
|
|
||||||
|
// 响应式工具类
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.d-md-none { display: none; }
|
||||||
|
.d-md-block { display: block; }
|
||||||
|
.d-md-flex { display: flex; }
|
||||||
|
.d-md-grid { display: grid; }
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
.d-lg-none { display: none; }
|
||||||
|
.d-lg-block { display: block; }
|
||||||
|
.d-lg-flex { display: flex; }
|
||||||
|
.d-lg-grid { display: grid; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// 动画工具类
|
||||||
|
.fade-in {
|
||||||
|
animation: fadeIn 0.5s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slide-up {
|
||||||
|
animation: slideUp 0.5s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slide-down {
|
||||||
|
animation: slideDown 0.5s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fadeIn {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slideUp {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(20px);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slideDown {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(-20px);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加载动画
|
||||||
|
.loading {
|
||||||
|
display: inline-block;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
border: 3px solid rgba(255, 255, 255, 0.3);
|
||||||
|
border-radius: 50%;
|
||||||
|
border-top-color: #fff;
|
||||||
|
animation: spin 1s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes spin {
|
||||||
|
to {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 徽章样式
|
||||||
|
.badge {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 4px 8px;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 500;
|
||||||
|
border-radius: 4px;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
&.badge-primary {
|
||||||
|
background: var(--primary-color);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.badge-success {
|
||||||
|
background: var(--success-color);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.badge-warning {
|
||||||
|
background: var(--warning-color);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.badge-danger {
|
||||||
|
background: var(--danger-color);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.badge-info {
|
||||||
|
background: var(--info-color);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 标签样式
|
||||||
|
.tag {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 4px 12px;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 500;
|
||||||
|
border-radius: 16px;
|
||||||
|
background: var(--background-light);
|
||||||
|
color: var(--text-regular);
|
||||||
|
margin: 2px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: var(--primary-color);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分割线
|
||||||
|
.divider {
|
||||||
|
height: 1px;
|
||||||
|
background: var(--border-light);
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 空状态
|
||||||
|
.empty-state {
|
||||||
|
text-align: center;
|
||||||
|
padding: 40px 20px;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
|
||||||
|
.empty-icon {
|
||||||
|
font-size: 48px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-title {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 500;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-description {
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
}
|
||||||
232
website/src/assets/styles/index.scss
Normal file
@@ -0,0 +1,232 @@
|
|||||||
|
// 引入组件样式
|
||||||
|
//@import './components.scss';
|
||||||
|
|
||||||
|
// 全局样式变量
|
||||||
|
:root {
|
||||||
|
--primary-color: #409eff;
|
||||||
|
--success-color: #67c23a;
|
||||||
|
--warning-color: #e6a23c;
|
||||||
|
--danger-color: #f56c6c;
|
||||||
|
--info-color: #909399;
|
||||||
|
|
||||||
|
--text-primary: #303133;
|
||||||
|
--text-regular: #606266;
|
||||||
|
--text-secondary: #909399;
|
||||||
|
--text-placeholder: #c0c4cc;
|
||||||
|
|
||||||
|
--border-color: #dcdfe6;
|
||||||
|
--border-light: #e4e7ed;
|
||||||
|
--border-lighter: #ebeef5;
|
||||||
|
--border-extra-light: #f2f6fc;
|
||||||
|
|
||||||
|
--background-color: #ffffff;
|
||||||
|
--background-light: #f5f7fa;
|
||||||
|
|
||||||
|
--shadow-light: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||||
|
--shadow-base: 0 2px 4px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.04);
|
||||||
|
--shadow-dark: 0 4px 8px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.04);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 全局样式
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
html, body {
|
||||||
|
height: 100%;
|
||||||
|
font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', '微软雅黑', Arial, sans-serif;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
color: var(--text-primary);
|
||||||
|
background-color: var(--background-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 通用工具类
|
||||||
|
.container {
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-center {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-left {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-right {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-center {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-between {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-column {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 按钮样式
|
||||||
|
.btn {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 12px 24px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 6px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
text-decoration: none;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
|
||||||
|
&.btn-primary {
|
||||||
|
background-color: var(--primary-color);
|
||||||
|
color: white;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: #66b1ff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.btn-outline {
|
||||||
|
background-color: transparent;
|
||||||
|
border: 2px solid var(--primary-color);
|
||||||
|
color: var(--primary-color);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--primary-color);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.btn-large {
|
||||||
|
padding: 16px 32px;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 卡片样式
|
||||||
|
.card {
|
||||||
|
background: white;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: var(--shadow-light);
|
||||||
|
padding: 24px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
&.card-hover {
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
transform: translateY(-4px);
|
||||||
|
box-shadow: var(--shadow-dark);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 标题样式
|
||||||
|
.title {
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
|
||||||
|
&.title-large {
|
||||||
|
font-size: 32px;
|
||||||
|
line-height: 1.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.title-medium {
|
||||||
|
font-size: 24px;
|
||||||
|
line-height: 1.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.title-small {
|
||||||
|
font-size: 18px;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 段落样式
|
||||||
|
.paragraph {
|
||||||
|
line-height: 1.6;
|
||||||
|
color: var(--text-regular);
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 代码块样式
|
||||||
|
.code-block {
|
||||||
|
background-color: #f6f8fa;
|
||||||
|
border: 1px solid var(--border-light);
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 16px;
|
||||||
|
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.5;
|
||||||
|
overflow-x: auto;
|
||||||
|
|
||||||
|
&.code-block-dark {
|
||||||
|
background-color: #2d3748;
|
||||||
|
color: #e2e8f0;
|
||||||
|
border-color: #4a5568;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 响应式设计
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.container {
|
||||||
|
padding: 0 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-large {
|
||||||
|
font-size: 24px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-medium {
|
||||||
|
font-size: 20px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-large {
|
||||||
|
padding: 12px 24px !important;
|
||||||
|
font-size: 14px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 动画效果
|
||||||
|
.fade-enter-active,
|
||||||
|
.fade-leave-active {
|
||||||
|
transition: opacity 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-enter-from,
|
||||||
|
.fade-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slide-up-enter-active,
|
||||||
|
.slide-up-leave-active {
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slide-up-enter-from {
|
||||||
|
transform: translateY(30px);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slide-up-leave-to {
|
||||||
|
transform: translateY(-30px);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
189
website/src/components/Footer.vue
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
<template>
|
||||||
|
<footer class="footer">
|
||||||
|
<div class="container">
|
||||||
|
<div class="footer-content">
|
||||||
|
<div class="footer-section">
|
||||||
|
<h3 class="footer-title">Wu-Lazy-Cloud-Network</h3>
|
||||||
|
<p class="footer-description">
|
||||||
|
基于 Spring Boot 3.5.0 和 JDK 24 开发的高性能网络穿透和代理工具,
|
||||||
|
支持 TCP、HTTP、SOCKS 协议,提供完整的内网穿透、网络代理、流量监控等功能。
|
||||||
|
</p>
|
||||||
|
<div class="footer-social">
|
||||||
|
<a href="https://gitee.com/wujiawei1207537021/wu-lazy-cloud-network" target="_blank" class="social-link">
|
||||||
|
<el-icon><Platform /></el-icon>
|
||||||
|
</a>
|
||||||
|
<a href="https://github.com/wujiawei1207537021/wu-lazy-cloud-network" target="_blank" class="social-link">
|
||||||
|
<el-icon><Platform /></el-icon>
|
||||||
|
</a>
|
||||||
|
<a href="mailto:1207537021@qq.com" class="social-link">
|
||||||
|
<el-icon><Message /></el-icon>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="footer-section">
|
||||||
|
<h4 class="footer-subtitle">功能特性</h4>
|
||||||
|
<ul class="footer-links">
|
||||||
|
<li><router-link to="/features#penetration">内网穿透</router-link></li>
|
||||||
|
<li><router-link to="/features#proxy">网络代理</router-link></li>
|
||||||
|
<li><router-link to="/features#monitor">流量监控</router-link></li>
|
||||||
|
<li><router-link to="/features#route">路由管理</router-link></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="footer-section">
|
||||||
|
<h4 class="footer-subtitle">技术文档</h4>
|
||||||
|
<ul class="footer-links">
|
||||||
|
<li><router-link to="/docs">使用文档</router-link></li>
|
||||||
|
<li><router-link to="/architecture">系统架构</router-link></li>
|
||||||
|
<li><router-link to="/download">下载安装</router-link></li>
|
||||||
|
<li><a href="https://gitee.com/wujiawei1207537021/wu-framework-parent" target="_blank">Lazy ORM</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="footer-section">
|
||||||
|
<h4 class="footer-subtitle">技术支持</h4>
|
||||||
|
<ul class="footer-links">
|
||||||
|
<li><a href="https://gitee.com/wujiawei1207537021/wu-lazy-cloud-network/issues" target="_blank">问题反馈</a></li>
|
||||||
|
<li><a href="https://gitee.com/wujiawei1207537021/wu-lazy-cloud-network/pulls" target="_blank">贡献代码</a></li>
|
||||||
|
<li><a href="mailto:1207537021@qq.com">联系我们</a></li>
|
||||||
|
<li><router-link to="/about">关于我们</router-link></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="footer-bottom">
|
||||||
|
<div class="footer-copyright">
|
||||||
|
<p>© 2024 Wu-Lazy-Cloud-Network. All rights reserved.</p>
|
||||||
|
<p>由 <a href="mailto:1207537021@qq.com">吴佳伟</a> 开发和维护</p>
|
||||||
|
</div>
|
||||||
|
<div class="footer-license">
|
||||||
|
<p>基于 <a href="https://www.apache.org/licenses/LICENSE-2.0" target="_blank">Apache License 2.0</a> 开源协议</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { Platform, Message } from '@element-plus/icons-vue'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.footer {
|
||||||
|
background: var(--background-light);
|
||||||
|
border-top: 1px solid var(--border-light);
|
||||||
|
padding: 60px 0 20px;
|
||||||
|
margin-top: 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-content {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 2fr 1fr 1fr 1fr;
|
||||||
|
gap: 40px;
|
||||||
|
margin-bottom: 40px;
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
gap: 30px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-section {
|
||||||
|
.footer-title {
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-description {
|
||||||
|
color: var(--text-regular);
|
||||||
|
line-height: 1.6;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-subtitle {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-social {
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
|
|
||||||
|
.social-link {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
border-radius: 6px;
|
||||||
|
background: white;
|
||||||
|
color: var(--text-regular);
|
||||||
|
text-decoration: none;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
border: 1px solid var(--border-light);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: var(--primary-color);
|
||||||
|
border-color: var(--primary-color);
|
||||||
|
transform: translateY(-2px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-icon {
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-links {
|
||||||
|
list-style: none;
|
||||||
|
|
||||||
|
li {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: var(--text-regular);
|
||||||
|
text-decoration: none;
|
||||||
|
transition: color 0.3s ease;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: var(--primary-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-bottom {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding-top: 20px;
|
||||||
|
border-top: 1px solid var(--border-light);
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 16px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
color: var(--text-secondary);
|
||||||
|
font-size: 14px;
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: var(--primary-color);
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
215
website/src/components/Header.vue
Normal file
@@ -0,0 +1,215 @@
|
|||||||
|
<template>
|
||||||
|
<header class="header" :class="{ 'header-scrolled': isScrolled }">
|
||||||
|
<div class="container">
|
||||||
|
<div class="header-content">
|
||||||
|
<div class="logo">
|
||||||
|
<router-link to="/" class="logo-link">
|
||||||
|
<el-icon class="logo-icon"><Connection /></el-icon>
|
||||||
|
<span class="logo-text">Wu-Lazy-Cloud-Network</span>
|
||||||
|
</router-link>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<nav class="nav" :class="{ 'nav-mobile': isMobileMenuOpen }">
|
||||||
|
<router-link to="/" class="nav-link" @click="closeMobileMenu">首页</router-link>
|
||||||
|
<router-link to="/features" class="nav-link" @click="closeMobileMenu">功能特性</router-link>
|
||||||
|
<router-link to="/architecture" class="nav-link" @click="closeMobileMenu">系统架构</router-link>
|
||||||
|
<router-link to="/docs" class="nav-link" @click="closeMobileMenu">使用文档</router-link>
|
||||||
|
<router-link to="/download" class="nav-link" @click="closeMobileMenu">下载安装</router-link>
|
||||||
|
<router-link to="/about" class="nav-link" @click="closeMobileMenu">关于我们</router-link>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<div class="header-actions">
|
||||||
|
<a href="https://gitee.com/wujiawei1207537021/wu-lazy-cloud-network" target="_blank" class="btn btn-outline">
|
||||||
|
<el-icon><Platform /></el-icon>
|
||||||
|
Gitee
|
||||||
|
</a>
|
||||||
|
<a href="https://github.com/wujiawei1207537021/wu-lazy-cloud-network" target="_blank" class="btn btn-outline">
|
||||||
|
<el-icon><Platform /></el-icon>
|
||||||
|
GitHub
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mobile-menu-toggle" @click="toggleMobileMenu">
|
||||||
|
<el-icon><Menu /></el-icon>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted, onUnmounted } from 'vue'
|
||||||
|
import { Connection, Platform, Menu } from '@element-plus/icons-vue'
|
||||||
|
|
||||||
|
const isScrolled = ref(false)
|
||||||
|
const isMobileMenuOpen = ref(false)
|
||||||
|
|
||||||
|
const handleScroll = () => {
|
||||||
|
isScrolled.value = window.scrollY > 50
|
||||||
|
}
|
||||||
|
|
||||||
|
const toggleMobileMenu = () => {
|
||||||
|
isMobileMenuOpen.value = !isMobileMenuOpen.value
|
||||||
|
}
|
||||||
|
|
||||||
|
const closeMobileMenu = () => {
|
||||||
|
isMobileMenuOpen.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
window.addEventListener('scroll', handleScroll)
|
||||||
|
})
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
window.removeEventListener('scroll', handleScroll)
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.header {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
z-index: 1000;
|
||||||
|
background: rgba(255, 255, 255, 0.95);
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
border-bottom: 1px solid var(--border-light);
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
|
||||||
|
&.header-scrolled {
|
||||||
|
background: rgba(255, 255, 255, 0.98);
|
||||||
|
box-shadow: var(--shadow-light);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-content {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
height: 70px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
.logo-link {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
text-decoration: none;
|
||||||
|
color: var(--text-primary);
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 18px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: var(--primary-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo-icon {
|
||||||
|
font-size: 24px;
|
||||||
|
color: var(--primary-color);
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo-text {
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 32px;
|
||||||
|
|
||||||
|
.nav-link {
|
||||||
|
text-decoration: none;
|
||||||
|
color: var(--text-regular);
|
||||||
|
font-weight: 500;
|
||||||
|
transition: color 0.3s ease;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&.router-link-active {
|
||||||
|
color: var(--primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.router-link-active::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
bottom: -8px;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
height: 2px;
|
||||||
|
background: var(--primary-color);
|
||||||
|
border-radius: 1px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
position: fixed;
|
||||||
|
top: 70px;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
background: white;
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 20px;
|
||||||
|
gap: 16px;
|
||||||
|
border-bottom: 1px solid var(--border-light);
|
||||||
|
transform: translateY(-100%);
|
||||||
|
opacity: 0;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
|
||||||
|
&.nav-mobile {
|
||||||
|
transform: translateY(0);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-actions {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
padding: 8px 16px;
|
||||||
|
font-size: 14px;
|
||||||
|
|
||||||
|
.el-icon {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-menu-toggle {
|
||||||
|
display: none;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 6px;
|
||||||
|
transition: background-color 0.3s ease;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--background-light);
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-icon {
|
||||||
|
font-size: 20px;
|
||||||
|
color: var(--text-regular);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
BIN
website/src/favicon.ico
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
22
website/src/main.js
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import { createApp } from 'vue'
|
||||||
|
import { createPinia } from 'pinia'
|
||||||
|
import ElementPlus from 'element-plus'
|
||||||
|
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
|
||||||
|
import 'element-plus/dist/index.css'
|
||||||
|
|
||||||
|
import App from './App.vue'
|
||||||
|
import router from './router'
|
||||||
|
import './assets/styles/index.scss'
|
||||||
|
|
||||||
|
const app = createApp(App)
|
||||||
|
|
||||||
|
// 注册 Element Plus 图标
|
||||||
|
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
|
||||||
|
app.component(key, component)
|
||||||
|
}
|
||||||
|
|
||||||
|
app.use(createPinia())
|
||||||
|
app.use(router)
|
||||||
|
app.use(ElementPlus)
|
||||||
|
|
||||||
|
app.mount('#app')
|
||||||
63
website/src/router/index.js
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
import { createRouter, createWebHistory } from 'vue-router'
|
||||||
|
|
||||||
|
const routes = [
|
||||||
|
{
|
||||||
|
path: '/',
|
||||||
|
name: 'Home',
|
||||||
|
component: () => import('@/views/Home.vue'),
|
||||||
|
meta: { title: '首页' }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/features',
|
||||||
|
name: 'Features',
|
||||||
|
component: () => import('@/views/Features.vue'),
|
||||||
|
meta: { title: '功能特性' }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/architecture',
|
||||||
|
name: 'Architecture',
|
||||||
|
component: () => import('@/views/Architecture.vue'),
|
||||||
|
meta: { title: '系统架构' }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/docs',
|
||||||
|
name: 'Docs',
|
||||||
|
component: () => import('@/views/Docs.vue'),
|
||||||
|
meta: { title: '使用文档' }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/download',
|
||||||
|
name: 'Download',
|
||||||
|
component: () => import('@/views/Download.vue'),
|
||||||
|
meta: { title: '下载安装' }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/about',
|
||||||
|
name: 'About',
|
||||||
|
component: () => import('@/views/About.vue'),
|
||||||
|
meta: { title: '关于我们' }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const router = createRouter({
|
||||||
|
history: createWebHistory(),
|
||||||
|
routes,
|
||||||
|
scrollBehavior(to, from, savedPosition) {
|
||||||
|
if (savedPosition) {
|
||||||
|
return savedPosition
|
||||||
|
} else {
|
||||||
|
return { top: 0 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 路由守卫
|
||||||
|
router.beforeEach((to, from, next) => {
|
||||||
|
// 设置页面标题
|
||||||
|
if (to.meta.title) {
|
||||||
|
document.title = `${to.meta.title} - Wu-Lazy-Cloud-Network`
|
||||||
|
}
|
||||||
|
next()
|
||||||
|
})
|
||||||
|
|
||||||
|
export default router
|
||||||
227
website/src/utils/index.js
Normal file
@@ -0,0 +1,227 @@
|
|||||||
|
// 工具函数集合
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 格式化文件大小
|
||||||
|
* @param {number} bytes 字节数
|
||||||
|
* @returns {string} 格式化后的文件大小
|
||||||
|
*/
|
||||||
|
export function formatFileSize(bytes) {
|
||||||
|
if (bytes === 0) return '0 B'
|
||||||
|
|
||||||
|
const k = 1024
|
||||||
|
const sizes = ['B', 'KB', 'MB', 'GB', 'TB']
|
||||||
|
const i = Math.floor(Math.log(bytes) / Math.log(k))
|
||||||
|
|
||||||
|
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 格式化时间
|
||||||
|
* @param {Date|string|number} date 日期
|
||||||
|
* @returns {string} 格式化后的时间
|
||||||
|
*/
|
||||||
|
export function formatDate(date) {
|
||||||
|
const d = new Date(date)
|
||||||
|
return d.toLocaleDateString('zh-CN', {
|
||||||
|
year: 'numeric',
|
||||||
|
month: '2-digit',
|
||||||
|
day: '2-digit',
|
||||||
|
hour: '2-digit',
|
||||||
|
minute: '2-digit',
|
||||||
|
second: '2-digit'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 防抖函数
|
||||||
|
* @param {Function} func 要防抖的函数
|
||||||
|
* @param {number} wait 等待时间
|
||||||
|
* @returns {Function} 防抖后的函数
|
||||||
|
*/
|
||||||
|
export function debounce(func, wait) {
|
||||||
|
let timeout
|
||||||
|
return function executedFunction(...args) {
|
||||||
|
const later = () => {
|
||||||
|
clearTimeout(timeout)
|
||||||
|
func(...args)
|
||||||
|
}
|
||||||
|
clearTimeout(timeout)
|
||||||
|
timeout = setTimeout(later, wait)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 节流函数
|
||||||
|
* @param {Function} func 要节流的函数
|
||||||
|
* @param {number} limit 限制时间
|
||||||
|
* @returns {Function} 节流后的函数
|
||||||
|
*/
|
||||||
|
export function throttle(func, limit) {
|
||||||
|
let inThrottle
|
||||||
|
return function() {
|
||||||
|
const args = arguments
|
||||||
|
const context = this
|
||||||
|
if (!inThrottle) {
|
||||||
|
func.apply(context, args)
|
||||||
|
inThrottle = true
|
||||||
|
setTimeout(() => inThrottle = false, limit)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 复制文本到剪贴板
|
||||||
|
* @param {string} text 要复制的文本
|
||||||
|
* @returns {Promise<boolean>} 是否复制成功
|
||||||
|
*/
|
||||||
|
export async function copyToClipboard(text) {
|
||||||
|
try {
|
||||||
|
await navigator.clipboard.writeText(text)
|
||||||
|
return true
|
||||||
|
} catch (err) {
|
||||||
|
// 降级方案
|
||||||
|
const textArea = document.createElement('textarea')
|
||||||
|
textArea.value = text
|
||||||
|
document.body.appendChild(textArea)
|
||||||
|
textArea.focus()
|
||||||
|
textArea.select()
|
||||||
|
try {
|
||||||
|
document.execCommand('copy')
|
||||||
|
document.body.removeChild(textArea)
|
||||||
|
return true
|
||||||
|
} catch (err) {
|
||||||
|
document.body.removeChild(textArea)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成随机ID
|
||||||
|
* @param {number} length ID长度
|
||||||
|
* @returns {string} 随机ID
|
||||||
|
*/
|
||||||
|
export function generateId(length = 8) {
|
||||||
|
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
|
||||||
|
let result = ''
|
||||||
|
for (let i = 0; i < length; i++) {
|
||||||
|
result += chars.charAt(Math.floor(Math.random() * chars.length))
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查是否为移动设备
|
||||||
|
* @returns {boolean} 是否为移动设备
|
||||||
|
*/
|
||||||
|
export function isMobile() {
|
||||||
|
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取浏览器信息
|
||||||
|
* @returns {object} 浏览器信息
|
||||||
|
*/
|
||||||
|
export function getBrowserInfo() {
|
||||||
|
const ua = navigator.userAgent
|
||||||
|
let browser = 'Unknown'
|
||||||
|
let version = 'Unknown'
|
||||||
|
|
||||||
|
if (ua.includes('Chrome')) {
|
||||||
|
browser = 'Chrome'
|
||||||
|
version = ua.match(/Chrome\/(\d+)/)?.[1] || 'Unknown'
|
||||||
|
} else if (ua.includes('Firefox')) {
|
||||||
|
browser = 'Firefox'
|
||||||
|
version = ua.match(/Firefox\/(\d+)/)?.[1] || 'Unknown'
|
||||||
|
} else if (ua.includes('Safari')) {
|
||||||
|
browser = 'Safari'
|
||||||
|
version = ua.match(/Version\/(\d+)/)?.[1] || 'Unknown'
|
||||||
|
} else if (ua.includes('Edge')) {
|
||||||
|
browser = 'Edge'
|
||||||
|
version = ua.match(/Edge\/(\d+)/)?.[1] || 'Unknown'
|
||||||
|
}
|
||||||
|
|
||||||
|
return { browser, version }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取操作系统信息
|
||||||
|
* @returns {string} 操作系统名称
|
||||||
|
*/
|
||||||
|
export function getOS() {
|
||||||
|
const ua = navigator.userAgent
|
||||||
|
if (ua.includes('Windows')) return 'Windows'
|
||||||
|
if (ua.includes('Mac')) return 'macOS'
|
||||||
|
if (ua.includes('Linux')) return 'Linux'
|
||||||
|
if (ua.includes('Android')) return 'Android'
|
||||||
|
if (ua.includes('iOS')) return 'iOS'
|
||||||
|
return 'Unknown'
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 格式化数字
|
||||||
|
* @param {number} num 数字
|
||||||
|
* @param {number} digits 小数位数
|
||||||
|
* @returns {string} 格式化后的数字
|
||||||
|
*/
|
||||||
|
export function formatNumber(num, digits = 2) {
|
||||||
|
return Number(num).toLocaleString('zh-CN', {
|
||||||
|
minimumFractionDigits: digits,
|
||||||
|
maximumFractionDigits: digits
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证邮箱格式
|
||||||
|
* @param {string} email 邮箱地址
|
||||||
|
* @returns {boolean} 是否为有效邮箱
|
||||||
|
*/
|
||||||
|
export function isValidEmail(email) {
|
||||||
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
|
||||||
|
return emailRegex.test(email)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证URL格式
|
||||||
|
* @param {string} url URL地址
|
||||||
|
* @returns {boolean} 是否为有效URL
|
||||||
|
*/
|
||||||
|
export function isValidURL(url) {
|
||||||
|
try {
|
||||||
|
new URL(url)
|
||||||
|
return true
|
||||||
|
} catch {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取URL参数
|
||||||
|
* @param {string} name 参数名
|
||||||
|
* @returns {string|null} 参数值
|
||||||
|
*/
|
||||||
|
export function getUrlParam(name) {
|
||||||
|
const urlParams = new URLSearchParams(window.location.search)
|
||||||
|
return urlParams.get(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置URL参数
|
||||||
|
* @param {string} name 参数名
|
||||||
|
* @param {string} value 参数值
|
||||||
|
*/
|
||||||
|
export function setUrlParam(name, value) {
|
||||||
|
const url = new URL(window.location)
|
||||||
|
url.searchParams.set(name, value)
|
||||||
|
window.history.replaceState({}, '', url)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 移除URL参数
|
||||||
|
* @param {string} name 参数名
|
||||||
|
*/
|
||||||
|
export function removeUrlParam(name) {
|
||||||
|
const url = new URL(window.location)
|
||||||
|
url.searchParams.delete(name)
|
||||||
|
window.history.replaceState({}, '', url)
|
||||||
|
}
|
||||||
863
website/src/views/About.vue
Normal file
@@ -0,0 +1,863 @@
|
|||||||
|
<template>
|
||||||
|
<div class="about-page">
|
||||||
|
<Header />
|
||||||
|
|
||||||
|
<!-- Hero Section -->
|
||||||
|
<section class="hero">
|
||||||
|
<div class="container">
|
||||||
|
<div class="hero-content">
|
||||||
|
<h1 class="hero-title">关于我们</h1>
|
||||||
|
<p class="hero-subtitle">
|
||||||
|
了解 Wu-Lazy-Cloud-Network 项目的背景、团队和愿景
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Project Introduction -->
|
||||||
|
<section class="project-intro">
|
||||||
|
<div class="container">
|
||||||
|
<div class="section-header">
|
||||||
|
<h2 class="section-title">项目介绍</h2>
|
||||||
|
<p class="section-subtitle">基于现代化技术栈的高性能网络穿透和代理工具</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="intro-content">
|
||||||
|
<div class="intro-text">
|
||||||
|
<h3>项目背景</h3>
|
||||||
|
<p>
|
||||||
|
Wu-Lazy-Cloud-Network 是一个基于 Spring Boot 3.5.0 和 JDK 24 开发的高性能网络穿透和代理工具。
|
||||||
|
项目起源于对现有网络穿透工具的不足之处的思考,旨在提供一个更加稳定、高效、易用的解决方案。
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3>核心价值</h3>
|
||||||
|
<ul>
|
||||||
|
<li><strong>高性能</strong>: 基于 Netty 异步网络框架,支持高并发连接处理</li>
|
||||||
|
<li><strong>易用性</strong>: 提供 Web 管理界面,支持一键部署和配置</li>
|
||||||
|
<li><strong>稳定性</strong>: 采用心跳机制和连接池管理,确保服务稳定运行</li>
|
||||||
|
<li><strong>扩展性</strong>: 模块化设计,支持自定义协议和过滤器</li>
|
||||||
|
<li><strong>安全性</strong>: 支持多种认证机制和加密传输</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h3>技术特色</h3>
|
||||||
|
<ul>
|
||||||
|
<li>基于最新的 JDK 24 和 Spring Boot 3.5.0</li>
|
||||||
|
<li>采用 Netty 高性能网络框架</li>
|
||||||
|
<li>支持多种协议:TCP、HTTP、SOCKS</li>
|
||||||
|
<li>提供完整的流量监控和统计功能</li>
|
||||||
|
<li>支持集群部署和负载均衡</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="intro-stats">
|
||||||
|
<div class="stat-item">
|
||||||
|
<div class="stat-number">1.3.1</div>
|
||||||
|
<div class="stat-label">当前版本</div>
|
||||||
|
</div>
|
||||||
|
<div class="stat-item">
|
||||||
|
<div class="stat-number">10K+</div>
|
||||||
|
<div class="stat-label">并发连接</div>
|
||||||
|
</div>
|
||||||
|
<div class="stat-item">
|
||||||
|
<div class="stat-number">99.9%</div>
|
||||||
|
<div class="stat-label">可用性</div>
|
||||||
|
</div>
|
||||||
|
<div class="stat-item">
|
||||||
|
<div class="stat-number">< 10ms</div>
|
||||||
|
<div class="stat-label">响应时间</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Team -->
|
||||||
|
<section class="team">
|
||||||
|
<div class="container">
|
||||||
|
<div class="section-header">
|
||||||
|
<h2 class="section-title">开发团队</h2>
|
||||||
|
<p class="section-subtitle">专业的开发团队,致力于提供优质的网络解决方案</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="team-content">
|
||||||
|
<div class="team-member">
|
||||||
|
<div class="member-avatar">
|
||||||
|
<el-icon><User /></el-icon>
|
||||||
|
</div>
|
||||||
|
<div class="member-info">
|
||||||
|
<h3>吴佳伟 (Jia Wei Wu)</h3>
|
||||||
|
<p class="member-title">项目负责人 & 主要开发者</p>
|
||||||
|
<p class="member-description">
|
||||||
|
拥有多年 Java 开发经验,专注于高性能网络应用开发。
|
||||||
|
负责项目的整体架构设计、核心功能开发和性能优化。
|
||||||
|
</p>
|
||||||
|
<div class="member-skills">
|
||||||
|
<span class="skill-tag">Java</span>
|
||||||
|
<span class="skill-tag">Spring Boot</span>
|
||||||
|
<span class="skill-tag">Netty</span>
|
||||||
|
<span class="skill-tag">网络编程</span>
|
||||||
|
<span class="skill-tag">系统架构</span>
|
||||||
|
</div>
|
||||||
|
<div class="member-contact">
|
||||||
|
<a href="mailto:1207537021@qq.com" class="contact-link">
|
||||||
|
<el-icon><Message /></el-icon>
|
||||||
|
1207537021@qq.com
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Technology Stack -->
|
||||||
|
<section class="technology-stack">
|
||||||
|
<div class="container">
|
||||||
|
<div class="section-header">
|
||||||
|
<h2 class="section-title">技术栈</h2>
|
||||||
|
<p class="section-subtitle">采用现代化的技术栈,确保高性能和可靠性</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tech-categories">
|
||||||
|
<div class="tech-category">
|
||||||
|
<h3>后端框架</h3>
|
||||||
|
<div class="tech-items">
|
||||||
|
<div class="tech-item">
|
||||||
|
<div class="tech-icon">
|
||||||
|
<el-icon><Monitor /></el-icon>
|
||||||
|
</div>
|
||||||
|
<div class="tech-info">
|
||||||
|
<h4>Spring Boot 3.5.0</h4>
|
||||||
|
<p>现代化的应用框架,提供快速开发和部署能力</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tech-item">
|
||||||
|
<div class="tech-icon">
|
||||||
|
<el-icon><Connection /></el-icon>
|
||||||
|
</div>
|
||||||
|
<div class="tech-info">
|
||||||
|
<h4>Netty</h4>
|
||||||
|
<p>高性能异步网络框架,支持高并发连接处理</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tech-item">
|
||||||
|
<div class="tech-icon">
|
||||||
|
<el-icon><Cpu /></el-icon>
|
||||||
|
</div>
|
||||||
|
<div class="tech-info">
|
||||||
|
<h4>JDK 24</h4>
|
||||||
|
<p>最新的 Java 开发工具包,提供优秀的性能表现</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tech-category">
|
||||||
|
<h3>数据存储</h3>
|
||||||
|
<div class="tech-items">
|
||||||
|
<div class="tech-item">
|
||||||
|
<div class="tech-icon">
|
||||||
|
<el-icon><DataBase /></el-icon>
|
||||||
|
</div>
|
||||||
|
<div class="tech-info">
|
||||||
|
<h4>MySQL 8.0</h4>
|
||||||
|
<p>主数据库,存储配置和监控数据</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tech-item">
|
||||||
|
<div class="tech-icon">
|
||||||
|
<el-icon><DataBase /></el-icon>
|
||||||
|
</div>
|
||||||
|
<div class="tech-info">
|
||||||
|
<h4>H2</h4>
|
||||||
|
<p>开发环境数据库,轻量级嵌入式数据库</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tech-item">
|
||||||
|
<div class="tech-icon">
|
||||||
|
<el-icon><DataBase /></el-icon>
|
||||||
|
</div>
|
||||||
|
<div class="tech-info">
|
||||||
|
<h4>Lazy ORM</h4>
|
||||||
|
<p>轻量级 ORM 框架,提供类型安全的数据库操作</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tech-category">
|
||||||
|
<h3>部署运维</h3>
|
||||||
|
<div class="tech-items">
|
||||||
|
<div class="tech-item">
|
||||||
|
<div class="tech-icon">
|
||||||
|
<el-icon><Box /></el-icon>
|
||||||
|
</div>
|
||||||
|
<div class="tech-info">
|
||||||
|
<h4>Docker</h4>
|
||||||
|
<p>容器化部署,提供一致的运行环境</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tech-item">
|
||||||
|
<div class="tech-icon">
|
||||||
|
<el-icon><Setting /></el-icon>
|
||||||
|
</div>
|
||||||
|
<div class="tech-info">
|
||||||
|
<h4>Maven</h4>
|
||||||
|
<p>构建自动化工具,管理项目依赖</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tech-item">
|
||||||
|
<div class="tech-icon">
|
||||||
|
<el-icon><Monitor /></el-icon>
|
||||||
|
</div>
|
||||||
|
<div class="tech-info">
|
||||||
|
<h4>Spring Boot Actuator</h4>
|
||||||
|
<p>应用监控和管理,提供健康检查和指标</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Roadmap -->
|
||||||
|
<section class="roadmap">
|
||||||
|
<div class="container">
|
||||||
|
<div class="section-header">
|
||||||
|
<h2 class="section-title">发展路线</h2>
|
||||||
|
<p class="section-subtitle">项目的未来发展规划和功能演进</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="roadmap-timeline">
|
||||||
|
<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>
|
||||||
|
<ul>
|
||||||
|
<li>升级到 JDK 24 和 Spring Boot 3.5.0</li>
|
||||||
|
<li>优化网络性能和稳定性</li>
|
||||||
|
<li>增强安全性和认证机制</li>
|
||||||
|
<li>完善文档和部署指南</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="timeline-item current">
|
||||||
|
<div class="timeline-marker"></div>
|
||||||
|
<div class="timeline-content">
|
||||||
|
<h3>v1.4.0 (开发中)</h3>
|
||||||
|
<p class="timeline-date">2025年Q1</p>
|
||||||
|
<ul>
|
||||||
|
<li>支持 WebSocket 协议</li>
|
||||||
|
<li>增强集群管理功能</li>
|
||||||
|
<li>提供 RESTful API</li>
|
||||||
|
<li>优化用户界面体验</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="timeline-item planned">
|
||||||
|
<div class="timeline-marker"></div>
|
||||||
|
<div class="timeline-content">
|
||||||
|
<h3>v2.0.0 (规划中)</h3>
|
||||||
|
<p class="timeline-date">2025年Q2</p>
|
||||||
|
<ul>
|
||||||
|
<li>微服务架构重构</li>
|
||||||
|
<li>支持 Kubernetes 部署</li>
|
||||||
|
<li>提供 SDK 和插件机制</li>
|
||||||
|
<li>增强监控和告警功能</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Contact -->
|
||||||
|
<section class="contact">
|
||||||
|
<div class="container">
|
||||||
|
<div class="section-header">
|
||||||
|
<h2 class="section-title">联系我们</h2>
|
||||||
|
<p class="section-subtitle">欢迎反馈建议、报告问题或参与项目贡献</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="contact-content">
|
||||||
|
<div class="contact-methods">
|
||||||
|
<div class="contact-method">
|
||||||
|
<div class="method-icon">
|
||||||
|
<el-icon><Message /></el-icon>
|
||||||
|
</div>
|
||||||
|
<h3>邮箱联系</h3>
|
||||||
|
<p>通过邮件与我们联系,我们会在24小时内回复</p>
|
||||||
|
<a href="mailto:1207537021@qq.com" class="contact-link">
|
||||||
|
1207537021@qq.com
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="contact-method">
|
||||||
|
<div class="method-icon">
|
||||||
|
<el-icon><Platform /></el-icon>
|
||||||
|
</div>
|
||||||
|
<h3>项目地址</h3>
|
||||||
|
<p>访问项目仓库,查看源码、提交问题或参与贡献</p>
|
||||||
|
<div class="project-links">
|
||||||
|
<a href="https://gitee.com/wujiawei1207537021/wu-lazy-cloud-network" target="_blank" class="contact-link">
|
||||||
|
<el-icon><Platform /></el-icon>
|
||||||
|
Gitee
|
||||||
|
</a>
|
||||||
|
<a href="https://github.com/wujiawei1207537021/wu-lazy-cloud-network" target="_blank" class="contact-link">
|
||||||
|
<el-icon><Platform /></el-icon>
|
||||||
|
GitHub
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="contact-method">
|
||||||
|
<div class="method-icon">
|
||||||
|
<el-icon><Document /></el-icon>
|
||||||
|
</div>
|
||||||
|
<h3>文档支持</h3>
|
||||||
|
<p>查看详细的使用文档、API 文档和开发指南</p>
|
||||||
|
<router-link to="/docs" class="contact-link">
|
||||||
|
<el-icon><Document /></el-icon>
|
||||||
|
查看文档
|
||||||
|
</router-link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- License -->
|
||||||
|
<section class="license">
|
||||||
|
<div class="container">
|
||||||
|
<div class="license-content">
|
||||||
|
<h2>开源许可证</h2>
|
||||||
|
<p>
|
||||||
|
本项目采用 <strong>Apache License 2.0</strong> 开源许可证。
|
||||||
|
您可以自由使用、修改和分发本软件,但需要遵守许可证条款。
|
||||||
|
</p>
|
||||||
|
<div class="license-actions">
|
||||||
|
<a href="https://www.apache.org/licenses/LICENSE-2.0" target="_blank" class="btn btn-outline">
|
||||||
|
<el-icon><Document /></el-icon>
|
||||||
|
查看许可证
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<Footer />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { onMounted } from 'vue'
|
||||||
|
import Header from '@/components/Header.vue'
|
||||||
|
import Footer from '@/components/Footer.vue'
|
||||||
|
import {
|
||||||
|
User,
|
||||||
|
Message,
|
||||||
|
Platform,
|
||||||
|
Document,
|
||||||
|
Monitor,
|
||||||
|
Connection,
|
||||||
|
Cpu,
|
||||||
|
// DataBase,
|
||||||
|
Box,
|
||||||
|
Setting
|
||||||
|
} from '@element-plus/icons-vue'
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
// 页面初始化逻辑
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.about-page {
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hero Section
|
||||||
|
.hero {
|
||||||
|
padding: 120px 0 60px;
|
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
|
color: white;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
.hero-title {
|
||||||
|
font-size: 48px;
|
||||||
|
font-weight: 700;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
font-size: 32px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-subtitle {
|
||||||
|
font-size: 18px;
|
||||||
|
opacity: 0.9;
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Section Header
|
||||||
|
.section-header {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 60px;
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: 36px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 16px;
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
font-size: 28px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-subtitle {
|
||||||
|
font-size: 18px;
|
||||||
|
color: var(--text-regular);
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Project Introduction
|
||||||
|
.project-intro {
|
||||||
|
padding: 80px 0;
|
||||||
|
background: var(--background-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.intro-content {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 2fr 1fr;
|
||||||
|
gap: 60px;
|
||||||
|
align-items: start;
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
gap: 40px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.intro-text {
|
||||||
|
h3 {
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
color: var(--text-regular);
|
||||||
|
line-height: 1.6;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style: none;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
li {
|
||||||
|
color: var(--text-regular);
|
||||||
|
margin-bottom: 8px;
|
||||||
|
position: relative;
|
||||||
|
padding-left: 16px;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: '•';
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
color: var(--primary-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.intro-stats {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
gap: 20px;
|
||||||
|
|
||||||
|
.stat-item {
|
||||||
|
text-align: center;
|
||||||
|
padding: 20px;
|
||||||
|
background: white;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: var(--shadow-light);
|
||||||
|
|
||||||
|
.stat-number {
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: var(--primary-color);
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-label {
|
||||||
|
color: var(--text-regular);
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Team
|
||||||
|
.team {
|
||||||
|
padding: 80px 0;
|
||||||
|
background: var(--background-light);
|
||||||
|
}
|
||||||
|
|
||||||
|
.team-content {
|
||||||
|
max-width: 800px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.team-member {
|
||||||
|
display: flex;
|
||||||
|
gap: 30px;
|
||||||
|
align-items: start;
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
flex-direction: column;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.member-avatar {
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
background: var(--primary-color);
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-shrink: 0;
|
||||||
|
|
||||||
|
.el-icon {
|
||||||
|
font-size: 40px;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.member-info {
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.member-title {
|
||||||
|
color: var(--primary-color);
|
||||||
|
font-weight: 500;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.member-description {
|
||||||
|
color: var(--text-regular);
|
||||||
|
line-height: 1.6;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.member-skills {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 8px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
|
||||||
|
.skill-tag {
|
||||||
|
background: var(--background-light);
|
||||||
|
color: var(--text-regular);
|
||||||
|
padding: 4px 12px;
|
||||||
|
border-radius: 16px;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.member-contact {
|
||||||
|
.contact-link {
|
||||||
|
color: var(--primary-color);
|
||||||
|
text-decoration: none;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Technology Stack
|
||||||
|
.technology-stack {
|
||||||
|
padding: 80px 0;
|
||||||
|
background: var(--background-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tech-categories {
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tech-category {
|
||||||
|
margin-bottom: 60px;
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 30px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tech-items {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
|
||||||
|
gap: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tech-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 16px;
|
||||||
|
padding: 20px;
|
||||||
|
background: white;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: var(--shadow-light);
|
||||||
|
|
||||||
|
.tech-icon {
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
background: var(--primary-color);
|
||||||
|
border-radius: 10px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-shrink: 0;
|
||||||
|
|
||||||
|
.el-icon {
|
||||||
|
font-size: 24px;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tech-info {
|
||||||
|
h4 {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-size: 14px;
|
||||||
|
color: var(--text-regular);
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Roadmap
|
||||||
|
.roadmap {
|
||||||
|
padding: 80px 0;
|
||||||
|
background: var(--background-light);
|
||||||
|
}
|
||||||
|
|
||||||
|
.roadmap-timeline {
|
||||||
|
max-width: 800px;
|
||||||
|
margin: 0 auto;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
left: 20px;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
width: 2px;
|
||||||
|
background: var(--border-light);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-item {
|
||||||
|
position: relative;
|
||||||
|
margin-bottom: 40px;
|
||||||
|
padding-left: 60px;
|
||||||
|
|
||||||
|
.timeline-marker {
|
||||||
|
position: absolute;
|
||||||
|
left: 11px;
|
||||||
|
top: 0;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
border-radius: 50%;
|
||||||
|
border: 3px solid white;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.completed .timeline-marker {
|
||||||
|
background: var(--success-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.current .timeline-marker {
|
||||||
|
background: var(--primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.planned .timeline-marker {
|
||||||
|
background: var(--warning-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-content {
|
||||||
|
background: white;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 20px;
|
||||||
|
box-shadow: var(--shadow-light);
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-date {
|
||||||
|
color: var(--text-regular);
|
||||||
|
font-size: 14px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style: none;
|
||||||
|
|
||||||
|
li {
|
||||||
|
color: var(--text-regular);
|
||||||
|
margin-bottom: 6px;
|
||||||
|
position: relative;
|
||||||
|
padding-left: 16px;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: '•';
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
color: var(--primary-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Contact
|
||||||
|
.contact {
|
||||||
|
padding: 80px 0;
|
||||||
|
background: var(--background-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.contact-methods {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||||
|
gap: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contact-method {
|
||||||
|
text-align: center;
|
||||||
|
padding: 30px;
|
||||||
|
background: white;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: var(--shadow-light);
|
||||||
|
|
||||||
|
.method-icon {
|
||||||
|
width: 60px;
|
||||||
|
height: 60px;
|
||||||
|
background: var(--primary-color);
|
||||||
|
border-radius: 12px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin: 0 auto 20px;
|
||||||
|
|
||||||
|
.el-icon {
|
||||||
|
font-size: 28px;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
color: var(--text-regular);
|
||||||
|
line-height: 1.6;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contact-link {
|
||||||
|
color: var(--primary-color);
|
||||||
|
text-decoration: none;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
font-weight: 500;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.project-links {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// License
|
||||||
|
.license {
|
||||||
|
padding: 60px 0;
|
||||||
|
background: var(--background-light);
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
.license-content {
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 0 auto;
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
color: var(--text-regular);
|
||||||
|
line-height: 1.6;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.license-actions {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
798
website/src/views/Architecture.vue
Normal file
@@ -0,0 +1,798 @@
|
|||||||
|
<template>
|
||||||
|
<div class="architecture-page">
|
||||||
|
<Header />
|
||||||
|
|
||||||
|
<!-- Hero Section -->
|
||||||
|
<section class="hero">
|
||||||
|
<div class="container">
|
||||||
|
<div class="hero-content">
|
||||||
|
<h1 class="hero-title">系统架构</h1>
|
||||||
|
<p class="hero-subtitle">
|
||||||
|
基于现代化的技术栈,采用模块化设计,提供高性能和可靠性
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Architecture Overview -->
|
||||||
|
<section class="architecture-overview">
|
||||||
|
<div class="container">
|
||||||
|
<div class="section-header">
|
||||||
|
<h2 class="section-title">整体架构</h2>
|
||||||
|
<p class="section-subtitle">采用分层架构设计,各模块职责清晰,便于维护和扩展</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="architecture-diagram">
|
||||||
|
<div class="layer application-layer">
|
||||||
|
<h3>应用层</h3>
|
||||||
|
<div class="components">
|
||||||
|
<div class="component">Web UI</div>
|
||||||
|
<div class="component">REST API</div>
|
||||||
|
<div class="component">WebSocket</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="layer business-layer">
|
||||||
|
<h3>业务层</h3>
|
||||||
|
<div class="components">
|
||||||
|
<div class="component">内网穿透</div>
|
||||||
|
<div class="component">网络代理</div>
|
||||||
|
<div class="component">流量监控</div>
|
||||||
|
<div class="component">路由管理</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="layer protocol-layer">
|
||||||
|
<h3>协议层</h3>
|
||||||
|
<div class="components">
|
||||||
|
<div class="component">HTTP 代理</div>
|
||||||
|
<div class="component">SOCKS 代理</div>
|
||||||
|
<div class="component">TCP 协议</div>
|
||||||
|
<div class="component">自定义协议</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="layer communication-layer">
|
||||||
|
<h3>通信层</h3>
|
||||||
|
<div class="components">
|
||||||
|
<div class="component">Netty 框架</div>
|
||||||
|
<div class="component">心跳机制</div>
|
||||||
|
<div class="component">连接池</div>
|
||||||
|
<div class="component">过滤器链</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="layer data-layer">
|
||||||
|
<h3>数据层</h3>
|
||||||
|
<div class="components">
|
||||||
|
<div class="component">MySQL</div>
|
||||||
|
<div class="component">H2</div>
|
||||||
|
<div class="component">Lazy ORM</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Module Architecture -->
|
||||||
|
<section class="module-architecture">
|
||||||
|
<div class="container">
|
||||||
|
<div class="section-header">
|
||||||
|
<h2 class="section-title">模块架构</h2>
|
||||||
|
<p class="section-subtitle">松耦合的模块化设计,支持独立开发和部署</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modules-grid">
|
||||||
|
<div class="module-card">
|
||||||
|
<div class="module-header">
|
||||||
|
<div class="module-icon">
|
||||||
|
<el-icon><Connection /></el-icon>
|
||||||
|
</div>
|
||||||
|
<h3>wu-lazy-cloud-heartbeat-common</h3>
|
||||||
|
</div>
|
||||||
|
<p class="module-description">公共基础模块,提供接口定义、枚举常量、适配器等</p>
|
||||||
|
<div class="module-components">
|
||||||
|
<h4>核心组件</h4>
|
||||||
|
<ul>
|
||||||
|
<li>NettyMsg - 网络消息基类</li>
|
||||||
|
<li>ChannelContext - 通道上下文</li>
|
||||||
|
<li>ProtocolAdapter - 协议适配器</li>
|
||||||
|
<li>NettyUtils - 工具类</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="module-card">
|
||||||
|
<div class="module-header">
|
||||||
|
<div class="module-icon">
|
||||||
|
<el-icon><Server /></el-icon>
|
||||||
|
</div>
|
||||||
|
<h3>wu-lazy-cloud-heartbeat-server</h3>
|
||||||
|
</div>
|
||||||
|
<p class="module-description">服务端核心模块,提供网络服务、客户端管理、端口映射等功能</p>
|
||||||
|
<div class="module-components">
|
||||||
|
<h4>核心组件</h4>
|
||||||
|
<ul>
|
||||||
|
<li>NettyTcpServerSocketApplicationListener</li>
|
||||||
|
<li>LazyServerPermeateServerMappingApplication</li>
|
||||||
|
<li>NettyServerVirtualRouteApplication</li>
|
||||||
|
<li>InitServerSocket</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="module-card">
|
||||||
|
<div class="module-header">
|
||||||
|
<div class="module-icon">
|
||||||
|
<el-icon><Monitor /></el-icon>
|
||||||
|
</div>
|
||||||
|
<h3>wu-lazy-cloud-heartbeat-client</h3>
|
||||||
|
</div>
|
||||||
|
<p class="module-description">客户端核心模块,提供连接管理、本地服务、端口转发等功能</p>
|
||||||
|
<div class="module-components">
|
||||||
|
<h4>核心组件</h4>
|
||||||
|
<ul>
|
||||||
|
<li>NettyClientSocketApplicationListener</li>
|
||||||
|
<li>LazyClientPermeateClientMappingApplication</li>
|
||||||
|
<li>NettyClientVirtualRouteApplication</li>
|
||||||
|
<li>LazyNettyClientApplication</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="module-card">
|
||||||
|
<div class="module-header">
|
||||||
|
<div class="module-icon">
|
||||||
|
<el-icon><Share /></el-icon>
|
||||||
|
</div>
|
||||||
|
<h3>wu-lazy-cloud-heartbeat-protocol-proxy</h3>
|
||||||
|
</div>
|
||||||
|
<p class="module-description">代理协议模块,提供 HTTP 和 SOCKS 代理服务</p>
|
||||||
|
<div class="module-components">
|
||||||
|
<h4>核心组件</h4>
|
||||||
|
<ul>
|
||||||
|
<li>NettyHttpProxySocketApplicationListener</li>
|
||||||
|
<li>NettySocketProxySocketApplicationListener</li>
|
||||||
|
<li>NettyTcpProxyFilter</li>
|
||||||
|
<li>HttpProxyHandler</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Data Flow -->
|
||||||
|
<section class="data-flow">
|
||||||
|
<div class="container">
|
||||||
|
<div class="section-header">
|
||||||
|
<h2 class="section-title">数据流架构</h2>
|
||||||
|
<p class="section-subtitle">清晰的数据流向,支持高效的数据传输和处理</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flow-diagrams">
|
||||||
|
<div class="flow-diagram">
|
||||||
|
<h3>内网穿透数据流</h3>
|
||||||
|
<div class="flow-steps">
|
||||||
|
<div class="flow-step">
|
||||||
|
<div class="step-icon">
|
||||||
|
<el-icon><User /></el-icon>
|
||||||
|
</div>
|
||||||
|
<div class="step-content">
|
||||||
|
<h4>访客请求</h4>
|
||||||
|
<p>外部用户连接到服务端访客端口</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flow-arrow">→</div>
|
||||||
|
|
||||||
|
<div class="flow-step">
|
||||||
|
<div class="step-icon">
|
||||||
|
<el-icon><Server /></el-icon>
|
||||||
|
</div>
|
||||||
|
<div class="step-content">
|
||||||
|
<h4>服务端处理</h4>
|
||||||
|
<p>服务端创建访客通道,通过心跳通道转发数据</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flow-arrow">→</div>
|
||||||
|
|
||||||
|
<div class="flow-step">
|
||||||
|
<div class="step-icon">
|
||||||
|
<el-icon><Monitor /></el-icon>
|
||||||
|
</div>
|
||||||
|
<div class="step-content">
|
||||||
|
<h4>客户端转发</h4>
|
||||||
|
<p>客户端接收数据并转发给本地服务</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flow-arrow">→</div>
|
||||||
|
|
||||||
|
<div class="flow-step">
|
||||||
|
<div class="step-icon">
|
||||||
|
<el-icon><Connection /></el-icon>
|
||||||
|
</div>
|
||||||
|
<div class="step-content">
|
||||||
|
<h4>响应返回</h4>
|
||||||
|
<p>本地服务响应数据,通过心跳通道返回给访客</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flow-diagram">
|
||||||
|
<h3>代理数据流</h3>
|
||||||
|
<div class="flow-steps">
|
||||||
|
<div class="flow-step">
|
||||||
|
<div class="step-icon">
|
||||||
|
<el-icon><Monitor /></el-icon>
|
||||||
|
</div>
|
||||||
|
<div class="step-content">
|
||||||
|
<h4>客户端应用</h4>
|
||||||
|
<p>应用程序发起代理请求</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flow-arrow">→</div>
|
||||||
|
|
||||||
|
<div class="flow-step">
|
||||||
|
<div class="step-icon">
|
||||||
|
<el-icon><Share /></el-icon>
|
||||||
|
</div>
|
||||||
|
<div class="step-content">
|
||||||
|
<h4>代理客户端</h4>
|
||||||
|
<p>代理客户端接收请求并转发</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flow-arrow">→</div>
|
||||||
|
|
||||||
|
<div class="flow-step">
|
||||||
|
<div class="step-icon">
|
||||||
|
<el-icon><Server /></el-icon>
|
||||||
|
</div>
|
||||||
|
<div class="step-content">
|
||||||
|
<h4>代理服务端</h4>
|
||||||
|
<p>代理服务端处理请求并访问目标服务器</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flow-arrow">→</div>
|
||||||
|
|
||||||
|
<div class="flow-step">
|
||||||
|
<div class="step-icon">
|
||||||
|
<el-icon><Globe /></el-icon>
|
||||||
|
</div>
|
||||||
|
<div class="step-content">
|
||||||
|
<h4>目标服务器</h4>
|
||||||
|
<p>目标服务器处理请求并返回响应</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Technology Stack -->
|
||||||
|
<section class="technology-stack">
|
||||||
|
<div class="container">
|
||||||
|
<div class="section-header">
|
||||||
|
<h2 class="section-title">技术栈</h2>
|
||||||
|
<p class="section-subtitle">采用现代化的技术栈,确保高性能和可靠性</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tech-categories">
|
||||||
|
<div class="tech-category">
|
||||||
|
<h3>核心框架</h3>
|
||||||
|
<div class="tech-items">
|
||||||
|
<div class="tech-item">
|
||||||
|
<div class="tech-icon">
|
||||||
|
<el-icon><Monitor /></el-icon>
|
||||||
|
</div>
|
||||||
|
<div class="tech-info">
|
||||||
|
<h4>Spring Boot 3.5.0</h4>
|
||||||
|
<p>现代化的应用框架,提供快速开发和部署能力</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tech-item">
|
||||||
|
<div class="tech-icon">
|
||||||
|
<el-icon><Connection /></el-icon>
|
||||||
|
</div>
|
||||||
|
<div class="tech-info">
|
||||||
|
<h4>Netty</h4>
|
||||||
|
<p>高性能异步网络框架,支持高并发连接处理</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tech-item">
|
||||||
|
<div class="tech-icon">
|
||||||
|
<el-icon><Cpu /></el-icon>
|
||||||
|
</div>
|
||||||
|
<div class="tech-info">
|
||||||
|
<h4>JDK 24</h4>
|
||||||
|
<p>最新的 Java 开发工具包,提供优秀的性能表现</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tech-category">
|
||||||
|
<h3>数据存储</h3>
|
||||||
|
<div class="tech-items">
|
||||||
|
<div class="tech-item">
|
||||||
|
<div class="tech-icon">
|
||||||
|
<el-icon><DataBase /></el-icon>
|
||||||
|
</div>
|
||||||
|
<div class="tech-info">
|
||||||
|
<h4>MySQL 8.0</h4>
|
||||||
|
<p>主数据库,存储配置和监控数据</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tech-item">
|
||||||
|
<div class="tech-icon">
|
||||||
|
<el-icon><DataBase /></el-icon>
|
||||||
|
</div>
|
||||||
|
<div class="tech-info">
|
||||||
|
<h4>H2</h4>
|
||||||
|
<p>开发环境数据库,轻量级嵌入式数据库</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tech-item">
|
||||||
|
<div class="tech-icon">
|
||||||
|
<el-icon><DataBase /></el-icon>
|
||||||
|
</div>
|
||||||
|
<div class="tech-info">
|
||||||
|
<h4>Lazy ORM</h4>
|
||||||
|
<p>轻量级 ORM 框架,提供类型安全的数据库操作</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tech-category">
|
||||||
|
<h3>部署运维</h3>
|
||||||
|
<div class="tech-items">
|
||||||
|
<div class="tech-item">
|
||||||
|
<div class="tech-icon">
|
||||||
|
<el-icon><Box /></el-icon>
|
||||||
|
</div>
|
||||||
|
<div class="tech-info">
|
||||||
|
<h4>Docker</h4>
|
||||||
|
<p>容器化部署,提供一致的运行环境</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tech-item">
|
||||||
|
<div class="tech-icon">
|
||||||
|
<el-icon><Setting /></el-icon>
|
||||||
|
</div>
|
||||||
|
<div class="tech-info">
|
||||||
|
<h4>Maven</h4>
|
||||||
|
<p>构建自动化工具,管理项目依赖</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tech-item">
|
||||||
|
<div class="tech-icon">
|
||||||
|
<el-icon><Monitor /></el-icon>
|
||||||
|
</div>
|
||||||
|
<div class="tech-info">
|
||||||
|
<h4>Spring Boot Actuator</h4>
|
||||||
|
<p>应用监控和管理,提供健康检查和指标</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<Footer />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { onMounted } from 'vue'
|
||||||
|
import Header from '@/components/Header.vue'
|
||||||
|
import Footer from '@/components/Footer.vue'
|
||||||
|
import {
|
||||||
|
Connection,
|
||||||
|
// Server,
|
||||||
|
Monitor,
|
||||||
|
Share,
|
||||||
|
User,
|
||||||
|
// Globe,
|
||||||
|
Cpu,
|
||||||
|
// DataBase,
|
||||||
|
Box,
|
||||||
|
Setting
|
||||||
|
} from '@element-plus/icons-vue'
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
// 页面初始化逻辑
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.architecture-page {
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hero Section
|
||||||
|
.hero {
|
||||||
|
padding: 120px 0 60px;
|
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
|
color: white;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
.hero-title {
|
||||||
|
font-size: 48px;
|
||||||
|
font-weight: 700;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
font-size: 32px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-subtitle {
|
||||||
|
font-size: 18px;
|
||||||
|
opacity: 0.9;
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Section Header
|
||||||
|
.section-header {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 60px;
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: 36px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 16px;
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
font-size: 28px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-subtitle {
|
||||||
|
font-size: 18px;
|
||||||
|
color: var(--text-regular);
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Architecture Overview
|
||||||
|
.architecture-overview {
|
||||||
|
padding: 80px 0;
|
||||||
|
background: var(--background-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.architecture-diagram {
|
||||||
|
max-width: 1000px;
|
||||||
|
margin: 0 auto;
|
||||||
|
|
||||||
|
.layer {
|
||||||
|
margin-bottom: 30px;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 12px;
|
||||||
|
background: var(--background-light);
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 16px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.components {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 12px;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
.component {
|
||||||
|
padding: 8px 16px;
|
||||||
|
background: var(--primary-color);
|
||||||
|
color: white;
|
||||||
|
border-radius: 6px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.application-layer {
|
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
|
color: white;
|
||||||
|
|
||||||
|
.component {
|
||||||
|
background: rgba(255, 255, 255, 0.2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.business-layer {
|
||||||
|
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
|
||||||
|
color: white;
|
||||||
|
|
||||||
|
.component {
|
||||||
|
background: rgba(255, 255, 255, 0.2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.protocol-layer {
|
||||||
|
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
|
||||||
|
color: white;
|
||||||
|
|
||||||
|
.component {
|
||||||
|
background: rgba(255, 255, 255, 0.2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.communication-layer {
|
||||||
|
background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);
|
||||||
|
color: white;
|
||||||
|
|
||||||
|
.component {
|
||||||
|
background: rgba(255, 255, 255, 0.2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.data-layer {
|
||||||
|
background: linear-gradient(135deg, #fa709a 0%, #fee140 100%);
|
||||||
|
color: white;
|
||||||
|
|
||||||
|
.component {
|
||||||
|
background: rgba(255, 255, 255, 0.2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Module Architecture
|
||||||
|
.module-architecture {
|
||||||
|
padding: 80px 0;
|
||||||
|
background: var(--background-light);
|
||||||
|
}
|
||||||
|
|
||||||
|
.modules-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
|
||||||
|
gap: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.module-card {
|
||||||
|
background: white;
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 30px;
|
||||||
|
box-shadow: var(--shadow-light);
|
||||||
|
transition: transform 0.3s ease;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
transform: translateY(-4px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.module-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 16px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
.module-icon {
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
background: var(--primary-color);
|
||||||
|
border-radius: 10px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
.el-icon {
|
||||||
|
font-size: 24px;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.module-description {
|
||||||
|
color: var(--text-regular);
|
||||||
|
line-height: 1.6;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.module-components {
|
||||||
|
h4 {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style: none;
|
||||||
|
|
||||||
|
li {
|
||||||
|
color: var(--text-regular);
|
||||||
|
margin-bottom: 6px;
|
||||||
|
position: relative;
|
||||||
|
padding-left: 16px;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: '•';
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
color: var(--primary-color);
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Data Flow
|
||||||
|
.data-flow {
|
||||||
|
padding: 80px 0;
|
||||||
|
background: var(--background-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.flow-diagrams {
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flow-diagram {
|
||||||
|
margin-bottom: 60px;
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 30px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.flow-steps {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 20px;
|
||||||
|
|
||||||
|
.flow-step {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
text-align: center;
|
||||||
|
max-width: 200px;
|
||||||
|
|
||||||
|
.step-icon {
|
||||||
|
width: 60px;
|
||||||
|
height: 60px;
|
||||||
|
background: var(--primary-color);
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
|
||||||
|
.el-icon {
|
||||||
|
font-size: 24px;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.step-content {
|
||||||
|
h4 {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-size: 14px;
|
||||||
|
color: var(--text-regular);
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.flow-arrow {
|
||||||
|
font-size: 24px;
|
||||||
|
color: var(--primary-color);
|
||||||
|
font-weight: bold;
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
transform: rotate(90deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Technology Stack
|
||||||
|
.technology-stack {
|
||||||
|
padding: 80px 0;
|
||||||
|
background: var(--background-light);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tech-categories {
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tech-category {
|
||||||
|
margin-bottom: 60px;
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 30px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tech-items {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
|
||||||
|
gap: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tech-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 16px;
|
||||||
|
padding: 20px;
|
||||||
|
background: white;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: var(--shadow-light);
|
||||||
|
|
||||||
|
.tech-icon {
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
background: var(--primary-color);
|
||||||
|
border-radius: 10px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-shrink: 0;
|
||||||
|
|
||||||
|
.el-icon {
|
||||||
|
font-size: 24px;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tech-info {
|
||||||
|
h4 {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-size: 14px;
|
||||||
|
color: var(--text-regular);
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
967
website/src/views/Docs.vue
Normal file
@@ -0,0 +1,967 @@
|
|||||||
|
<template>
|
||||||
|
<div class="docs-page">
|
||||||
|
<Header />
|
||||||
|
|
||||||
|
<!-- Hero Section -->
|
||||||
|
<section class="hero">
|
||||||
|
<div class="container">
|
||||||
|
<div class="hero-content">
|
||||||
|
<h1 class="hero-title">使用文档</h1>
|
||||||
|
<p class="hero-subtitle">
|
||||||
|
详细的使用指南和配置说明,帮助您快速上手 Wu-Lazy-Cloud-Network
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Docs Navigation -->
|
||||||
|
<section class="docs-navigation">
|
||||||
|
<div class="container">
|
||||||
|
<div class="docs-nav">
|
||||||
|
<div class="nav-item" @click="scrollToSection('quick-start')">
|
||||||
|
<el-icon><Timer /></el-icon>
|
||||||
|
<span>快速开始</span>
|
||||||
|
</div>
|
||||||
|
<div class="nav-item" @click="scrollToSection('installation')">
|
||||||
|
<el-icon><Download /></el-icon>
|
||||||
|
<span>安装部署</span>
|
||||||
|
</div>
|
||||||
|
<div class="nav-item" @click="scrollToSection('configuration')">
|
||||||
|
<el-icon><Setting /></el-icon>
|
||||||
|
<span>配置说明</span>
|
||||||
|
</div>
|
||||||
|
<div class="nav-item" @click="scrollToSection('usage')">
|
||||||
|
<el-icon><Document /></el-icon>
|
||||||
|
<span>使用指南</span>
|
||||||
|
</div>
|
||||||
|
<div class="nav-item" @click="scrollToSection('troubleshooting')">
|
||||||
|
<el-icon><Tools /></el-icon>
|
||||||
|
<span>故障排除</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Quick Start -->
|
||||||
|
<section class="docs-section" id="quick-start">
|
||||||
|
<div class="container">
|
||||||
|
<div class="section-header">
|
||||||
|
<h2 class="section-title">快速开始</h2>
|
||||||
|
<p class="section-subtitle">几分钟内完成部署和配置</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="docs-content">
|
||||||
|
<div class="step-guide">
|
||||||
|
<div class="step">
|
||||||
|
<div class="step-number">1</div>
|
||||||
|
<div class="step-content">
|
||||||
|
<h3>启动服务端</h3>
|
||||||
|
<p>使用 Docker 快速启动服务端</p>
|
||||||
|
<div class="code-block">
|
||||||
|
<pre><code class="language-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</code></pre>
|
||||||
|
</div>
|
||||||
|
<div class="step-notes">
|
||||||
|
<h4>端口说明</h4>
|
||||||
|
<ul>
|
||||||
|
<li><strong>6001</strong>: Web 管理界面</li>
|
||||||
|
<li><strong>7001</strong>: TCP 连接端口</li>
|
||||||
|
<li><strong>8001</strong>: HTTP 代理端口</li>
|
||||||
|
<li><strong>9001</strong>: SOCKS 代理端口</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="step">
|
||||||
|
<div class="step-number">2</div>
|
||||||
|
<div class="step-content">
|
||||||
|
<h3>启动客户端</h3>
|
||||||
|
<p>配置客户端连接到服务端</p>
|
||||||
|
<div class="code-block">
|
||||||
|
<pre><code class="language-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</code></pre>
|
||||||
|
</div>
|
||||||
|
<div class="step-notes">
|
||||||
|
<h4>环境变量说明</h4>
|
||||||
|
<ul>
|
||||||
|
<li><strong>inet-host</strong>: 服务端 IP 地址</li>
|
||||||
|
<li><strong>inet-port</strong>: 服务端 TCP 端口</li>
|
||||||
|
<li><strong>client-id</strong>: 客户端唯一标识</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="step">
|
||||||
|
<div class="step-number">3</div>
|
||||||
|
<div class="step-content">
|
||||||
|
<h3>访问管理界面</h3>
|
||||||
|
<p>通过 Web 界面进行配置和管理</p>
|
||||||
|
<div class="code-block">
|
||||||
|
<pre><code class="language-bash"># 服务端管理界面
|
||||||
|
http://127.0.0.1:6001/netty-server-ui/index.html
|
||||||
|
|
||||||
|
# 客户端管理界面
|
||||||
|
http://127.0.0.1:6004/netty-client-local-ui/index.html</code></pre>
|
||||||
|
</div>
|
||||||
|
<div class="step-notes">
|
||||||
|
<h4>默认登录信息</h4>
|
||||||
|
<ul>
|
||||||
|
<li><strong>用户名</strong>: admin</li>
|
||||||
|
<li><strong>密码</strong>: admin</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Installation -->
|
||||||
|
<section class="docs-section" id="installation">
|
||||||
|
<div class="container">
|
||||||
|
<div class="section-header">
|
||||||
|
<h2 class="section-title">安装部署</h2>
|
||||||
|
<p class="section-subtitle">支持多种部署方式,满足不同环境需求</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="docs-content">
|
||||||
|
<div class="deployment-methods">
|
||||||
|
<div class="method-card">
|
||||||
|
<div class="method-header">
|
||||||
|
<el-icon><Box /></el-icon>
|
||||||
|
<h3>Docker 部署</h3>
|
||||||
|
</div>
|
||||||
|
<p>推荐使用 Docker 进行部署,简单快速</p>
|
||||||
|
<div class="method-steps">
|
||||||
|
<h4>服务端部署</h4>
|
||||||
|
<div class="code-block">
|
||||||
|
<pre><code class="language-bash"># 拉取镜像
|
||||||
|
docker pull registry.cn-hangzhou.aliyuncs.com/wu-lazy/wu-lazy-cloud-heartbeat-server:1.3.1-JDK24
|
||||||
|
|
||||||
|
# 启动容器
|
||||||
|
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</code></pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h4>客户端部署</h4>
|
||||||
|
<div class="code-block">
|
||||||
|
<pre><code class="language-bash"># 拉取镜像
|
||||||
|
docker pull registry.cn-hangzhou.aliyuncs.com/wu-lazy/wu-lazy-cloud-heartbeat-client-start:1.3.1-JDK24
|
||||||
|
|
||||||
|
# 启动容器
|
||||||
|
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</code></pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="method-card">
|
||||||
|
<div class="method-header">
|
||||||
|
<el-icon><Download /></el-icon>
|
||||||
|
<h3>源码部署</h3>
|
||||||
|
</div>
|
||||||
|
<p>从源码编译部署,适合开发环境</p>
|
||||||
|
<div class="method-steps">
|
||||||
|
<h4>环境要求</h4>
|
||||||
|
<ul>
|
||||||
|
<li>JDK 24 或 JDK 17+</li>
|
||||||
|
<li>Maven 3.6+</li>
|
||||||
|
<li>MySQL 8.0+ (可选)</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h4>编译部署</h4>
|
||||||
|
<div class="code-block">
|
||||||
|
<pre><code class="language-bash"># 克隆项目
|
||||||
|
git clone https://gitee.com/wujiawei1207537021/wu-lazy-cloud-network.git
|
||||||
|
cd wu-lazy-cloud-network
|
||||||
|
|
||||||
|
# 编译项目
|
||||||
|
mvn clean package -DskipTests
|
||||||
|
|
||||||
|
# 启动服务端
|
||||||
|
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
|
||||||
|
|
||||||
|
# 启动客户端
|
||||||
|
cd ../wu-lazy-cloud-heartbeat-client-start
|
||||||
|
java -jar target/wu-lazy-cloud-heartbeat-client-start-1.3.1-JDK24.jar</code></pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Configuration -->
|
||||||
|
<section class="docs-section" id="configuration">
|
||||||
|
<div class="container">
|
||||||
|
<div class="section-header">
|
||||||
|
<h2 class="section-title">配置说明</h2>
|
||||||
|
<p class="section-subtitle">详细的配置参数说明和使用示例</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="docs-content">
|
||||||
|
<div class="config-tabs">
|
||||||
|
<el-tabs v-model="activeConfigTab">
|
||||||
|
<el-tab-pane label="服务端配置" name="server">
|
||||||
|
<div class="config-content">
|
||||||
|
<h3>服务端配置</h3>
|
||||||
|
<div class="code-block">
|
||||||
|
<pre><code class="language-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端口</code></pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h4>配置参数说明</h4>
|
||||||
|
<div class="param-table">
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>参数</th>
|
||||||
|
<th>说明</th>
|
||||||
|
<th>默认值</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>mode</td>
|
||||||
|
<td>运行模式,支持 standalone 和 cluster</td>
|
||||||
|
<td>standalone</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>node-id</td>
|
||||||
|
<td>节点唯一标识</td>
|
||||||
|
<td>default</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>node-host</td>
|
||||||
|
<td>节点主机地址</td>
|
||||||
|
<td>127.0.0.1</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>node-port</td>
|
||||||
|
<td>节点监听端口</td>
|
||||||
|
<td>7001</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>enable-flow-control</td>
|
||||||
|
<td>是否启用流量控制</td>
|
||||||
|
<td>true</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-tab-pane>
|
||||||
|
|
||||||
|
<el-tab-pane label="客户端配置" name="client">
|
||||||
|
<div class="config-content">
|
||||||
|
<h3>客户端配置</h3>
|
||||||
|
<div class="code-block">
|
||||||
|
<pre><code class="language-yaml">spring:
|
||||||
|
lazy:
|
||||||
|
netty:
|
||||||
|
client:
|
||||||
|
client-id: your-client-id # 客户端ID
|
||||||
|
inet-host: 127.0.0.1 # 服务端地址
|
||||||
|
inet-port: 7001 # 服务端端口
|
||||||
|
enable: true # 启用客户端连接</code></pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h4>配置参数说明</h4>
|
||||||
|
<div class="param-table">
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>参数</th>
|
||||||
|
<th>说明</th>
|
||||||
|
<th>默认值</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>client-id</td>
|
||||||
|
<td>客户端唯一标识</td>
|
||||||
|
<td>-</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>inet-host</td>
|
||||||
|
<td>服务端 IP 地址</td>
|
||||||
|
<td>127.0.0.1</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>inet-port</td>
|
||||||
|
<td>服务端 TCP 端口</td>
|
||||||
|
<td>7001</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>enable</td>
|
||||||
|
<td>是否启用客户端连接</td>
|
||||||
|
<td>true</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-tab-pane>
|
||||||
|
|
||||||
|
<el-tab-pane label="代理配置" name="proxy">
|
||||||
|
<div class="config-content">
|
||||||
|
<h3>代理配置</h3>
|
||||||
|
<div class="code-block">
|
||||||
|
<pre><code class="language-yaml">spring:
|
||||||
|
lazy:
|
||||||
|
netty:
|
||||||
|
protocol:
|
||||||
|
proxy:
|
||||||
|
authentication: true # 启用代理认证
|
||||||
|
enable-proxy-log: false # 启用代理日志
|
||||||
|
socket-protocol-proxy:
|
||||||
|
port: 9001 # SOCKS代理端口
|
||||||
|
http-protocol-proxy:
|
||||||
|
port: 8001 # HTTP代理端口</code></pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h4>配置参数说明</h4>
|
||||||
|
<div class="param-table">
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>参数</th>
|
||||||
|
<th>说明</th>
|
||||||
|
<th>默认值</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>authentication</td>
|
||||||
|
<td>是否启用代理认证</td>
|
||||||
|
<td>true</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>enable-proxy-log</td>
|
||||||
|
<td>是否启用代理日志</td>
|
||||||
|
<td>false</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>socket-protocol-proxy.port</td>
|
||||||
|
<td>SOCKS 代理端口</td>
|
||||||
|
<td>9001</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>http-protocol-proxy.port</td>
|
||||||
|
<td>HTTP 代理端口</td>
|
||||||
|
<td>8001</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Usage Globe -->
|
||||||
|
<section class="docs-section" id="usage">
|
||||||
|
<div class="container">
|
||||||
|
<div class="section-header">
|
||||||
|
<h2 class="section-title">使用指南</h2>
|
||||||
|
<p class="section-subtitle">详细的功能使用说明和最佳实践</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="docs-content">
|
||||||
|
<div class="usage-guides">
|
||||||
|
<div class="guide-card">
|
||||||
|
<h3>内网穿透配置</h3>
|
||||||
|
<div class="guide-content">
|
||||||
|
<h4>服务端渗透客户端</h4>
|
||||||
|
<ol>
|
||||||
|
<li>在服务端管理界面配置端口池</li>
|
||||||
|
<li>设置访客端口与客户端真实端口的映射关系</li>
|
||||||
|
<li>例如:访客端口 19080 → 客户端本地端口 18080</li>
|
||||||
|
<li>通过 <code>http://服务端IP:19080</code> 访问客户端本地 18080 端口</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<h4>客户端渗透服务端</h4>
|
||||||
|
<ol>
|
||||||
|
<li>在客户端管理界面配置本地端口池</li>
|
||||||
|
<li>设置本地端口到远程端口的映射关系</li>
|
||||||
|
<li>例如:本地端口 13306 → 远程端口 3306</li>
|
||||||
|
<li>通过 <code>localhost:13306</code> 访问远程 3306 端口</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="guide-card">
|
||||||
|
<h3>代理功能使用</h3>
|
||||||
|
<div class="guide-content">
|
||||||
|
<h4>HTTP 代理</h4>
|
||||||
|
<ul>
|
||||||
|
<li><strong>服务端代理</strong>: 127.0.0.1:8001</li>
|
||||||
|
<li><strong>客户端代理</strong>: 127.0.0.1:8002</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h4>SOCKS 代理</h4>
|
||||||
|
<ul>
|
||||||
|
<li><strong>服务端代理</strong>: 127.0.0.1:9001</li>
|
||||||
|
<li><strong>客户端代理</strong>: 127.0.0.1:9002</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h4>代理配置示例</h4>
|
||||||
|
<div class="code-block">
|
||||||
|
<pre><code class="language-bash"># 系统代理设置 (Mac)
|
||||||
|
networksetup -setwebproxy "Wi-Fi" 127.0.0.1 8001
|
||||||
|
networksetup -setsecurewebproxy "Wi-Fi" 127.0.0.1 8001
|
||||||
|
|
||||||
|
# 使用 curl 测试代理
|
||||||
|
curl -x http://127.0.0.1:8001 http://httpbin.org/ip</code></pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="guide-card">
|
||||||
|
<h3>流量监控</h3>
|
||||||
|
<div class="guide-content">
|
||||||
|
<h4>监控功能</h4>
|
||||||
|
<ul>
|
||||||
|
<li>实时监控每个客户端的流量使用情况</li>
|
||||||
|
<li>按端口统计流量数据</li>
|
||||||
|
<li>提供流量趋势图表</li>
|
||||||
|
<li>支持流量告警设置</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h4>报表功能</h4>
|
||||||
|
<ul>
|
||||||
|
<li>日流量统计报表</li>
|
||||||
|
<li>客户端流量排行</li>
|
||||||
|
<li>端口使用情况分析</li>
|
||||||
|
<li>历史数据查询</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Troubleshooting -->
|
||||||
|
<section class="docs-section" id="troubleshooting">
|
||||||
|
<div class="container">
|
||||||
|
<div class="section-header">
|
||||||
|
<h2 class="section-title">故障排除</h2>
|
||||||
|
<p class="section-subtitle">常见问题解决方案和调试技巧</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="docs-content">
|
||||||
|
<div class="troubleshooting-list">
|
||||||
|
<div class="trouble-item">
|
||||||
|
<h3>客户端连接失败</h3>
|
||||||
|
<div class="trouble-content">
|
||||||
|
<h4>检查项</h4>
|
||||||
|
<ul>
|
||||||
|
<li>服务端 IP 和端口是否正确</li>
|
||||||
|
<li>网络连接是否正常</li>
|
||||||
|
<li>防火墙是否阻止连接</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h4>解决方案</h4>
|
||||||
|
<div class="code-block">
|
||||||
|
<pre><code class="language-bash"># 检查网络连接
|
||||||
|
ping YOUR_SERVER_IP
|
||||||
|
|
||||||
|
# 检查端口是否开放
|
||||||
|
telnet YOUR_SERVER_IP 7001
|
||||||
|
|
||||||
|
# 查看客户端日志
|
||||||
|
docker logs wlcn-client</code></pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="trouble-item">
|
||||||
|
<h3>内网穿透不工作</h3>
|
||||||
|
<div class="trouble-content">
|
||||||
|
<h4>检查项</h4>
|
||||||
|
<ul>
|
||||||
|
<li>端口映射配置是否正确</li>
|
||||||
|
<li>目标服务是否正在运行</li>
|
||||||
|
<li>防火墙规则是否允许</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h4>解决方案</h4>
|
||||||
|
<ul>
|
||||||
|
<li>确认映射配置: 访客端口 → 客户端端口</li>
|
||||||
|
<li>检查目标服务状态</li>
|
||||||
|
<li>测试本地端口访问</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="trouble-item">
|
||||||
|
<h3>代理连接失败</h3>
|
||||||
|
<div class="trouble-content">
|
||||||
|
<h4>检查项</h4>
|
||||||
|
<ul>
|
||||||
|
<li>代理地址和端口是否正确</li>
|
||||||
|
<li>代理认证信息是否正确</li>
|
||||||
|
<li>网络连接是否正常</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h4>解决方案</h4>
|
||||||
|
<ul>
|
||||||
|
<li>验证代理配置信息</li>
|
||||||
|
<li>检查认证设置</li>
|
||||||
|
<li>测试网络连接</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<Footer />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted } from 'vue'
|
||||||
|
import Header from '@/components/Header.vue'
|
||||||
|
import Footer from '@/components/Footer.vue'
|
||||||
|
import {
|
||||||
|
Timer,
|
||||||
|
Download,
|
||||||
|
Setting,
|
||||||
|
Document,
|
||||||
|
Tools,
|
||||||
|
Box
|
||||||
|
} from '@element-plus/icons-vue'
|
||||||
|
|
||||||
|
const activeConfigTab = ref('server')
|
||||||
|
|
||||||
|
const scrollToSection = (sectionId) => {
|
||||||
|
const element = document.getElementById(sectionId)
|
||||||
|
if (element) {
|
||||||
|
element.scrollIntoView({ behavior: 'smooth' })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
// 高亮代码块
|
||||||
|
if (window.Prism) {
|
||||||
|
window.Prism.highlightAll()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.docs-page {
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hero Section
|
||||||
|
.hero {
|
||||||
|
padding: 120px 0 60px;
|
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
|
color: white;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
.hero-title {
|
||||||
|
font-size: 48px;
|
||||||
|
font-weight: 700;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
font-size: 32px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-subtitle {
|
||||||
|
font-size: 18px;
|
||||||
|
opacity: 0.9;
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Docs Navigation
|
||||||
|
.docs-navigation {
|
||||||
|
background: white;
|
||||||
|
border-bottom: 1px solid var(--border-light);
|
||||||
|
padding: 20px 0;
|
||||||
|
position: sticky;
|
||||||
|
top: 70px;
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
.docs-nav {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 40px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
|
||||||
|
.nav-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 12px 20px;
|
||||||
|
border-radius: 6px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
color: var(--text-regular);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: var(--background-light);
|
||||||
|
color: var(--primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-icon {
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Section Header
|
||||||
|
.section-header {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 60px;
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: 36px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 16px;
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
font-size: 28px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-subtitle {
|
||||||
|
font-size: 18px;
|
||||||
|
color: var(--text-regular);
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Docs Section
|
||||||
|
.docs-section {
|
||||||
|
padding: 80px 0;
|
||||||
|
|
||||||
|
&:nth-child(even) {
|
||||||
|
background: var(--background-light);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.docs-content {
|
||||||
|
max-width: 1000px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step Globe
|
||||||
|
.step-guide {
|
||||||
|
.step {
|
||||||
|
display: flex;
|
||||||
|
gap: 20px;
|
||||||
|
margin-bottom: 40px;
|
||||||
|
|
||||||
|
.step-number {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
background: var(--primary-color);
|
||||||
|
color: white;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-weight: 600;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step-content {
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
color: var(--text-regular);
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step-notes {
|
||||||
|
margin-top: 16px;
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style: none;
|
||||||
|
|
||||||
|
li {
|
||||||
|
color: var(--text-regular);
|
||||||
|
margin-bottom: 4px;
|
||||||
|
position: relative;
|
||||||
|
padding-left: 16px;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: '•';
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
color: var(--primary-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deployment Methods
|
||||||
|
.deployment-methods {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
|
||||||
|
gap: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.method-card {
|
||||||
|
background: white;
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 30px;
|
||||||
|
box-shadow: var(--shadow-light);
|
||||||
|
|
||||||
|
.method-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
|
||||||
|
.el-icon {
|
||||||
|
font-size: 24px;
|
||||||
|
color: var(--primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
color: var(--text-regular);
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.method-steps {
|
||||||
|
h4 {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style: none;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
|
||||||
|
li {
|
||||||
|
color: var(--text-regular);
|
||||||
|
margin-bottom: 6px;
|
||||||
|
position: relative;
|
||||||
|
padding-left: 16px;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: '•';
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
color: var(--primary-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Config Tabs
|
||||||
|
.config-tabs {
|
||||||
|
.config-content {
|
||||||
|
h3 {
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin: 20px 0 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parameter Table
|
||||||
|
.param-table {
|
||||||
|
margin-top: 20px;
|
||||||
|
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
|
||||||
|
th, td {
|
||||||
|
padding: 12px;
|
||||||
|
text-align: left;
|
||||||
|
border-bottom: 1px solid var(--border-light);
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
background: var(--background-light);
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
td {
|
||||||
|
color: var(--text-regular);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Usage Globes
|
||||||
|
.usage-guides {
|
||||||
|
display: grid;
|
||||||
|
gap: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.guide-card {
|
||||||
|
background: white;
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 30px;
|
||||||
|
box-shadow: var(--shadow-light);
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.guide-content {
|
||||||
|
h4 {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin: 16px 0 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol, ul {
|
||||||
|
color: var(--text-regular);
|
||||||
|
margin-bottom: 16px;
|
||||||
|
|
||||||
|
li {
|
||||||
|
margin-bottom: 6px;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
background: var(--background-light);
|
||||||
|
padding: 2px 6px;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Troubleshooting
|
||||||
|
.troubleshooting-list {
|
||||||
|
display: grid;
|
||||||
|
gap: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.trouble-item {
|
||||||
|
background: white;
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 30px;
|
||||||
|
box-shadow: var(--shadow-light);
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.trouble-content {
|
||||||
|
h4 {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin: 16px 0 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style: none;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
|
||||||
|
li {
|
||||||
|
color: var(--text-regular);
|
||||||
|
margin-bottom: 6px;
|
||||||
|
position: relative;
|
||||||
|
padding-left: 16px;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: '•';
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
color: var(--primary-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
773
website/src/views/Download.vue
Normal file
@@ -0,0 +1,773 @@
|
|||||||
|
<template>
|
||||||
|
<div class="download-page">
|
||||||
|
<Header />
|
||||||
|
|
||||||
|
<!-- Hero Section -->
|
||||||
|
<section class="hero">
|
||||||
|
<div class="container">
|
||||||
|
<div class="hero-content">
|
||||||
|
<h1 class="hero-title">下载安装</h1>
|
||||||
|
<p class="hero-subtitle">
|
||||||
|
选择适合您的部署方式,快速开始使用 Wu-Lazy-Cloud-Network
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Version Info -->
|
||||||
|
<section class="version-info">
|
||||||
|
<div class="container">
|
||||||
|
<div class="version-card">
|
||||||
|
<div class="version-header">
|
||||||
|
<h2>当前版本</h2>
|
||||||
|
<div class="version-badge">v1.3.1-JDK24</div>
|
||||||
|
</div>
|
||||||
|
<div class="version-details">
|
||||||
|
<div class="detail-item">
|
||||||
|
<span class="label">发布日期</span>
|
||||||
|
<span class="value">2024年12月</span>
|
||||||
|
</div>
|
||||||
|
<div class="detail-item">
|
||||||
|
<span class="label">JDK 版本</span>
|
||||||
|
<span class="value">JDK 24</span>
|
||||||
|
</div>
|
||||||
|
<div class="detail-item">
|
||||||
|
<span class="label">Spring Boot</span>
|
||||||
|
<span class="value">3.5.0</span>
|
||||||
|
</div>
|
||||||
|
<div class="detail-item">
|
||||||
|
<span class="label">许可证</span>
|
||||||
|
<span class="value">Apache License 2.0</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Download Options -->
|
||||||
|
<section class="download-options">
|
||||||
|
<div class="container">
|
||||||
|
<div class="section-header">
|
||||||
|
<h2 class="section-title">下载方式</h2>
|
||||||
|
<p class="section-subtitle">支持多种部署方式,满足不同环境需求</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="options-grid">
|
||||||
|
<div class="option-card">
|
||||||
|
<div class="option-header">
|
||||||
|
<div class="option-icon">
|
||||||
|
<el-icon><Box /></el-icon>
|
||||||
|
</div>
|
||||||
|
<h3>Docker 镜像</h3>
|
||||||
|
<p>推荐使用,简单快速部署</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="option-content">
|
||||||
|
<h4>服务端镜像</h4>
|
||||||
|
<div class="code-block">
|
||||||
|
<pre><code class="language-bash"># 拉取镜像
|
||||||
|
docker pull registry.cn-hangzhou.aliyuncs.com/wu-lazy/wu-lazy-cloud-heartbeat-server:1.3.1-JDK24
|
||||||
|
|
||||||
|
# 启动容器
|
||||||
|
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</code></pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h4>客户端镜像</h4>
|
||||||
|
<div class="code-block">
|
||||||
|
<pre><code class="language-bash"># 拉取镜像
|
||||||
|
docker pull registry.cn-hangzhou.aliyuncs.com/wu-lazy/wu-lazy-cloud-heartbeat-client-start:1.3.1-JDK24
|
||||||
|
|
||||||
|
# 启动容器
|
||||||
|
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</code></pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="option-actions">
|
||||||
|
<a href="https://gitee.com/wujiawei1207537021/wu-lazy-cloud-network" target="_blank" class="btn btn-primary">
|
||||||
|
<el-icon><Platform /></el-icon>
|
||||||
|
查看源码
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="option-card">
|
||||||
|
<div class="option-header">
|
||||||
|
<div class="option-icon">
|
||||||
|
<el-icon><Download /></el-icon>
|
||||||
|
</div>
|
||||||
|
<h3>源码编译</h3>
|
||||||
|
<p>从源码编译,适合开发环境</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="option-content">
|
||||||
|
<h4>环境要求</h4>
|
||||||
|
<ul>
|
||||||
|
<li>JDK 24 或 JDK 17+</li>
|
||||||
|
<li>Maven 3.6+</li>
|
||||||
|
<li>MySQL 8.0+ (可选)</li>
|
||||||
|
<li>Git 2.30+</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h4>编译步骤</h4>
|
||||||
|
<div class="code-block">
|
||||||
|
<pre><code class="language-bash"># 克隆项目
|
||||||
|
git clone https://gitee.com/wujiawei1207537021/wu-lazy-cloud-network.git
|
||||||
|
cd wu-lazy-cloud-network
|
||||||
|
|
||||||
|
# 编译项目
|
||||||
|
mvn clean package -DskipTests
|
||||||
|
|
||||||
|
# 启动服务端
|
||||||
|
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
|
||||||
|
|
||||||
|
# 启动客户端
|
||||||
|
cd ../wu-lazy-cloud-heartbeat-client-start
|
||||||
|
java -jar target/wu-lazy-cloud-heartbeat-client-start-1.3.1-JDK24.jar</code></pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="option-actions">
|
||||||
|
<a href="https://gitee.com/wujiawei1207537021/wu-lazy-cloud-network" target="_blank" class="btn btn-outline">
|
||||||
|
<el-icon><Platform /></el-icon>
|
||||||
|
下载源码
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="option-card">
|
||||||
|
<div class="option-header">
|
||||||
|
<div class="option-icon">
|
||||||
|
<el-icon><Setting /></el-icon>
|
||||||
|
</div>
|
||||||
|
<h3>预编译包</h3>
|
||||||
|
<p>直接下载预编译的 JAR 包</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="option-content">
|
||||||
|
<h4>下载链接</h4>
|
||||||
|
<div class="download-links">
|
||||||
|
<div class="download-link">
|
||||||
|
<span class="link-label">服务端</span>
|
||||||
|
<a href="https://gitee.com/wujiawei1207537021/wu-lazy-cloud-network/releases" target="_blank" class="link-url">
|
||||||
|
wu-lazy-cloud-heartbeat-server-start-1.3.1-JDK24.jar
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="download-link">
|
||||||
|
<span class="link-label">客户端</span>
|
||||||
|
<a href="https://gitee.com/wujiawei1207537021/wu-lazy-cloud-network/releases" target="_blank" class="link-url">
|
||||||
|
wu-lazy-cloud-heartbeat-client-start-1.3.1-JDK24.jar
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="download-link">
|
||||||
|
<span class="link-label">集群版</span>
|
||||||
|
<a href="https://gitee.com/wujiawei1207537021/wu-lazy-cloud-network/releases" target="_blank" class="link-url">
|
||||||
|
wu-lazy-cloud-heartbeat-server-cluster-start-1.3.1-JDK24.jar
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h4>启动命令</h4>
|
||||||
|
<div class="code-block">
|
||||||
|
<pre><code class="language-bash"># 服务端启动
|
||||||
|
java -jar wu-lazy-cloud-heartbeat-server-start-1.3.1-JDK24.jar
|
||||||
|
|
||||||
|
# 客户端启动
|
||||||
|
java -jar wu-lazy-cloud-heartbeat-client-start-1.3.1-JDK24.jar</code></pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="option-actions">
|
||||||
|
<a href="https://gitee.com/wujiawei1207537021/wu-lazy-cloud-network/releases" target="_blank" class="btn btn-outline">
|
||||||
|
<el-icon><Download /></el-icon>
|
||||||
|
下载 JAR 包
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Deployment Globe -->
|
||||||
|
<section class="deployment-guide">
|
||||||
|
<div class="container">
|
||||||
|
<div class="section-header">
|
||||||
|
<h2 class="section-title">部署指南</h2>
|
||||||
|
<p class="section-subtitle">详细的部署说明和最佳实践</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="guide-content">
|
||||||
|
<div class="guide-tabs">
|
||||||
|
<el-tabs v-model="activeGlobeTab">
|
||||||
|
<el-tab-pane label="Docker 部署" name="docker">
|
||||||
|
<div class="guide-section">
|
||||||
|
<h3>Docker 部署指南</h3>
|
||||||
|
|
||||||
|
<h4>1. 环境准备</h4>
|
||||||
|
<ul>
|
||||||
|
<li>安装 Docker 20.10+</li>
|
||||||
|
<li>确保 Docker 服务正在运行</li>
|
||||||
|
<li>准备公网 IP 地址(服务端)</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h4>2. 启动服务端</h4>
|
||||||
|
<div class="code-block">
|
||||||
|
<pre><code class="language-bash"># 拉取镜像
|
||||||
|
docker pull registry.cn-hangzhou.aliyuncs.com/wu-lazy/wu-lazy-cloud-heartbeat-server:1.3.1-JDK24
|
||||||
|
|
||||||
|
# 启动容器
|
||||||
|
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</code></pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h4>3. 启动客户端</h4>
|
||||||
|
<div class="code-block">
|
||||||
|
<pre><code class="language-bash"># 拉取镜像
|
||||||
|
docker pull registry.cn-hangzhou.aliyuncs.com/wu-lazy/wu-lazy-cloud-heartbeat-client-start:1.3.1-JDK24
|
||||||
|
|
||||||
|
# 启动容器(替换 YOUR_SERVER_IP 为实际服务端 IP)
|
||||||
|
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</code></pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h4>4. 验证部署</h4>
|
||||||
|
<ul>
|
||||||
|
<li>访问服务端管理界面: <code>http://服务端IP:6001/netty-server-ui/index.html</code></li>
|
||||||
|
<li>访问客户端管理界面: <code>http://客户端IP:6004/netty-client-local-ui/index.html</code></li>
|
||||||
|
<li>默认登录信息: admin/admin</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</el-tab-pane>
|
||||||
|
|
||||||
|
<el-tab-pane label="源码部署" name="source">
|
||||||
|
<div class="guide-section">
|
||||||
|
<h3>源码部署指南</h3>
|
||||||
|
|
||||||
|
<h4>1. 环境准备</h4>
|
||||||
|
<ul>
|
||||||
|
<li>安装 JDK 24 或 JDK 17+</li>
|
||||||
|
<li>安装 Maven 3.6+</li>
|
||||||
|
<li>安装 Git 2.30+</li>
|
||||||
|
<li>准备 MySQL 8.0+ (可选)</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h4>2. 获取源码</h4>
|
||||||
|
<div class="code-block">
|
||||||
|
<pre><code class="language-bash"># 克隆项目
|
||||||
|
git clone https://gitee.com/wujiawei1207537021/wu-lazy-cloud-network.git
|
||||||
|
cd wu-lazy-cloud-network
|
||||||
|
|
||||||
|
# 切换到稳定版本
|
||||||
|
git checkout v1.3.1-JDK24</code></pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h4>3. 编译项目</h4>
|
||||||
|
<div class="code-block">
|
||||||
|
<pre><code class="language-bash"># 编译所有模块
|
||||||
|
mvn clean package -DskipTests
|
||||||
|
|
||||||
|
# 或者编译特定模块
|
||||||
|
mvn clean package -pl wu-lazy-cloud-heartbeat-server-start -am -DskipTests
|
||||||
|
mvn clean package -pl wu-lazy-cloud-heartbeat-client-start -am -DskipTests</code></pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h4>4. 启动应用</h4>
|
||||||
|
<div class="code-block">
|
||||||
|
<pre><code class="language-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
|
||||||
|
|
||||||
|
# 启动客户端
|
||||||
|
cd ../wu-lazy-cloud-heartbeat-client-start
|
||||||
|
java -jar target/wu-lazy-cloud-heartbeat-client-start-1.3.1-JDK24.jar</code></pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-tab-pane>
|
||||||
|
|
||||||
|
<el-tab-pane label="集群部署" name="cluster">
|
||||||
|
<div class="guide-section">
|
||||||
|
<h3>集群部署指南</h3>
|
||||||
|
|
||||||
|
<h4>1. 集群架构</h4>
|
||||||
|
<p>支持多节点集群部署,提供高可用性和负载均衡</p>
|
||||||
|
|
||||||
|
<h4>2. 节点配置</h4>
|
||||||
|
<div class="code-block">
|
||||||
|
<pre><code class="language-yaml">spring:
|
||||||
|
lazy:
|
||||||
|
netty:
|
||||||
|
server:
|
||||||
|
mode: cluster
|
||||||
|
node-id: node-1
|
||||||
|
node-host: 192.168.1.100
|
||||||
|
node-port: 7001</code></pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h4>3. 启动集群节点</h4>
|
||||||
|
<div class="code-block">
|
||||||
|
<pre><code class="language-bash"># 启动集群服务端
|
||||||
|
cd wu-lazy-cloud-heartbeat-start/wu-lazy-cloud-heartbeat-server-cluster-start
|
||||||
|
java -jar target/wu-lazy-cloud-heartbeat-server-cluster-start-1.3.1-JDK24.jar</code></pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h4>4. 负载均衡</h4>
|
||||||
|
<ul>
|
||||||
|
<li>使用 Nginx 进行负载均衡</li>
|
||||||
|
<li>配置健康检查和故障转移</li>
|
||||||
|
<li>支持会话保持</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- System Requirements -->
|
||||||
|
<section class="system-requirements">
|
||||||
|
<div class="container">
|
||||||
|
<div class="section-header">
|
||||||
|
<h2 class="section-title">系统要求</h2>
|
||||||
|
<p class="section-subtitle">确保您的环境满足运行要求</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="requirements-grid">
|
||||||
|
<div class="requirement-card">
|
||||||
|
<div class="requirement-header">
|
||||||
|
<el-icon><Monitor /></el-icon>
|
||||||
|
<h3>操作系统</h3>
|
||||||
|
</div>
|
||||||
|
<ul>
|
||||||
|
<li>Linux (Ubuntu 18.04+, CentOS 7+)</li>
|
||||||
|
<li>Windows 10+</li>
|
||||||
|
<li>macOS 10.15+</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="requirement-card">
|
||||||
|
<div class="requirement-header">
|
||||||
|
<el-icon><Cpu /></el-icon>
|
||||||
|
<h3>Java 环境</h3>
|
||||||
|
</div>
|
||||||
|
<ul>
|
||||||
|
<li>JDK 24 (推荐)</li>
|
||||||
|
<li>JDK 17+ (最低要求)</li>
|
||||||
|
<li>JVM 内存: 512MB+</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="requirement-card">
|
||||||
|
<div class="requirement-header">
|
||||||
|
<el-icon><DataBase /></el-icon>
|
||||||
|
<h3>数据库</h3>
|
||||||
|
</div>
|
||||||
|
<ul>
|
||||||
|
<li>MySQL 8.0+ (生产环境)</li>
|
||||||
|
<li>H2 2.1+ (开发环境)</li>
|
||||||
|
<li>支持自动初始化</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="requirement-card">
|
||||||
|
<div class="requirement-header">
|
||||||
|
<el-icon><Connection /></el-icon>
|
||||||
|
<h3>网络要求</h3>
|
||||||
|
</div>
|
||||||
|
<ul>
|
||||||
|
<li>服务端需要公网 IP</li>
|
||||||
|
<li>端口 6001, 7001, 8001, 9001</li>
|
||||||
|
<li>客户端端口 6004, 8002, 9002</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<Footer />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted } from 'vue'
|
||||||
|
import Header from '@/components/Header.vue'
|
||||||
|
import Footer from '@/components/Footer.vue'
|
||||||
|
import {
|
||||||
|
Box,
|
||||||
|
Download,
|
||||||
|
Setting,
|
||||||
|
Platform,
|
||||||
|
Monitor,
|
||||||
|
Cpu,
|
||||||
|
// DataBase, // 替换 DataBase
|
||||||
|
Connection,
|
||||||
|
// Server, // 替换 Server
|
||||||
|
// Globe // 替换 Globe
|
||||||
|
} from '@element-plus/icons-vue'
|
||||||
|
|
||||||
|
const activeGlobeTab = ref('docker')
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
// 高亮代码块
|
||||||
|
if (window.Prism) {
|
||||||
|
window.Prism.highlightAll()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.download-page {
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hero Section
|
||||||
|
.hero {
|
||||||
|
padding: 120px 0 60px;
|
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
|
color: white;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
.hero-title {
|
||||||
|
font-size: 48px;
|
||||||
|
font-weight: 700;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
font-size: 32px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-subtitle {
|
||||||
|
font-size: 18px;
|
||||||
|
opacity: 0.9;
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Version Info
|
||||||
|
.version-info {
|
||||||
|
padding: 60px 0;
|
||||||
|
background: var(--background-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.version-card {
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 0 auto;
|
||||||
|
background: white;
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 40px;
|
||||||
|
box-shadow: var(--shadow-light);
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
.version-header {
|
||||||
|
margin-bottom: 30px;
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.version-badge {
|
||||||
|
display: inline-block;
|
||||||
|
background: var(--primary-color);
|
||||||
|
color: white;
|
||||||
|
padding: 8px 16px;
|
||||||
|
border-radius: 6px;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.version-details {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||||
|
gap: 20px;
|
||||||
|
|
||||||
|
.detail-item {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 12px 0;
|
||||||
|
border-bottom: 1px solid var(--border-light);
|
||||||
|
|
||||||
|
.label {
|
||||||
|
color: var(--text-regular);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value {
|
||||||
|
color: var(--text-primary);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Section Header
|
||||||
|
.section-header {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 60px;
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: 36px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 16px;
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
font-size: 28px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-subtitle {
|
||||||
|
font-size: 18px;
|
||||||
|
color: var(--text-regular);
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Download Options
|
||||||
|
.download-options {
|
||||||
|
padding: 80px 0;
|
||||||
|
background: var(--background-light);
|
||||||
|
}
|
||||||
|
|
||||||
|
.options-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
|
||||||
|
gap: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.option-card {
|
||||||
|
background: white;
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 30px;
|
||||||
|
box-shadow: var(--shadow-light);
|
||||||
|
transition: transform 0.3s ease;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
transform: translateY(-4px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.option-header {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
|
||||||
|
.option-icon {
|
||||||
|
width: 60px;
|
||||||
|
height: 60px;
|
||||||
|
background: var(--primary-color);
|
||||||
|
border-radius: 12px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin: 0 auto 16px;
|
||||||
|
|
||||||
|
.el-icon {
|
||||||
|
font-size: 28px;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
color: var(--text-regular);
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.option-content {
|
||||||
|
h4 {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style: none;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
li {
|
||||||
|
color: var(--text-regular);
|
||||||
|
margin-bottom: 6px;
|
||||||
|
position: relative;
|
||||||
|
padding-left: 16px;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: '•';
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
color: var(--primary-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.download-links {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
.download-link {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 8px 0;
|
||||||
|
border-bottom: 1px solid var(--border-light);
|
||||||
|
|
||||||
|
.link-label {
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.link-url {
|
||||||
|
color: var(--primary-color);
|
||||||
|
text-decoration: none;
|
||||||
|
font-size: 14px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.option-actions {
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deployment Globe
|
||||||
|
.deployment-guide {
|
||||||
|
padding: 80px 0;
|
||||||
|
background: var(--background-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.guide-content {
|
||||||
|
max-width: 1000px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.guide-section {
|
||||||
|
h3 {
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin: 20px 0 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style: none;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
li {
|
||||||
|
color: var(--text-regular);
|
||||||
|
margin-bottom: 6px;
|
||||||
|
position: relative;
|
||||||
|
padding-left: 16px;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: '•';
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
color: var(--primary-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
background: var(--background-light);
|
||||||
|
padding: 2px 6px;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// System Requirements
|
||||||
|
.system-requirements {
|
||||||
|
padding: 80px 0;
|
||||||
|
background: var(--background-light);
|
||||||
|
}
|
||||||
|
|
||||||
|
.requirements-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||||
|
gap: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.requirement-card {
|
||||||
|
background: white;
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 30px;
|
||||||
|
box-shadow: var(--shadow-light);
|
||||||
|
|
||||||
|
.requirement-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
.el-icon {
|
||||||
|
font-size: 24px;
|
||||||
|
color: var(--primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style: none;
|
||||||
|
|
||||||
|
li {
|
||||||
|
color: var(--text-regular);
|
||||||
|
margin-bottom: 8px;
|
||||||
|
position: relative;
|
||||||
|
padding-left: 16px;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: '✓';
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
color: var(--success-color);
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
641
website/src/views/Features.vue
Normal file
@@ -0,0 +1,641 @@
|
|||||||
|
<template>
|
||||||
|
<div class="features-page">
|
||||||
|
<Header />
|
||||||
|
|
||||||
|
<!-- Hero Section -->
|
||||||
|
<section class="hero">
|
||||||
|
<div class="container">
|
||||||
|
<div class="hero-content">
|
||||||
|
<h1 class="hero-title">功能特性</h1>
|
||||||
|
<p class="hero-subtitle">
|
||||||
|
提供完整的内网穿透和网络代理解决方案,支持多种协议和部署模式
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Features Overview -->
|
||||||
|
<section class="features-overview">
|
||||||
|
<div class="container">
|
||||||
|
<div class="features-grid">
|
||||||
|
<div class="feature-item" id="penetration">
|
||||||
|
<div class="feature-header">
|
||||||
|
<div class="feature-icon">
|
||||||
|
<el-icon><Connection /></el-icon>
|
||||||
|
</div>
|
||||||
|
<h2 class="feature-title">内网穿透</h2>
|
||||||
|
</div>
|
||||||
|
<p class="feature-description">
|
||||||
|
支持多种穿透模式,将内网服务安全地暴露到公网,实现远程访问和调试。
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="feature-details">
|
||||||
|
<h3>穿透模式</h3>
|
||||||
|
<div class="mode-grid">
|
||||||
|
<div class="mode-card">
|
||||||
|
<h4>服务端渗透客户端</h4>
|
||||||
|
<p>将内网服务映射到公网,实现远程访问</p>
|
||||||
|
<div class="code-block">
|
||||||
|
<pre><code class="language-yaml"># 配置示例
|
||||||
|
visitor_port: 19080
|
||||||
|
real_host: 192.168.1.100
|
||||||
|
real_port: 18080</code></pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mode-card">
|
||||||
|
<h4>客户端渗透服务端</h4>
|
||||||
|
<p>本地端口映射到远程服务端端口</p>
|
||||||
|
<div class="code-block">
|
||||||
|
<pre><code class="language-yaml"># 配置示例
|
||||||
|
local_port: 13306
|
||||||
|
remote_port: 3306</code></pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mode-card">
|
||||||
|
<h4>客户端渗透客户端</h4>
|
||||||
|
<p>不同网络间的端口映射,实现异地组网</p>
|
||||||
|
<div class="code-block">
|
||||||
|
<pre><code class="language-yaml"># 配置示例
|
||||||
|
client_a_port: 8080
|
||||||
|
client_b_port: 9090</code></pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="feature-item" id="proxy">
|
||||||
|
<div class="feature-header">
|
||||||
|
<div class="feature-icon">
|
||||||
|
<el-icon><Share /></el-icon>
|
||||||
|
</div>
|
||||||
|
<h2 class="feature-title">网络代理</h2>
|
||||||
|
</div>
|
||||||
|
<p class="feature-description">
|
||||||
|
提供 HTTP 和 SOCKS 代理服务,支持异地组网和网络加速。
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="feature-details">
|
||||||
|
<h3>代理类型</h3>
|
||||||
|
<div class="proxy-types">
|
||||||
|
<div class="proxy-type">
|
||||||
|
<h4>HTTP 代理</h4>
|
||||||
|
<ul>
|
||||||
|
<li>支持 HTTP/HTTPS 协议</li>
|
||||||
|
<li>可配置代理认证</li>
|
||||||
|
<li>支持流量监控</li>
|
||||||
|
<li>端口:服务端 8001,客户端 8002</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="proxy-type">
|
||||||
|
<h4>SOCKS 代理</h4>
|
||||||
|
<ul>
|
||||||
|
<li>支持 SOCKS4/SOCKS5 协议</li>
|
||||||
|
<li>支持 TCP/UDP 代理</li>
|
||||||
|
<li>可配置认证机制</li>
|
||||||
|
<li>端口:服务端 9001,客户端 9002</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="proxy-config">
|
||||||
|
<h4>代理配置示例</h4>
|
||||||
|
<div class="code-block">
|
||||||
|
<pre><code class="language-yaml">spring:
|
||||||
|
lazy:
|
||||||
|
netty:
|
||||||
|
protocol:
|
||||||
|
proxy:
|
||||||
|
authentication: true
|
||||||
|
enable-proxy-log: false
|
||||||
|
socket-protocol-proxy:
|
||||||
|
port: 9001
|
||||||
|
http-protocol-proxy:
|
||||||
|
port: 8001</code></pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="feature-item" id="monitor">
|
||||||
|
<div class="feature-header">
|
||||||
|
<div class="feature-icon">
|
||||||
|
<el-icon><DataAnalysis /></el-icon>
|
||||||
|
</div>
|
||||||
|
<h2 class="feature-title">流量监控</h2>
|
||||||
|
</div>
|
||||||
|
<p class="feature-description">
|
||||||
|
实时监控网络流量使用情况,提供详细的统计报表和分析。
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="feature-details">
|
||||||
|
<h3>监控功能</h3>
|
||||||
|
<div class="monitor-features">
|
||||||
|
<div class="monitor-feature">
|
||||||
|
<h4>实时监控</h4>
|
||||||
|
<ul>
|
||||||
|
<li>监控每个客户端的实时流量</li>
|
||||||
|
<li>按端口统计流量使用情况</li>
|
||||||
|
<li>提供流量趋势图表</li>
|
||||||
|
<li>支持流量告警设置</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="monitor-feature">
|
||||||
|
<h4>报表功能</h4>
|
||||||
|
<ul>
|
||||||
|
<li>日流量统计报表</li>
|
||||||
|
<li>客户端流量排行</li>
|
||||||
|
<li>端口使用情况分析</li>
|
||||||
|
<li>历史数据查询</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="monitor-stats">
|
||||||
|
<h4>监控指标</h4>
|
||||||
|
<div class="stats-grid">
|
||||||
|
<div class="stat-card">
|
||||||
|
<div class="stat-value">10,000+</div>
|
||||||
|
<div class="stat-label">并发连接</div>
|
||||||
|
</div>
|
||||||
|
<div class="stat-card">
|
||||||
|
<div class="stat-value">< 10ms</div>
|
||||||
|
<div class="stat-label">平均响应时间</div>
|
||||||
|
</div>
|
||||||
|
<div class="stat-card">
|
||||||
|
<div class="stat-value">99.9%</div>
|
||||||
|
<div class="stat-label">系统可用性</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="feature-item" id="route">
|
||||||
|
<div class="feature-header">
|
||||||
|
<div class="feature-icon">
|
||||||
|
<el-icon><Setting /></el-icon>
|
||||||
|
</div>
|
||||||
|
<h2 class="feature-title">路由管理</h2>
|
||||||
|
</div>
|
||||||
|
<p class="feature-description">
|
||||||
|
支持虚拟路由和流量转发,实现灵活的网络配置。
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="feature-details">
|
||||||
|
<h3>路由功能</h3>
|
||||||
|
<div class="route-features">
|
||||||
|
<div class="route-feature">
|
||||||
|
<h4>虚拟 IP 路由</h4>
|
||||||
|
<p>创建虚拟 IP 地址,将流量代理到目标地址</p>
|
||||||
|
<div class="code-block">
|
||||||
|
<pre><code class="language-yaml"># 虚拟路由配置
|
||||||
|
virtual_ip: 10.0.0.100
|
||||||
|
target_host: 192.168.1.100
|
||||||
|
target_port: 8080</code></pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="route-feature">
|
||||||
|
<h4>流量转发规则</h4>
|
||||||
|
<ul>
|
||||||
|
<li>支持基于端口的转发</li>
|
||||||
|
<li>支持基于协议的转发</li>
|
||||||
|
<li>支持负载均衡</li>
|
||||||
|
<li>支持故障转移</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Security Features -->
|
||||||
|
<section class="security-features">
|
||||||
|
<div class="container">
|
||||||
|
<div class="section-header">
|
||||||
|
<h2 class="section-title">安全特性</h2>
|
||||||
|
<p class="section-subtitle">多重安全机制,保障数据传输和访问安全</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="security-grid">
|
||||||
|
<div class="security-card">
|
||||||
|
<div class="security-icon">
|
||||||
|
<el-icon><Lock /></el-icon>
|
||||||
|
</div>
|
||||||
|
<h3>认证机制</h3>
|
||||||
|
<ul>
|
||||||
|
<li>Token 认证</li>
|
||||||
|
<li>AppKey/AppSecret 认证</li>
|
||||||
|
<li>代理认证</li>
|
||||||
|
<li>动态密钥管理</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="security-card">
|
||||||
|
<div class="security-icon">
|
||||||
|
<el-icon><Key /></el-icon>
|
||||||
|
</div>
|
||||||
|
<h3>加密传输</h3>
|
||||||
|
<ul>
|
||||||
|
<li>SSL/TLS 加密</li>
|
||||||
|
<li>流量加密传输</li>
|
||||||
|
<li>敏感信息加密存储</li>
|
||||||
|
<li>支持自定义加密算法</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="security-card">
|
||||||
|
<div class="security-icon">
|
||||||
|
<el-icon><User /></el-icon>
|
||||||
|
</div>
|
||||||
|
<h3>访问控制</h3>
|
||||||
|
<ul>
|
||||||
|
<li>基于角色的权限控制</li>
|
||||||
|
<li>细粒度权限管理</li>
|
||||||
|
<li>操作审计日志</li>
|
||||||
|
<li>访问白名单</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<Footer />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { onMounted } from 'vue'
|
||||||
|
import Header from '@/components/Header.vue'
|
||||||
|
import Footer from '@/components/Footer.vue'
|
||||||
|
import {
|
||||||
|
Connection,
|
||||||
|
Share,
|
||||||
|
DataAnalysis,
|
||||||
|
Setting,
|
||||||
|
Lock,
|
||||||
|
Key,
|
||||||
|
User
|
||||||
|
} from '@element-plus/icons-vue'
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
// 高亮代码块
|
||||||
|
if (window.Prism) {
|
||||||
|
window.Prism.highlightAll()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.features-page {
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hero Section
|
||||||
|
.hero {
|
||||||
|
padding: 120px 0 60px;
|
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
|
color: white;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
.hero-title {
|
||||||
|
font-size: 48px;
|
||||||
|
font-weight: 700;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
font-size: 32px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-subtitle {
|
||||||
|
font-size: 18px;
|
||||||
|
opacity: 0.9;
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Features Overview
|
||||||
|
.features-overview {
|
||||||
|
padding: 80px 0;
|
||||||
|
background: var(--background-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.features-grid {
|
||||||
|
max-width: 1000px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.feature-item {
|
||||||
|
margin-bottom: 80px;
|
||||||
|
|
||||||
|
.feature-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 16px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
.feature-icon {
|
||||||
|
width: 60px;
|
||||||
|
height: 60px;
|
||||||
|
background: var(--primary-color);
|
||||||
|
border-radius: 12px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
.el-icon {
|
||||||
|
font-size: 28px;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.feature-title {
|
||||||
|
font-size: 32px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: var(--text-primary);
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.feature-description {
|
||||||
|
font-size: 18px;
|
||||||
|
color: var(--text-regular);
|
||||||
|
line-height: 1.6;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.feature-details {
|
||||||
|
h3 {
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mode Grid
|
||||||
|
.mode-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||||
|
gap: 20px;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mode-card {
|
||||||
|
background: var(--background-light);
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 20px;
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
color: var(--text-regular);
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Proxy Types
|
||||||
|
.proxy-types {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||||
|
gap: 30px;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.proxy-type {
|
||||||
|
h4 {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style: none;
|
||||||
|
|
||||||
|
li {
|
||||||
|
color: var(--text-regular);
|
||||||
|
margin-bottom: 6px;
|
||||||
|
position: relative;
|
||||||
|
padding-left: 16px;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: '✓';
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
color: var(--success-color);
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Monitor Features
|
||||||
|
.monitor-features {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||||
|
gap: 30px;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.monitor-feature {
|
||||||
|
h4 {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style: none;
|
||||||
|
|
||||||
|
li {
|
||||||
|
color: var(--text-regular);
|
||||||
|
margin-bottom: 6px;
|
||||||
|
position: relative;
|
||||||
|
padding-left: 16px;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: '✓';
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
color: var(--success-color);
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stats Grid
|
||||||
|
.stats-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||||
|
gap: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card {
|
||||||
|
text-align: center;
|
||||||
|
padding: 20px;
|
||||||
|
background: var(--background-light);
|
||||||
|
border-radius: 8px;
|
||||||
|
|
||||||
|
.stat-value {
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: var(--primary-color);
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-label {
|
||||||
|
color: var(--text-regular);
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Route Features
|
||||||
|
.route-features {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||||
|
gap: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.route-feature {
|
||||||
|
h4 {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
color: var(--text-regular);
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style: none;
|
||||||
|
|
||||||
|
li {
|
||||||
|
color: var(--text-regular);
|
||||||
|
margin-bottom: 6px;
|
||||||
|
position: relative;
|
||||||
|
padding-left: 16px;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: '✓';
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
color: var(--success-color);
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Security Features
|
||||||
|
.security-features {
|
||||||
|
padding: 80px 0;
|
||||||
|
background: var(--background-light);
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-header {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 60px;
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: 36px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 16px;
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
font-size: 28px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-subtitle {
|
||||||
|
font-size: 18px;
|
||||||
|
color: var(--text-regular);
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.security-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||||
|
gap: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.security-card {
|
||||||
|
background: white;
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 30px;
|
||||||
|
box-shadow: var(--shadow-light);
|
||||||
|
transition: transform 0.3s ease;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
transform: translateY(-4px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.security-icon {
|
||||||
|
width: 60px;
|
||||||
|
height: 60px;
|
||||||
|
background: var(--primary-color);
|
||||||
|
border-radius: 12px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
.el-icon {
|
||||||
|
font-size: 28px;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style: none;
|
||||||
|
|
||||||
|
li {
|
||||||
|
color: var(--text-regular);
|
||||||
|
margin-bottom: 8px;
|
||||||
|
position: relative;
|
||||||
|
padding-left: 16px;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: '✓';
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
color: var(--success-color);
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
649
website/src/views/Home.vue
Normal file
@@ -0,0 +1,649 @@
|
|||||||
|
<template>
|
||||||
|
<div class="home">
|
||||||
|
<Header />
|
||||||
|
|
||||||
|
<!-- Hero Section -->
|
||||||
|
<section class="hero">
|
||||||
|
<div class="container">
|
||||||
|
<div class="hero-content">
|
||||||
|
<div class="hero-text">
|
||||||
|
<h1 class="hero-title">
|
||||||
|
高性能网络穿透和代理工具
|
||||||
|
</h1>
|
||||||
|
<p class="hero-subtitle">
|
||||||
|
基于 Spring Boot 3.5.0 和 JDK 24 开发,支持 TCP、HTTP、SOCKS 协议,
|
||||||
|
提供完整的内网穿透、网络代理、流量监控等功能。
|
||||||
|
</p>
|
||||||
|
<div class="hero-actions">
|
||||||
|
<router-link to="/download" class="btn btn-primary btn-large">
|
||||||
|
<el-icon><Download /></el-icon>
|
||||||
|
立即下载
|
||||||
|
</router-link>
|
||||||
|
<router-link to="/docs" class="btn btn-outline btn-large">
|
||||||
|
<el-icon><Document /></el-icon>
|
||||||
|
查看文档
|
||||||
|
</router-link>
|
||||||
|
</div>
|
||||||
|
<div class="hero-stats">
|
||||||
|
<div class="stat-item">
|
||||||
|
<div class="stat-number">1.3.1</div>
|
||||||
|
<div class="stat-label">当前版本</div>
|
||||||
|
</div>
|
||||||
|
<div class="stat-item">
|
||||||
|
<div class="stat-number">JDK 24</div>
|
||||||
|
<div class="stat-label">技术栈</div>
|
||||||
|
</div>
|
||||||
|
<div class="stat-item">
|
||||||
|
<div class="stat-number">10K+</div>
|
||||||
|
<div class="stat-label">并发连接</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="hero-visual">
|
||||||
|
<div class="network-diagram">
|
||||||
|
<div class="client-node">
|
||||||
|
<el-icon><Monitor /></el-icon>
|
||||||
|
<span>客户端</span>
|
||||||
|
</div>
|
||||||
|
<div class="connection-line"></div>
|
||||||
|
<div class="server-node">
|
||||||
|
<el-icon><Server /></el-icon>
|
||||||
|
<span>服务端</span>
|
||||||
|
</div>
|
||||||
|
<div class="connection-line"></div>
|
||||||
|
<div class="internet-node">
|
||||||
|
<el-icon><Globe /></el-icon>
|
||||||
|
<span>公网</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Features Section -->
|
||||||
|
<section class="features">
|
||||||
|
<div class="container">
|
||||||
|
<div class="section-header">
|
||||||
|
<h2 class="section-title">核心功能</h2>
|
||||||
|
<p class="section-subtitle">提供完整的内网穿透和网络代理解决方案</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="features-grid">
|
||||||
|
<div class="feature-card card card-hover">
|
||||||
|
<div class="feature-icon">
|
||||||
|
<el-icon><Connection /></el-icon>
|
||||||
|
</div>
|
||||||
|
<h3 class="feature-title">内网穿透</h3>
|
||||||
|
<p class="feature-description">
|
||||||
|
支持多种穿透模式,将内网服务安全地暴露到公网,实现远程访问和调试。
|
||||||
|
</p>
|
||||||
|
<ul class="feature-list">
|
||||||
|
<li>服务端渗透客户端</li>
|
||||||
|
<li>客户端渗透服务端</li>
|
||||||
|
<li>客户端渗透客户端</li>
|
||||||
|
<li>支持 TCP/HTTP 协议</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="feature-card card card-hover">
|
||||||
|
<div class="feature-icon">
|
||||||
|
<el-icon><Share /></el-icon>
|
||||||
|
</div>
|
||||||
|
<h3 class="feature-title">网络代理</h3>
|
||||||
|
<p class="feature-description">
|
||||||
|
提供 HTTP 和 SOCKS 代理服务,支持异地组网和网络加速。
|
||||||
|
</p>
|
||||||
|
<ul class="feature-list">
|
||||||
|
<li>HTTP/HTTPS 代理</li>
|
||||||
|
<li>SOCKS4/SOCKS5 代理</li>
|
||||||
|
<li>代理认证支持</li>
|
||||||
|
<li>流量加密传输</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="feature-card card card-hover">
|
||||||
|
<div class="feature-icon">
|
||||||
|
<el-icon><DataAnalysis /></el-icon>
|
||||||
|
</div>
|
||||||
|
<h3 class="feature-title">流量监控</h3>
|
||||||
|
<p class="feature-description">
|
||||||
|
实时监控网络流量使用情况,提供详细的统计报表和分析。
|
||||||
|
</p>
|
||||||
|
<ul class="feature-list">
|
||||||
|
<li>实时流量统计</li>
|
||||||
|
<li>客户端流量排行</li>
|
||||||
|
<li>端口使用分析</li>
|
||||||
|
<li>流量趋势图表</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="feature-card card card-hover">
|
||||||
|
<div class="feature-icon">
|
||||||
|
<el-icon><Setting /></el-icon>
|
||||||
|
</div>
|
||||||
|
<h3 class="feature-title">路由管理</h3>
|
||||||
|
<p class="feature-description">
|
||||||
|
支持虚拟路由和流量转发,实现灵活的网络配置。
|
||||||
|
</p>
|
||||||
|
<ul class="feature-list">
|
||||||
|
<li>虚拟 IP 路由</li>
|
||||||
|
<li>流量转发规则</li>
|
||||||
|
<li>智能路由选择</li>
|
||||||
|
<li>负载均衡支持</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Technology Section -->
|
||||||
|
<section class="technology">
|
||||||
|
<div class="container">
|
||||||
|
<div class="section-header">
|
||||||
|
<h2 class="section-title">技术架构</h2>
|
||||||
|
<p class="section-subtitle">基于现代化的技术栈,提供高性能和可靠性</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tech-grid">
|
||||||
|
<div class="tech-item">
|
||||||
|
<div class="tech-icon">
|
||||||
|
<el-icon><Monitor /></el-icon>
|
||||||
|
</div>
|
||||||
|
<h4>Spring Boot 3.5.0</h4>
|
||||||
|
<p>现代化的应用框架,提供快速开发和部署能力</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tech-item">
|
||||||
|
<div class="tech-icon">
|
||||||
|
<el-icon><Connection /></el-icon>
|
||||||
|
</div>
|
||||||
|
<h4>Netty</h4>
|
||||||
|
<p>高性能异步网络框架,支持高并发连接处理</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tech-item">
|
||||||
|
<div class="tech-icon">
|
||||||
|
<el-icon><DataBase /></el-icon>
|
||||||
|
</div>
|
||||||
|
<h4>Lazy ORM</h4>
|
||||||
|
<p>轻量级 ORM 框架,提供类型安全的数据库操作</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tech-item">
|
||||||
|
<div class="tech-icon">
|
||||||
|
<el-icon><Cpu /></el-icon>
|
||||||
|
</div>
|
||||||
|
<h4>JDK 24</h4>
|
||||||
|
<p>最新的 Java 开发工具包,提供优秀的性能表现</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Quick Start Section -->
|
||||||
|
<section class="quick-start">
|
||||||
|
<div class="container">
|
||||||
|
<div class="section-header">
|
||||||
|
<h2 class="section-title">快速开始</h2>
|
||||||
|
<p class="section-subtitle">几分钟内完成部署和配置</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="start-steps">
|
||||||
|
<div class="step-item">
|
||||||
|
<div class="step-number">1</div>
|
||||||
|
<div class="step-content">
|
||||||
|
<h4>启动服务端</h4>
|
||||||
|
<div class="code-block">
|
||||||
|
<pre><code class="language-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</code></pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="step-item">
|
||||||
|
<div class="step-number">2</div>
|
||||||
|
<div class="step-content">
|
||||||
|
<h4>启动客户端</h4>
|
||||||
|
<div class="code-block">
|
||||||
|
<pre><code class="language-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</code></pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="step-item">
|
||||||
|
<div class="step-number">3</div>
|
||||||
|
<div class="step-content">
|
||||||
|
<h4>访问管理界面</h4>
|
||||||
|
<div class="code-block">
|
||||||
|
<pre><code class="language-bash"># 服务端管理界面
|
||||||
|
http://127.0.0.1:6001/netty-server-ui/index.html
|
||||||
|
|
||||||
|
# 客户端管理界面
|
||||||
|
http://127.0.0.1:6004/netty-client-local-ui/index.html</code></pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="start-actions">
|
||||||
|
<router-link to="/docs" class="btn btn-primary btn-large">
|
||||||
|
<el-icon><Document /></el-icon>
|
||||||
|
查看详细文档
|
||||||
|
</router-link>
|
||||||
|
<a href="https://gitee.com/wujiawei1207537021/wu-lazy-cloud-network" target="_blank" class="btn btn-outline btn-large">
|
||||||
|
<el-icon><Platform /></el-icon>
|
||||||
|
访问 GitHub
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- CTA Section -->
|
||||||
|
<section class="cta">
|
||||||
|
<div class="container">
|
||||||
|
<div class="cta-content">
|
||||||
|
<h2 class="cta-title">开始使用 Wu-Lazy-Cloud-Network</h2>
|
||||||
|
<p class="cta-subtitle">
|
||||||
|
加入数千名开发者,体验高性能的网络穿透和代理服务
|
||||||
|
</p>
|
||||||
|
<div class="cta-actions">
|
||||||
|
<router-link to="/download" class="btn btn-primary btn-large">
|
||||||
|
<el-icon><Download /></el-icon>
|
||||||
|
立即下载
|
||||||
|
</router-link>
|
||||||
|
<router-link to="/docs" class="btn btn-outline btn-large">
|
||||||
|
<el-icon><Document /></el-icon>
|
||||||
|
查看文档
|
||||||
|
</router-link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<Footer />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { onMounted } from 'vue'
|
||||||
|
import Header from '@/components/Header.vue'
|
||||||
|
import Footer from '@/components/Footer.vue'
|
||||||
|
import {
|
||||||
|
Download,
|
||||||
|
Document,
|
||||||
|
Connection,
|
||||||
|
Share,
|
||||||
|
DataAnalysis,
|
||||||
|
Setting,
|
||||||
|
Monitor,
|
||||||
|
// Server,
|
||||||
|
// Globe,
|
||||||
|
// DataBase,
|
||||||
|
Cpu,
|
||||||
|
Platform
|
||||||
|
} from '@element-plus/icons-vue'
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
// 高亮代码块
|
||||||
|
if (window.Prism) {
|
||||||
|
window.Prism.highlightAll()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.home {
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hero Section
|
||||||
|
.hero {
|
||||||
|
padding: 120px 0 80px;
|
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
|
color: white;
|
||||||
|
|
||||||
|
.hero-content {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 60px;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
gap: 40px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-title {
|
||||||
|
font-size: 48px;
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 1.2;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
font-size: 32px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-subtitle {
|
||||||
|
font-size: 18px;
|
||||||
|
line-height: 1.6;
|
||||||
|
margin-bottom: 32px;
|
||||||
|
opacity: 0.9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 16px;
|
||||||
|
margin-bottom: 40px;
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-stats {
|
||||||
|
display: flex;
|
||||||
|
gap: 40px;
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
gap: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-item {
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
.stat-number {
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 700;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-label {
|
||||||
|
font-size: 14px;
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-visual {
|
||||||
|
.network-diagram {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 20px;
|
||||||
|
|
||||||
|
.client-node,
|
||||||
|
.server-node,
|
||||||
|
.internet-node {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 20px;
|
||||||
|
background: rgba(255, 255, 255, 0.1);
|
||||||
|
border-radius: 12px;
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
|
||||||
|
.el-icon {
|
||||||
|
font-size: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.connection-line {
|
||||||
|
width: 40px;
|
||||||
|
height: 2px;
|
||||||
|
background: rgba(255, 255, 255, 0.3);
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: -3px;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
border-left: 6px solid rgba(255, 255, 255, 0.3);
|
||||||
|
border-top: 4px solid transparent;
|
||||||
|
border-bottom: 4px solid transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Features Section
|
||||||
|
.features {
|
||||||
|
padding: 80px 0;
|
||||||
|
background: var(--background-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-header {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 60px;
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: 36px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 16px;
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
font-size: 28px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-subtitle {
|
||||||
|
font-size: 18px;
|
||||||
|
color: var(--text-regular);
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.features-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
||||||
|
gap: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.feature-card {
|
||||||
|
.feature-icon {
|
||||||
|
width: 60px;
|
||||||
|
height: 60px;
|
||||||
|
background: var(--primary-color);
|
||||||
|
border-radius: 12px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
.el-icon {
|
||||||
|
font-size: 28px;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.feature-title {
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.feature-description {
|
||||||
|
color: var(--text-regular);
|
||||||
|
line-height: 1.6;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.feature-list {
|
||||||
|
list-style: none;
|
||||||
|
|
||||||
|
li {
|
||||||
|
color: var(--text-regular);
|
||||||
|
margin-bottom: 6px;
|
||||||
|
position: relative;
|
||||||
|
padding-left: 16px;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: '✓';
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
color: var(--success-color);
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Technology Section
|
||||||
|
.technology {
|
||||||
|
padding: 80px 0;
|
||||||
|
background: var(--background-light);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tech-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
||||||
|
gap: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tech-item {
|
||||||
|
text-align: center;
|
||||||
|
padding: 30px;
|
||||||
|
|
||||||
|
.tech-icon {
|
||||||
|
width: 80px;
|
||||||
|
height: 80px;
|
||||||
|
background: white;
|
||||||
|
border-radius: 16px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin: 0 auto 20px;
|
||||||
|
box-shadow: var(--shadow-light);
|
||||||
|
|
||||||
|
.el-icon {
|
||||||
|
font-size: 36px;
|
||||||
|
color: var(--primary-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
color: var(--text-regular);
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Quick Start Section
|
||||||
|
.quick-start {
|
||||||
|
padding: 80px 0;
|
||||||
|
background: var(--background-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.start-steps {
|
||||||
|
max-width: 800px;
|
||||||
|
margin: 0 auto 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step-item {
|
||||||
|
display: flex;
|
||||||
|
gap: 20px;
|
||||||
|
margin-bottom: 40px;
|
||||||
|
|
||||||
|
.step-number {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
background: var(--primary-color);
|
||||||
|
color: white;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-weight: 600;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step-content {
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.start-actions {
|
||||||
|
text-align: center;
|
||||||
|
display: flex;
|
||||||
|
gap: 16px;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CTA Section
|
||||||
|
.cta {
|
||||||
|
padding: 80px 0;
|
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
|
color: white;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
.cta-title {
|
||||||
|
font-size: 36px;
|
||||||
|
font-weight: 700;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
font-size: 28px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta-subtitle {
|
||||||
|
font-size: 18px;
|
||||||
|
opacity: 0.9;
|
||||||
|
margin-bottom: 32px;
|
||||||
|
max-width: 600px;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 16px;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
30
website/vite.config.js
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import { defineConfig } from 'vite'
|
||||||
|
import vue from '@vitejs/plugin-vue'
|
||||||
|
import { resolve } from 'path'
|
||||||
|
import viteCompression from 'vite-plugin-compression'
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [vue(), viteCompression()],
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
'@': resolve(__dirname, 'src')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
server: {
|
||||||
|
port: 3000,
|
||||||
|
open: true
|
||||||
|
},
|
||||||
|
build: {
|
||||||
|
outDir: 'dist',
|
||||||
|
assetsDir: 'assets',
|
||||||
|
sourcemap: false,
|
||||||
|
rollupOptions: {
|
||||||
|
output: {
|
||||||
|
manualChunks: {
|
||||||
|
vendor: ['vue', 'vue-router', 'pinia'],
|
||||||
|
elementPlus: ['element-plus', '@element-plus/icons-vue']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
BIN
windows_wifi_proxy.png
Normal file
|
After Width: | Height: | Size: 309 KiB |
BIN
wlcn-proxy1.0-.png
Normal file
|
After Width: | Height: | Size: 76 KiB |
84
wlcn-proxy1.0.puml
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
|
||||||
|
|
||||||
|
@startuml
|
||||||
|
|
||||||
|
title 网络代理
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
package "服务端" as "服务端"{
|
||||||
|
node "12.16.5.xx"{
|
||||||
|
[12.16.5.1]
|
||||||
|
[wlcn_s_a] as "wlcn服务端"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
package "杭州客户端"{
|
||||||
|
node "172.16.5.xx"{
|
||||||
|
[172.16.5.1]
|
||||||
|
[wlcn_c_a] as "wlcn客户端9001"
|
||||||
|
|
||||||
|
|
||||||
|
actor Navicat_c_a as "本地Navicat"
|
||||||
|
actor App_c_a as "本地App"
|
||||||
|
actor Chrome_c_a as "本地浏览器"
|
||||||
|
[socks_proxy_a] as "杭州本地用户socks代理软件"
|
||||||
|
|
||||||
|
[socks_proxy_a]<--up--> [wlcn_c_a]:访客通过软件代理本地socks网络
|
||||||
|
|
||||||
|
[Navicat_c_a]<..up..> [socks_proxy_a]:访问服务端所在网段(12.16.5.xx)
|
||||||
|
[App_c_a]<..up..> [socks_proxy_a]:访问访问本地所在网段(172.16.5.xx)
|
||||||
|
[Chrome_c_a]<..up..> [socks_proxy_a]:访问访问另一个客户端所在网段(162.16.5.xx)
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
package "上海客户端" as "上海客户端"{
|
||||||
|
|
||||||
|
node "162.16.5.xx"{
|
||||||
|
[162.16.5.1]
|
||||||
|
[wlcn_c_b] as "wlcn客户端9001"
|
||||||
|
|
||||||
|
actor Navicat_c_b as "本地Navicat"
|
||||||
|
actor App_c_b as "本地App"
|
||||||
|
actor Chrome_c_b as "本地浏览器"
|
||||||
|
[socks_proxy_b] as "上海本地用户socks代理软件"
|
||||||
|
|
||||||
|
[socks_proxy_b]<--up--> [wlcn_c_b]:访客通过软件代理本地socks网络
|
||||||
|
|
||||||
|
[Navicat_c_b]<..up..> [socks_proxy_b]:访问服务端所在网段(12.16.5.xx)
|
||||||
|
[App_c_b]<..up..> [socks_proxy_b]:访问访问本地所在网段(172.16.5.xx)
|
||||||
|
[Chrome_c_b]<..up..> [socks_proxy_b]:访问访问另一个客户端所在网段(162.16.5.xx)
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
package "第三方局域网"{
|
||||||
|
|
||||||
|
node "152.16.5.xx"{
|
||||||
|
[152.16.5.1]
|
||||||
|
|
||||||
|
actor Navicat_c_c as "本地Navicat"
|
||||||
|
actor App_c_c as "本地App"
|
||||||
|
actor Chrome_c_c as "本地浏览器"
|
||||||
|
[socks_proxy_c] as "上海本地用户socks代理软件"
|
||||||
|
|
||||||
|
|
||||||
|
[Navicat_c_c]<..up..> [socks_proxy_c]:访问服务端所在网段(12.16.5.xx)
|
||||||
|
[App_c_c]<..up..> [socks_proxy_c]:访问访问上海在网段(172.16.5.xx)
|
||||||
|
[Chrome_c_c]<..up..> [socks_proxy_c]:访问访问杭州客户端所在网段(162.16.5.xx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[wlcn_s_a] <==down==> [wlcn_c_a]: 客户端连接服务端
|
||||||
|
[wlcn_s_a] <==down==> [wlcn_c_b]: 客户端连接服务端
|
||||||
|
[wlcn_s_a]<--down--> [socks_proxy_c]:访客通过软件代理本地socks网络
|
||||||
|
|
||||||
|
|
||||||
|
@enduml
|
||||||
@@ -10,8 +10,8 @@ mvn native:build -Pnative
|
|||||||
### 构建docker镜像
|
### 构建docker镜像
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
docker build -t docker-registry.wujiawei.com/lazy/lazy-under-cloud-heartbeat-client:lazy-2.4.2-native-SNAPSHOT_latest -f Native-Dockerfile .
|
docker build -t docker-registry.wujiawei.com/lazy/lazy-under-cloud-heartbeat-client:lazy-2.4.2-NATIVE-SNAPSHOT_latest -f Native-Dockerfile .
|
||||||
docker push docker-registry.wujiawei.com/lazy/lazy-under-cloud-heartbeat-client:lazy-2.4.2-native-SNAPSHOT_latest
|
docker push docker-registry.wujiawei.com/lazy/lazy-under-cloud-heartbeat-client:lazy-2.4.2-NATIVE-SNAPSHOT_latest
|
||||||
```
|
```
|
||||||
|
|
||||||
## BUILD IMAGE
|
## BUILD IMAGE
|
||||||
|
|||||||
@@ -5,16 +5,36 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>top.wu2020</groupId>
|
<groupId>top.wu2020</groupId>
|
||||||
<artifactId>wu-lazy-cloud-network</artifactId>
|
<artifactId>wu-lazy-cloud-network</artifactId>
|
||||||
<version>1.2.8-JDK17-SNAPSHOT</version>
|
<version>1.3.4-JDK24-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<artifactId>wu-lazy-cloud-heartbeat-client</artifactId>
|
<artifactId>wu-lazy-cloud-heartbeat-client</artifactId>
|
||||||
<description>云下心跳客户端</description>
|
<description>云下心跳客户端</description>
|
||||||
|
|
||||||
|
<name>wlcn客户端模块</name>
|
||||||
|
<url>https://gitee.com/wujiawei1207537021/wu-lazy-cloud-network</url>
|
||||||
|
<!-->开发者的信息<-->
|
||||||
|
<developers>
|
||||||
|
<developer>
|
||||||
|
<name>Jia Wei Wu</name>
|
||||||
|
<email>1207537021@qq.com</email>
|
||||||
|
</developer>
|
||||||
|
</developers>
|
||||||
|
<licenses>
|
||||||
|
<license>
|
||||||
|
<name>Apache License, Version 2.0</name>
|
||||||
|
<url>https://www.apache.org/licenses/LICENSE-2.0</url>
|
||||||
|
<distribution>repo</distribution>
|
||||||
|
</license>
|
||||||
|
</licenses>
|
||||||
|
<!-->项目的版本管理地址<-->
|
||||||
|
<scm>
|
||||||
|
<url>https://gitee.com/wujiawei1207537021/wu-lazy-cloud-network</url>
|
||||||
|
</scm>
|
||||||
<properties>
|
<properties>
|
||||||
<maven.compiler.source>17</maven.compiler.source>
|
<maven.compiler.source>24</maven.compiler.source>
|
||||||
<maven.compiler.target>17</maven.compiler.target>
|
<maven.compiler.target>24</maven.compiler.target>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
@@ -22,25 +42,34 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>top.wu2020</groupId>
|
<groupId>top.wu2020</groupId>
|
||||||
<artifactId>wu-lazy-cloud-heartbeat-common</artifactId>
|
<artifactId>wu-lazy-cloud-heartbeat-common</artifactId>
|
||||||
|
<version>${wu-lazy-cloud-heartbeat-common.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>top.wu2020</groupId>
|
||||||
|
<artifactId>wu-lazy-cloud-heartbeat-protocol-proxy</artifactId>
|
||||||
|
<version>${wu-lazy-cloud-heartbeat-protocol-proxy.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.alibaba</groupId>
|
<groupId>com.alibaba</groupId>
|
||||||
<artifactId>fastjson</artifactId>
|
<artifactId>fastjson</artifactId>
|
||||||
<version>2.0.50</version>
|
<version>2.0.50</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>top.wu2020</groupId>
|
|
||||||
<artifactId>wu-framework-web-spring-starter</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- h2数据库驱动 -->
|
<!-- h2数据库驱动 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.h2database</groupId>
|
<groupId>com.h2database</groupId>
|
||||||
<artifactId>h2</artifactId>
|
<artifactId>h2</artifactId>
|
||||||
|
<version>2.3.232</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>top.wu2020</groupId>
|
<groupId>top.wu2020</groupId>
|
||||||
<artifactId>wu-database-lazy-plus-starter</artifactId>
|
<artifactId>wu-framework-web-spring-starter</artifactId>
|
||||||
|
<version>${wu-framework-web-spring-starter.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>top.wu2020</groupId>
|
||||||
|
<artifactId>wu-database-lazy-orm-plus-starter</artifactId>
|
||||||
|
<version>${wu-database-lazy-orm-plus-starter.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|||||||
@@ -5,5 +5,5 @@ import org.wu.framework.lazy.orm.core.stereotype.LazyScan;
|
|||||||
|
|
||||||
@ComponentScan(basePackages = "org.framework.lazy.cloud.network.heartbeat.client")
|
@ComponentScan(basePackages = "org.framework.lazy.cloud.network.heartbeat.client")
|
||||||
@LazyScan(scanBasePackages = "org.framework.lazy.cloud.network.heartbeat.client.infrastructure.entity")
|
@LazyScan(scanBasePackages = "org.framework.lazy.cloud.network.heartbeat.client.infrastructure.entity")
|
||||||
public class EnableHeartbeatClientAutoConfiguration {
|
public class EnableClientAutoConfiguration {
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package org.framework.lazy.cloud.network.heartbeat.client.application;
|
package org.framework.lazy.cloud.network.heartbeat.client.application;
|
||||||
|
|
||||||
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.client.netty.event.ClientChangeEvent;
|
import org.framework.lazy.cloud.network.heartbeat.client.netty.permeate.event.ClientChangeEvent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 客户端状态变更事件
|
* 客户端状态变更事件
|
||||||
|
|||||||
@@ -7,87 +7,86 @@ import org.framework.lazy.cloud.network.heartbeat.client.application.command.laz
|
|||||||
import org.framework.lazy.cloud.network.heartbeat.client.application.command.lazy.netty.server.properties.LazyNettyServerPropertiesQueryListCommand;
|
import org.framework.lazy.cloud.network.heartbeat.client.application.command.lazy.netty.server.properties.LazyNettyServerPropertiesQueryListCommand;
|
||||||
import org.framework.lazy.cloud.network.heartbeat.client.application.command.lazy.netty.server.properties.LazyNettyServerPropertiesQueryOneCommand;
|
import org.framework.lazy.cloud.network.heartbeat.client.application.command.lazy.netty.server.properties.LazyNettyServerPropertiesQueryOneCommand;
|
||||||
import org.framework.lazy.cloud.network.heartbeat.client.application.dto.LazyNettyServerPropertiesDTO;
|
import org.framework.lazy.cloud.network.heartbeat.client.application.dto.LazyNettyServerPropertiesDTO;
|
||||||
import org.mapstruct.factory.Mappers;
|
import org.wu.framework.core.mapper.LazyStructMappers;
|
||||||
import org.mapstruct.Mapper;
|
import org.wu.framework.core.mapper.LazyStructMapper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* describe 服务端配置信息
|
* describe 服务端配置信息
|
||||||
*
|
*
|
||||||
* @author Jia wei Wu
|
* @author Jia wei Wu
|
||||||
* @date 2024/04/03 03:00 下午
|
* @date 2024/04/03 03:00 下午
|
||||||
* @see org.wu.framework.lazy.orm.core.persistence.reverse.lazy.ddd.DefaultDDDLazyAssembler
|
* @see org.wu.framework.lazy.orm.core.persistence.reverse.lazy.ddd.DefaultDDDLazyAssembler
|
||||||
**/
|
**/
|
||||||
@Mapper
|
@LazyStructMapper
|
||||||
public interface LazyNettyServerPropertiesDTOAssembler {
|
public interface LazyNettyServerPropertiesDTOAssembler {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* describe MapStruct 创建的代理对象
|
* describe MapStruct 创建的代理对象
|
||||||
*
|
*
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
* @author Jia wei Wu
|
* @author Jia wei Wu
|
||||||
* @date 2024/04/03 03:00 下午
|
* @date 2024/04/03 03:00 下午
|
||||||
**/
|
**/
|
||||||
LazyNettyServerPropertiesDTOAssembler INSTANCE = Mappers.getMapper(LazyNettyServerPropertiesDTOAssembler.class);
|
LazyNettyServerPropertiesDTOAssembler INSTANCE = LazyStructMappers.getMapper(LazyNettyServerPropertiesDTOAssembler.class);
|
||||||
|
// LazyNettyServerPropertiesDTOAssembler INSTANCE = new LazyNettyServerPropertiesDTOAssemblerImpl();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* describe 应用层存储入参转换成 领域对象
|
* describe 应用层存储入参转换成 领域对象
|
||||||
*
|
*
|
||||||
* @param lazyNettyServerPropertiesStoryCommand 保存服务端配置信息对象
|
* @param lazyNettyServerPropertiesStoryCommand 保存服务端配置信息对象
|
||||||
* @return {@link LazyNettyServerProperties} 服务端配置信息领域对象
|
* @return {@link LazyNettyServerProperties} 服务端配置信息领域对象
|
||||||
|
|
||||||
* @author Jia wei Wu
|
* @author Jia wei Wu
|
||||||
* @date 2024/04/03 03:00 下午
|
* @date 2024/04/03 03:00 下午
|
||||||
**/
|
**/
|
||||||
LazyNettyServerProperties toLazyNettyServerProperties(LazyNettyServerPropertiesStoryCommand lazyNettyServerPropertiesStoryCommand);
|
LazyNettyServerProperties toLazyNettyServerProperties(LazyNettyServerPropertiesStoryCommand lazyNettyServerPropertiesStoryCommand);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* describe 应用层更新入参转换成 领域对象
|
* describe 应用层更新入参转换成 领域对象
|
||||||
*
|
*
|
||||||
* @param lazyNettyServerPropertiesUpdateCommand 更新服务端配置信息对象
|
* @param lazyNettyServerPropertiesUpdateCommand 更新服务端配置信息对象
|
||||||
* @return {@link LazyNettyServerProperties} 服务端配置信息领域对象
|
* @return {@link LazyNettyServerProperties} 服务端配置信息领域对象
|
||||||
|
|
||||||
* @author Jia wei Wu
|
* @author Jia wei Wu
|
||||||
* @date 2024/04/03 03:00 下午
|
* @date 2024/04/03 03:00 下午
|
||||||
**/
|
**/
|
||||||
LazyNettyServerProperties toLazyNettyServerProperties(LazyNettyServerPropertiesUpdateCommand lazyNettyServerPropertiesUpdateCommand);
|
LazyNettyServerProperties toLazyNettyServerProperties(LazyNettyServerPropertiesUpdateCommand lazyNettyServerPropertiesUpdateCommand);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* describe 应用层查询入参转换成 领域对象
|
* describe 应用层查询入参转换成 领域对象
|
||||||
*
|
*
|
||||||
* @param lazyNettyServerPropertiesQueryOneCommand 查询单个服务端配置信息对象参数
|
* @param lazyNettyServerPropertiesQueryOneCommand 查询单个服务端配置信息对象参数
|
||||||
* @return {@link LazyNettyServerProperties} 服务端配置信息领域对象
|
* @return {@link LazyNettyServerProperties} 服务端配置信息领域对象
|
||||||
|
|
||||||
* @author Jia wei Wu
|
* @author Jia wei Wu
|
||||||
* @date 2024/04/03 03:00 下午
|
* @date 2024/04/03 03:00 下午
|
||||||
**/
|
**/
|
||||||
LazyNettyServerProperties toLazyNettyServerProperties(LazyNettyServerPropertiesQueryOneCommand lazyNettyServerPropertiesQueryOneCommand);
|
LazyNettyServerProperties toLazyNettyServerProperties(LazyNettyServerPropertiesQueryOneCommand lazyNettyServerPropertiesQueryOneCommand);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* describe 应用层查询入参转换成 领域对象
|
* describe 应用层查询入参转换成 领域对象
|
||||||
*
|
*
|
||||||
* @param lazyNettyServerPropertiesQueryListCommand 查询集合服务端配置信息对象参数
|
* @param lazyNettyServerPropertiesQueryListCommand 查询集合服务端配置信息对象参数
|
||||||
* @return {@link LazyNettyServerProperties} 服务端配置信息领域对象
|
* @return {@link LazyNettyServerProperties} 服务端配置信息领域对象
|
||||||
|
|
||||||
* @author Jia wei Wu
|
* @author Jia wei Wu
|
||||||
* @date 2024/04/03 03:00 下午
|
* @date 2024/04/03 03:00 下午
|
||||||
**/
|
**/
|
||||||
LazyNettyServerProperties toLazyNettyServerProperties(LazyNettyServerPropertiesQueryListCommand lazyNettyServerPropertiesQueryListCommand);
|
LazyNettyServerProperties toLazyNettyServerProperties(LazyNettyServerPropertiesQueryListCommand lazyNettyServerPropertiesQueryListCommand);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* describe 应用层删除入参转换成 领域对象
|
* describe 应用层删除入参转换成 领域对象
|
||||||
*
|
*
|
||||||
* @param lazyNettyServerPropertiesRemoveCommand 删除服务端配置信息对象参数
|
* @param lazyNettyServerPropertiesRemoveCommand 删除服务端配置信息对象参数
|
||||||
* @return {@link LazyNettyServerProperties} 服务端配置信息领域对象
|
* @return {@link LazyNettyServerProperties} 服务端配置信息领域对象
|
||||||
|
|
||||||
* @author Jia wei Wu
|
* @author Jia wei Wu
|
||||||
* @date 2024/04/03 03:00 下午
|
* @date 2024/04/03 03:00 下午
|
||||||
**/
|
**/
|
||||||
LazyNettyServerProperties toLazyNettyServerProperties(LazyNettyServerPropertiesRemoveCommand lazyNettyServerPropertiesRemoveCommand);
|
LazyNettyServerProperties toLazyNettyServerProperties(LazyNettyServerPropertiesRemoveCommand lazyNettyServerPropertiesRemoveCommand);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* describe 持久层领域对象转换成DTO对象
|
* describe 持久层领域对象转换成DTO对象
|
||||||
*
|
*
|
||||||
* @param lazyNettyServerProperties 服务端配置信息领域对象
|
* @param lazyNettyServerProperties 服务端配置信息领域对象
|
||||||
* @return {@link LazyNettyServerPropertiesDTO} 服务端配置信息DTO对象
|
* @return {@link LazyNettyServerPropertiesDTO} 服务端配置信息DTO对象
|
||||||
|
|
||||||
* @author Jia wei Wu
|
* @author Jia wei Wu
|
||||||
* @date 2024/04/03 03:00 下午
|
* @date 2024/04/03 03:00 下午
|
||||||
**/
|
**/
|
||||||
LazyNettyServerPropertiesDTO fromLazyNettyServerProperties(LazyNettyServerProperties lazyNettyServerProperties);
|
LazyNettyServerPropertiesDTO fromLazyNettyServerProperties(LazyNettyServerProperties lazyNettyServerProperties);
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,12 @@
|
|||||||
package org.framework.lazy.cloud.network.heartbeat.client.application.command.lazy.netty.server.properties;
|
package org.framework.lazy.cloud.network.heartbeat.client.application.command.lazy.netty.server.properties;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.enums.NettyClientStatus;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.client.config.PropertiesType;
|
import org.framework.lazy.cloud.network.heartbeat.client.config.PropertiesType;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.common.enums.NettyClientStatus;
|
||||||
|
|
||||||
import java.lang.String;
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.lang.Integer;
|
|
||||||
/**
|
/**
|
||||||
* describe 服务端配置信息
|
* describe 服务端配置信息
|
||||||
*
|
*
|
||||||
@@ -21,7 +19,6 @@ import java.lang.Integer;
|
|||||||
@Schema(title = "lazy_netty_server_properties_query_List_command",description = "服务端配置信息")
|
@Schema(title = "lazy_netty_server_properties_query_List_command",description = "服务端配置信息")
|
||||||
public class LazyNettyServerPropertiesQueryListCommand {
|
public class LazyNettyServerPropertiesQueryListCommand {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* 客户身份ID
|
* 客户身份ID
|
||||||
@@ -66,7 +63,17 @@ public class LazyNettyServerPropertiesQueryListCommand {
|
|||||||
*/
|
*/
|
||||||
@Schema(description ="类型(配置、DB)",name ="type",example = "")
|
@Schema(description ="类型(配置、DB)",name ="type",example = "")
|
||||||
private PropertiesType type;
|
private PropertiesType type;
|
||||||
|
/**
|
||||||
|
* 令牌key
|
||||||
|
*/
|
||||||
|
@Schema(description = "令牌key", name = "appKey", example = "")
|
||||||
|
private String appKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 令牌密钥
|
||||||
|
*/
|
||||||
|
@Schema(description = "令牌密钥", name = "appSecret", example = "")
|
||||||
|
private String appSecret;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* 更新时间
|
* 更新时间
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import lombok.experimental.Accessors;
|
|||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.enums.NettyClientStatus;
|
import org.framework.lazy.cloud.network.heartbeat.common.enums.NettyClientStatus;
|
||||||
import org.framework.lazy.cloud.network.heartbeat.client.config.PropertiesType;
|
import org.framework.lazy.cloud.network.heartbeat.client.config.PropertiesType;
|
||||||
|
import org.wu.framework.core.NormalUsedString;
|
||||||
|
|
||||||
import java.lang.String;
|
import java.lang.String;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
@@ -22,6 +23,7 @@ import java.lang.Integer;
|
|||||||
public class LazyNettyServerPropertiesQueryOneCommand {
|
public class LazyNettyServerPropertiesQueryOneCommand {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* 客户身份ID
|
* 客户身份ID
|
||||||
@@ -65,7 +67,17 @@ public class LazyNettyServerPropertiesQueryOneCommand {
|
|||||||
*/
|
*/
|
||||||
@Schema(description ="类型(配置、DB)",name ="type",example = "")
|
@Schema(description ="类型(配置、DB)",name ="type",example = "")
|
||||||
private PropertiesType type;
|
private PropertiesType type;
|
||||||
|
/**
|
||||||
|
* 令牌key
|
||||||
|
*/
|
||||||
|
@Schema(description = "令牌key", name = "appKey", example = "")
|
||||||
|
private String appKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 令牌密钥
|
||||||
|
*/
|
||||||
|
@Schema(description = "令牌密钥", name = "appSecret", example = "")
|
||||||
|
private String appSecret;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* 更新时间
|
* 更新时间
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import lombok.experimental.Accessors;
|
|||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.enums.NettyClientStatus;
|
import org.framework.lazy.cloud.network.heartbeat.common.enums.NettyClientStatus;
|
||||||
import org.framework.lazy.cloud.network.heartbeat.client.config.PropertiesType;
|
import org.framework.lazy.cloud.network.heartbeat.client.config.PropertiesType;
|
||||||
|
import org.wu.framework.core.NormalUsedString;
|
||||||
|
|
||||||
import java.lang.String;
|
import java.lang.String;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
@@ -22,6 +23,7 @@ import java.lang.Integer;
|
|||||||
public class LazyNettyServerPropertiesRemoveCommand {
|
public class LazyNettyServerPropertiesRemoveCommand {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* 客户身份ID
|
* 客户身份ID
|
||||||
@@ -66,7 +68,17 @@ public class LazyNettyServerPropertiesRemoveCommand {
|
|||||||
*/
|
*/
|
||||||
@Schema(description ="类型(配置、DB)",name ="type",example = "")
|
@Schema(description ="类型(配置、DB)",name ="type",example = "")
|
||||||
private PropertiesType type;
|
private PropertiesType type;
|
||||||
|
/**
|
||||||
|
* 令牌key
|
||||||
|
*/
|
||||||
|
@Schema(description = "令牌key", name = "appKey", example = "")
|
||||||
|
private String appKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 令牌密钥
|
||||||
|
*/
|
||||||
|
@Schema(description = "令牌密钥", name = "appSecret", example = "")
|
||||||
|
private String appSecret;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* 更新时间
|
* 更新时间
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import lombok.experimental.Accessors;
|
|||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.enums.NettyClientStatus;
|
import org.framework.lazy.cloud.network.heartbeat.common.enums.NettyClientStatus;
|
||||||
import org.framework.lazy.cloud.network.heartbeat.client.config.PropertiesType;
|
import org.framework.lazy.cloud.network.heartbeat.client.config.PropertiesType;
|
||||||
|
import org.wu.framework.core.NormalUsedString;
|
||||||
|
|
||||||
import java.lang.String;
|
import java.lang.String;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
@@ -22,6 +23,7 @@ import java.lang.Integer;
|
|||||||
public class LazyNettyServerPropertiesStoryCommand {
|
public class LazyNettyServerPropertiesStoryCommand {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* 客户身份ID
|
* 客户身份ID
|
||||||
@@ -65,7 +67,17 @@ public class LazyNettyServerPropertiesStoryCommand {
|
|||||||
*/
|
*/
|
||||||
@Schema(description ="类型(配置、DB)",name ="type",example = "")
|
@Schema(description ="类型(配置、DB)",name ="type",example = "")
|
||||||
private PropertiesType type;
|
private PropertiesType type;
|
||||||
|
/**
|
||||||
|
* 令牌key
|
||||||
|
*/
|
||||||
|
@Schema(description = "令牌key", name = "appKey", example = "")
|
||||||
|
private String appKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 令牌密钥
|
||||||
|
*/
|
||||||
|
@Schema(description = "令牌密钥", name = "appSecret", example = "")
|
||||||
|
private String appSecret;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* 更新时间
|
* 更新时间
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import lombok.experimental.Accessors;
|
|||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.enums.NettyClientStatus;
|
import org.framework.lazy.cloud.network.heartbeat.common.enums.NettyClientStatus;
|
||||||
import org.framework.lazy.cloud.network.heartbeat.client.config.PropertiesType;
|
import org.framework.lazy.cloud.network.heartbeat.client.config.PropertiesType;
|
||||||
|
import org.wu.framework.core.NormalUsedString;
|
||||||
|
|
||||||
import java.lang.String;
|
import java.lang.String;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
@@ -22,6 +23,7 @@ import java.lang.Integer;
|
|||||||
public class LazyNettyServerPropertiesUpdateCommand {
|
public class LazyNettyServerPropertiesUpdateCommand {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* 客户身份ID
|
* 客户身份ID
|
||||||
@@ -65,7 +67,17 @@ public class LazyNettyServerPropertiesUpdateCommand {
|
|||||||
*/
|
*/
|
||||||
@Schema(description ="类型(配置、DB)",name ="type",example = "")
|
@Schema(description ="类型(配置、DB)",name ="type",example = "")
|
||||||
private PropertiesType type;
|
private PropertiesType type;
|
||||||
|
/**
|
||||||
|
* 令牌key
|
||||||
|
*/
|
||||||
|
@Schema(description = "令牌key", name = "appKey", example = "")
|
||||||
|
private String appKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 令牌密钥
|
||||||
|
*/
|
||||||
|
@Schema(description = "令牌密钥", name = "appSecret", example = "")
|
||||||
|
private String appSecret;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* 更新时间
|
* 更新时间
|
||||||
|
|||||||
@@ -1,14 +1,12 @@
|
|||||||
package org.framework.lazy.cloud.network.heartbeat.client.application.dto;
|
package org.framework.lazy.cloud.network.heartbeat.client.application.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.enums.NettyClientStatus;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.client.config.PropertiesType;
|
import org.framework.lazy.cloud.network.heartbeat.client.config.PropertiesType;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.common.enums.NettyClientStatus;
|
||||||
|
|
||||||
import java.lang.String;
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.lang.Integer;
|
|
||||||
/**
|
/**
|
||||||
* describe 服务端配置信息
|
* describe 服务端配置信息
|
||||||
*
|
*
|
||||||
@@ -22,6 +20,7 @@ import java.lang.Integer;
|
|||||||
public class LazyNettyServerPropertiesDTO {
|
public class LazyNettyServerPropertiesDTO {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* 客户身份ID
|
* 客户身份ID
|
||||||
@@ -65,7 +64,17 @@ public class LazyNettyServerPropertiesDTO {
|
|||||||
*/
|
*/
|
||||||
@Schema(description ="类型(配置、DB)",name ="type",example = "")
|
@Schema(description ="类型(配置、DB)",name ="type",example = "")
|
||||||
private PropertiesType type;
|
private PropertiesType type;
|
||||||
|
/**
|
||||||
|
* 令牌key
|
||||||
|
*/
|
||||||
|
@Schema(description = "令牌key", name = "appKey", example = "")
|
||||||
|
private String appKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 令牌密钥
|
||||||
|
*/
|
||||||
|
@Schema(description = "令牌密钥", name = "appSecret", example = "")
|
||||||
|
private String appSecret;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* 更新时间
|
* 更新时间
|
||||||
|
|||||||
@@ -2,21 +2,23 @@ package org.framework.lazy.cloud.network.heartbeat.client.application.impl;
|
|||||||
|
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.framework.lazy.cloud.network.heartbeat.client.application.assembler.LazyNettyServerPropertiesDTOAssembler;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.client.application.dto.LazyNettyServerPropertiesDTO;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.client.domain.model.lazy.netty.server.properties.LazyNettyServerProperties;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.client.domain.model.lazy.netty.server.properties.LazyNettyServerPropertiesRepository;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.client.netty.socket.NettyClientSocket;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.client.application.LazyNettyServerPropertiesApplication;
|
import org.framework.lazy.cloud.network.heartbeat.client.application.LazyNettyServerPropertiesApplication;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.client.application.assembler.LazyNettyServerPropertiesDTOAssembler;
|
||||||
import org.framework.lazy.cloud.network.heartbeat.client.application.command.lazy.netty.server.properties.*;
|
import org.framework.lazy.cloud.network.heartbeat.client.application.command.lazy.netty.server.properties.*;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.client.application.dto.LazyNettyServerPropertiesDTO;
|
||||||
import org.framework.lazy.cloud.network.heartbeat.client.config.NettyClientProperties;
|
import org.framework.lazy.cloud.network.heartbeat.client.config.NettyClientProperties;
|
||||||
import org.framework.lazy.cloud.network.heartbeat.client.config.PropertiesType;
|
import org.framework.lazy.cloud.network.heartbeat.client.config.PropertiesType;
|
||||||
import org.framework.lazy.cloud.network.heartbeat.client.netty.event.ClientChangeEvent;
|
import org.framework.lazy.cloud.network.heartbeat.client.domain.model.lazy.netty.server.properties.LazyNettyServerProperties;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.client.domain.model.lazy.netty.server.properties.LazyNettyServerPropertiesRepository;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.client.netty.permeate.NettyClientSocket;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.client.netty.permeate.event.ClientChangeEvent;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.client.netty.permeate.tcp.socket.NettyTcpClientSocket;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.client.netty.permeate.udp.socket.NettyUdpClientSocket;
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.advanced.HandleChannelTypeAdvanced;
|
import org.framework.lazy.cloud.network.heartbeat.common.advanced.HandleChannelTypeAdvanced;
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.enums.NettyClientStatus;
|
import org.framework.lazy.cloud.network.heartbeat.common.enums.NettyClientStatus;
|
||||||
import org.wu.framework.core.NormalUsedString;
|
import org.framework.lazy.cloud.network.heartbeat.common.enums.ProtocolType;
|
||||||
import org.wu.framework.database.lazy.web.plus.stereotype.LazyApplication;
|
|
||||||
import org.wu.framework.lazy.orm.database.lambda.domain.LazyPage;
|
import org.wu.framework.lazy.orm.database.lambda.domain.LazyPage;
|
||||||
|
import org.wu.framework.lazy.orm.web.plus.stereotype.LazyApplication;
|
||||||
import org.wu.framework.web.response.Result;
|
import org.wu.framework.web.response.Result;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -139,7 +141,7 @@ public class LazyNettyServerPropertiesApplicationImpl implements LazyNettyServer
|
|||||||
@Override
|
@Override
|
||||||
public Result<List<LazyNettyServerPropertiesDTO>> findList(LazyNettyServerPropertiesQueryListCommand lazyNettyServerPropertiesQueryListCommand) {
|
public Result<List<LazyNettyServerPropertiesDTO>> findList(LazyNettyServerPropertiesQueryListCommand lazyNettyServerPropertiesQueryListCommand) {
|
||||||
LazyNettyServerProperties lazyNettyServerProperties = LazyNettyServerPropertiesDTOAssembler.INSTANCE.toLazyNettyServerProperties(lazyNettyServerPropertiesQueryListCommand);
|
LazyNettyServerProperties lazyNettyServerProperties = LazyNettyServerPropertiesDTOAssembler.INSTANCE.toLazyNettyServerProperties(lazyNettyServerPropertiesQueryListCommand);
|
||||||
return lazyNettyServerPropertiesRepository.findList(lazyNettyServerProperties).convert(lazyNettyServerPropertiess -> lazyNettyServerPropertiess.stream().map(LazyNettyServerPropertiesDTOAssembler.INSTANCE::fromLazyNettyServerProperties).collect(Collectors.toList()));
|
return lazyNettyServerPropertiesRepository.findList(lazyNettyServerProperties).convert(lazyNettyServerPropertiesList -> lazyNettyServerPropertiesList.stream().map(LazyNettyServerPropertiesDTOAssembler.INSTANCE::fromLazyNettyServerProperties).collect(Collectors.toList()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -186,16 +188,35 @@ public class LazyNettyServerPropertiesApplicationImpl implements LazyNettyServer
|
|||||||
String inetHost = lazyNettyServerProperties.getInetHost();
|
String inetHost = lazyNettyServerProperties.getInetHost();
|
||||||
Integer inetPort = lazyNettyServerProperties.getInetPort();
|
Integer inetPort = lazyNettyServerProperties.getInetPort();
|
||||||
String clientId = lazyNettyServerProperties.getClientId();
|
String clientId = lazyNettyServerProperties.getClientId();
|
||||||
|
String appKey = lazyNettyServerProperties.getAppKey();
|
||||||
|
String appSecret = lazyNettyServerProperties.getAppSecret();
|
||||||
|
ProtocolType protocolType = lazyNettyServerProperties.getProtocolType();
|
||||||
|
NettyClientSocket nettyClientSocket;
|
||||||
|
if (ProtocolType.TCP.equals(protocolType)) {
|
||||||
|
nettyClientSocket = new
|
||||||
|
NettyTcpClientSocket(inetHost, inetPort, clientId,
|
||||||
|
appKey, appSecret,
|
||||||
|
clientChangeEvent, handleChannelTypeAdvancedList);
|
||||||
|
} else if (ProtocolType.UDP.equals(protocolType)) {
|
||||||
|
nettyClientSocket = new
|
||||||
|
NettyUdpClientSocket(inetHost, inetPort, clientId,
|
||||||
|
appKey, appSecret,
|
||||||
|
clientChangeEvent, handleChannelTypeAdvancedList);
|
||||||
|
} else {
|
||||||
|
nettyClientSocket = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nettyClientSocket == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
NettyClientSocket nettyClientSocket = new
|
|
||||||
NettyClientSocket(inetHost, inetPort, clientId,
|
|
||||||
NormalUsedString.DEFAULT,
|
|
||||||
clientChangeEvent, handleChannelTypeAdvancedList);
|
|
||||||
cacheNettyClientSocketMap.put(lazyNettyServerProperties, nettyClientSocket);
|
cacheNettyClientSocketMap.put(lazyNettyServerProperties, nettyClientSocket);
|
||||||
|
|
||||||
// 更新状态为运行中
|
// 更新状态为运行中
|
||||||
lazyNettyServerProperties.setConnectStatus(NettyClientStatus.RUNNING);
|
lazyNettyServerProperties.setConnectStatus(NettyClientStatus.RUNNING);
|
||||||
lazyNettyServerPropertiesRepository.story(lazyNettyServerProperties);
|
lazyNettyServerPropertiesRepository.story(lazyNettyServerProperties);
|
||||||
|
|
||||||
|
|
||||||
Thread thread = new Thread(() -> {
|
Thread thread = new Thread(() -> {
|
||||||
try {
|
try {
|
||||||
nettyClientSocket.newConnect2Server();
|
nettyClientSocket.newConnect2Server();
|
||||||
@@ -235,7 +256,7 @@ public class LazyNettyServerPropertiesApplicationImpl implements LazyNettyServer
|
|||||||
@Override
|
@Override
|
||||||
public void destroyOneClientSocket(LazyNettyServerProperties needCloseLazyNettyServerProperties) {
|
public void destroyOneClientSocket(LazyNettyServerProperties needCloseLazyNettyServerProperties) {
|
||||||
// 关闭指定socket
|
// 关闭指定socket
|
||||||
cacheNettyClientSocketMap.forEach(((nettyServerProperties, nettyClientSocket) -> {
|
cacheNettyClientSocketMap.forEach(((nettyServerProperties, nettyTcpClientSocket) -> {
|
||||||
String clientId = nettyServerProperties.getClientId();
|
String clientId = nettyServerProperties.getClientId();
|
||||||
String inetHost = nettyServerProperties.getInetHost();
|
String inetHost = nettyServerProperties.getInetHost();
|
||||||
Integer inetPort = nettyServerProperties.getInetPort();
|
Integer inetPort = nettyServerProperties.getInetPort();
|
||||||
@@ -245,7 +266,7 @@ public class LazyNettyServerPropertiesApplicationImpl implements LazyNettyServer
|
|||||||
if (Objects.equals(clientId, needCloseClientId)
|
if (Objects.equals(clientId, needCloseClientId)
|
||||||
&& Objects.equals(inetPort, needCloseInetPort)
|
&& Objects.equals(inetPort, needCloseInetPort)
|
||||||
&& Objects.equals(inetHost, needCloseInetHost)) {
|
&& Objects.equals(inetHost, needCloseInetHost)) {
|
||||||
nettyClientSocket.shutdown();
|
nettyTcpClientSocket.shutdown();
|
||||||
// 关闭客户端:{}与服务端连接:{}:{}
|
// 关闭客户端:{}与服务端连接:{}:{}
|
||||||
log.warn("Close client: {} Connect to server: {}: {}", clientId, inetHost, inetPort);
|
log.warn("Close client: {} Connect to server: {}: {}", clientId, inetHost, inetPort);
|
||||||
}
|
}
|
||||||
@@ -258,8 +279,8 @@ public class LazyNettyServerPropertiesApplicationImpl implements LazyNettyServer
|
|||||||
@Override
|
@Override
|
||||||
public void destroyClientSocket() {
|
public void destroyClientSocket() {
|
||||||
// 关闭socket
|
// 关闭socket
|
||||||
cacheNettyClientSocketMap.forEach(((nettyServerProperties, nettyClientSocket) -> {
|
cacheNettyClientSocketMap.forEach(((nettyServerProperties, nettyTcpClientSocket) -> {
|
||||||
nettyClientSocket.shutdown();
|
nettyTcpClientSocket.shutdown();
|
||||||
String clientId = nettyServerProperties.getClientId();
|
String clientId = nettyServerProperties.getClientId();
|
||||||
String inetHost = nettyServerProperties.getInetHost();
|
String inetHost = nettyServerProperties.getInetHost();
|
||||||
Integer inetPort = nettyServerProperties.getInetPort();
|
Integer inetPort = nettyServerProperties.getInetPort();
|
||||||
|
|||||||
@@ -1,82 +1,459 @@
|
|||||||
package org.framework.lazy.cloud.network.heartbeat.client.config;
|
package org.framework.lazy.cloud.network.heartbeat.client.config;
|
||||||
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import org.framework.lazy.cloud.network.heartbeat.client.context.NettyClientSocketApplicationListener;
|
||||||
import org.framework.lazy.cloud.network.heartbeat.client.netty.socket.NettyClientSocket;
|
import org.framework.lazy.cloud.network.heartbeat.client.netty.permeate.event.ClientChangeEvent;
|
||||||
import org.springframework.boot.CommandLineRunner;
|
import org.framework.lazy.cloud.network.heartbeat.client.netty.permeate.tcp.advanced.*;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.client.netty.permeate.udp.advanced.*;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.client.netty.proxy.http.advanced.*;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.client.netty.proxy.socks.advanced.*;
|
||||||
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.framework.lazy.cloud.network.heartbeat.client.netty.event.ClientChangeEvent;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.advanced.HandleChannelTypeAdvanced;
|
import org.springframework.context.annotation.Import;
|
||||||
import org.wu.framework.core.NormalUsedString;
|
import org.springframework.context.annotation.Role;
|
||||||
|
|
||||||
import java.util.List;
|
@Import({NettyClientSocketApplicationListener.class})
|
||||||
import java.util.concurrent.ArrayBlockingQueue;
|
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||||
import java.util.concurrent.ThreadPoolExecutor;
|
@ConditionalOnProperty(prefix = NettyClientProperties.PREFIX, name = "enabled", havingValue = "true", matchIfMissing = true)
|
||||||
import java.util.concurrent.TimeUnit;
|
public class ClientAutoConfiguration {
|
||||||
|
|
||||||
/**
|
|
||||||
* description 自动配置
|
|
||||||
*
|
|
||||||
* @author 吴佳伟
|
|
||||||
* @date 2023/09/12 18:22
|
|
||||||
* @see InitConfig
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
@Slf4j
|
|
||||||
public class ClientAutoConfiguration implements CommandLineRunner {
|
|
||||||
|
|
||||||
private final NettyClientProperties nettyClientProperties;
|
|
||||||
private final ClientChangeEvent clientChangeEvent;
|
|
||||||
|
|
||||||
private final List<HandleChannelTypeAdvanced> handleChannelTypeAdvancedList; // 处理服务端发送过来的数据类型
|
|
||||||
|
|
||||||
|
|
||||||
public static final ThreadPoolExecutor NETTY_CLIENT_EXECUTOR = new ThreadPoolExecutor(1, 1, 200, TimeUnit.MILLISECONDS,
|
@Configuration()
|
||||||
new ArrayBlockingQueue<>(1));
|
static class ClientTcpConfiguration {
|
||||||
|
/**
|
||||||
|
* 服务端 处理客户端心跳
|
||||||
|
*
|
||||||
|
* @return ClientHandleTcpChannelHeartbeatTypeAdvanced
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public ClientHandleTcpChannelHeartbeatTypeAdvanced clientHandleTcpChannelHeartbeatTypeAdvanced() {
|
||||||
|
return new ClientHandleTcpChannelHeartbeatTypeAdvanced();
|
||||||
|
}
|
||||||
|
|
||||||
public ClientAutoConfiguration(NettyClientProperties nettyClientProperties,
|
/**
|
||||||
ClientChangeEvent clientChangeEvent,
|
* 处理 客户端代理的真实端口自动读写
|
||||||
List<HandleChannelTypeAdvanced> handleChannelTypeAdvancedList) {
|
*
|
||||||
this.nettyClientProperties = nettyClientProperties;
|
* @return ClientHandleTcpDistributeSingleClientRealAutoReadConnectTypeAdvanced
|
||||||
this.clientChangeEvent = clientChangeEvent;
|
*/
|
||||||
this.handleChannelTypeAdvancedList = handleChannelTypeAdvancedList;
|
@Bean
|
||||||
|
public ClientHandleTcpDistributeSingleClientRealAutoReadConnectTypeAdvanced clientHandleTcpDistributeSingleClientRealAutoReadConnectTypeAdvanced() {
|
||||||
|
return new ClientHandleTcpDistributeSingleClientRealAutoReadConnectTypeAdvanced();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理 接收服务端发送过来的聊天信息
|
||||||
|
*
|
||||||
|
* @return ClientHandleTcpDistributeSingleClientMessageTypeAdvanced
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public ClientHandleTcpDistributeSingleClientMessageTypeAdvanced clientHandleTcpDistributeSingleClientMessageTypeAdvanced() {
|
||||||
|
return new ClientHandleTcpDistributeSingleClientMessageTypeAdvanced();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理 客户端渗透服务端数据传输通道连接成功
|
||||||
|
*
|
||||||
|
* @return ClientHandleTcpDistributeClientTransferServerPermeateChannelConnectionSuccessfulTypeAdvanced
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public ClientHandleTcpDistributeClientTransferServerPermeateChannelConnectionSuccessfulTypeAdvanced clientHandleTcpDistributeClientTransferServerPermeateChannelConnectionSuccessfulTypeAdvanced() {
|
||||||
|
return new ClientHandleTcpDistributeClientTransferServerPermeateChannelConnectionSuccessfulTypeAdvanced();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理 客户端渗透客户端数据传输通道连接成功
|
||||||
|
*
|
||||||
|
* @return ClientHandleTcpDistributeClientTransferClientPermeateChannelConnectionSuccessfulTypeAdvanced
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public ClientHandleTcpDistributeClientTransferClientPermeateChannelConnectionSuccessfulTypeAdvanced clientHandleTcpDistributeClientTransferClientPermeateChannelConnectionSuccessfulTypeAdvanced() {
|
||||||
|
return new ClientHandleTcpDistributeClientTransferClientPermeateChannelConnectionSuccessfulTypeAdvanced();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ClientHandleTcpDistributeClientTransferClientPermeateChannelInitSuccessfulTypeAdvanced clientHandleTcpDistributeClientTransferClientPermeateChannelInitSuccessfulTypeAdvanced() {
|
||||||
|
return new ClientHandleTcpDistributeClientTransferClientPermeateChannelInitSuccessfulTypeAdvanced();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ClientHandleTcpDistributeClientTransferClientRequestTypeAdvanced clientHandleTcpDistributeClientTransferClientRequestTypeAdvanced() {
|
||||||
|
return new ClientHandleTcpDistributeClientTransferClientRequestTypeAdvanced();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ClientHandleTcpDistributeServicePermeateClientTransferClientResponseTypeAdvanced clientHandleTcpDistributeServicePermeateClientTransferClientResponseTypeAdvanced() {
|
||||||
|
return new ClientHandleTcpDistributeServicePermeateClientTransferClientResponseTypeAdvanced();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ClientHandleTcpDistributeSingleClientRealCloseVisitorTypeAdvanced clientHandleTcpDistributeSingleClientRealCloseVisitorTypeAdvanced() {
|
||||||
|
return new ClientHandleTcpDistributeSingleClientRealCloseVisitorTypeAdvanced();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ClientHandleTcpChannelTransferTypeAdvancedHandleDistributeTcpDistribute clientHandleTcpChannelTransferTypeAdvancedHandleDistributeTcpDistribute(NettyClientProperties nettyClientProperties) {
|
||||||
|
return new ClientHandleTcpChannelTransferTypeAdvancedHandleDistributeTcpDistribute(nettyClientProperties);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ClientHandleTcpDistributeConnectSuccessNotificationTypeAdvancedHandle clientHandleTcpDistributeConnectSuccessNotificationTypeAdvancedHandle(ClientChangeEvent clientChangeEvent) {
|
||||||
|
return new ClientHandleTcpDistributeConnectSuccessNotificationTypeAdvancedHandle(clientChangeEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ClientHandleTcpClientChannelActiveAdvanced clientHandleTcpClientChannelActiveAdvanced(NettyClientProperties nettyClientProperties) {
|
||||||
|
return new ClientHandleTcpClientChannelActiveAdvanced(nettyClientProperties);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ClientHandleTcpDistributeDisconnectTypeAdvancedHandle clientHandleTcpDistributeDisconnectTypeAdvancedHandle(ClientChangeEvent clientChangeEvent) {
|
||||||
|
return new ClientHandleTcpDistributeDisconnectTypeAdvancedHandle(clientChangeEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ClientHandleTcpDistributeStagingClosedTypeAdvanced clientHandleTcpDistributeStagingClosedTypeAdvanced() {
|
||||||
|
return new ClientHandleTcpDistributeStagingClosedTypeAdvanced();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ClientHandleTcpDistributeStagingOpenedTypeAdvanced clientHandleTcpDistributeStagingOpenedTypeAdvanced() {
|
||||||
|
return new ClientHandleTcpDistributeStagingOpenedTypeAdvanced();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理 客户端渗透服务端init信息
|
||||||
|
*
|
||||||
|
* @return ClientHandleTcpDistributeClientPermeateServerInitTypeAdvanced
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public ClientHandleTcpDistributeClientPermeateServerInitTypeAdvanced clientHandleTcpDistributeClientPermeateServerInitTypeAdvanced(NettyClientProperties nettyClientProperties) {
|
||||||
|
return new ClientHandleTcpDistributeClientPermeateServerInitTypeAdvanced(nettyClientProperties);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理 客户端渗透服务端init close 信息
|
||||||
|
*
|
||||||
|
* @return ClientHandleTcpDistributeClientPermeateServerCloseTypeAdvanced
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public ClientHandleTcpDistributeClientPermeateServerCloseTypeAdvanced clientHandleTcpDistributeClientPermeateServerCloseTypeAdvanced() {
|
||||||
|
return new ClientHandleTcpDistributeClientPermeateServerCloseTypeAdvanced();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ClientHandleTcpDistributeClientPermeateServerTransferTypeAdvanced clientHandleTcpDistributeClientPermeateServerTransferTypeAdvanced() {
|
||||||
|
return new ClientHandleTcpDistributeClientPermeateServerTransferTypeAdvanced();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ClientHandleTcpDistributeClientPermeateClientCloseTypeAdvanced clientHandleTcpDistributeClientPermeateClientCloseTypeAdvanced() {
|
||||||
|
return new ClientHandleTcpDistributeClientPermeateClientCloseTypeAdvanced();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ClientHandleTcpDistributeClientPermeateClientInitTypeAdvanced clientHandleTcpDistributeClientPermeateClientInitTypeAdvanced() {
|
||||||
|
return new ClientHandleTcpDistributeClientPermeateClientInitTypeAdvanced();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ClientHandleTcpDistributeClientPermeateClientTransferCloseTypeAdvanced clientHandleTcpDistributeClientPermeateClientTransferCloseTypeAdvanced() {
|
||||||
|
return new ClientHandleTcpDistributeClientPermeateClientTransferCloseTypeAdvanced();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ClientHandleTcpDistributeServicePermeateClientRealConnectTypeAdvanced clientHandleTcpDistributeServicePermeateClientRealConnectTypeAdvanced(
|
||||||
|
NettyClientProperties nettyClientProperties) {
|
||||||
|
return new ClientHandleTcpDistributeServicePermeateClientRealConnectTypeAdvanced(nettyClientProperties);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ClientHandleTcpDistributeClientPermeateServerTransferCloseTypeAdvanced clientHandleTcpDistributeClientPermeateServerTransferCloseTypeAdvanced() {
|
||||||
|
return new ClientHandleTcpDistributeClientPermeateServerTransferCloseTypeAdvanced();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Configuration()
|
||||||
|
static class ClientUdpConfiguration {
|
||||||
|
/**
|
||||||
|
* 服务端 处理客户端心跳
|
||||||
|
*
|
||||||
|
* @return ClientHandleUdpChannelHeartbeatTypeAdvanced
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public ClientHandleUdpChannelHeartbeatTypeAdvanced clientHandleUdpChannelHeartbeatTypeAdvanced() {
|
||||||
|
return new ClientHandleUdpChannelHeartbeatTypeAdvanced();
|
||||||
|
}
|
||||||
|
|
||||||
@Bean(destroyMethod = "shutdown")
|
/**
|
||||||
public NettyClientSocket nettyClientSocket() {
|
* 处理 客户端代理的真实端口自动读写
|
||||||
String inetHost = nettyClientProperties.getInetHost();
|
*
|
||||||
int inetPort = nettyClientProperties.getInetPort();
|
* @return ClientHandleUdpDistributeSingleClientRealAutoReadConnectTypeAdvanced
|
||||||
String clientId = nettyClientProperties.getClientId();
|
*/
|
||||||
return new NettyClientSocket(inetHost, inetPort, clientId, NormalUsedString.DEFAULT, clientChangeEvent, handleChannelTypeAdvancedList);
|
@Bean
|
||||||
|
public ClientHandleUdpDistributeSingleClientRealAutoReadConnectTypeAdvanced clientHandleUdpDistributeSingleClientRealAutoReadConnectTypeAdvanced() {
|
||||||
|
return new ClientHandleUdpDistributeSingleClientRealAutoReadConnectTypeAdvanced();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理 接收服务端发送过来的聊天信息
|
||||||
|
*
|
||||||
|
* @return ClientHandleUdpDistributeSingleClientMessageTypeAdvanced
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public ClientHandleUdpDistributeSingleClientMessageTypeAdvanced clientHandleUdpDistributeSingleClientMessageTypeAdvanced() {
|
||||||
|
return new ClientHandleUdpDistributeSingleClientMessageTypeAdvanced();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理 客户端渗透服务端数据传输通道连接成功
|
||||||
|
*
|
||||||
|
* @return ClientHandleUdpDistributeClientTransferServerPermeateChannelConnectionSuccessfulTypeAdvanced
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public ClientHandleUdpDistributeClientTransferServerPermeateChannelConnectionSuccessfulTypeAdvanced clientHandleUdpDistributeClientTransferServerPermeateChannelConnectionSuccessfulTypeAdvanced() {
|
||||||
|
return new ClientHandleUdpDistributeClientTransferServerPermeateChannelConnectionSuccessfulTypeAdvanced();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理 客户端渗透客户端数据传输通道连接成功
|
||||||
|
*
|
||||||
|
* @return ClientHandleUdpDistributeClientTransferClientPermeateChannelConnectionSuccessfulTypeAdvanced
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public ClientHandleUdpDistributeClientTransferClientPermeateChannelConnectionSuccessfulTypeAdvanced clientHandleUdpDistributeClientTransferClientPermeateChannelConnectionSuccessfulTypeAdvanced() {
|
||||||
|
return new ClientHandleUdpDistributeClientTransferClientPermeateChannelConnectionSuccessfulTypeAdvanced();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ClientHandleUdpDistributeClientTransferClientPermeateChannelInitSuccessfulTypeAdvanced clientHandleUdpDistributeClientTransferClientPermeateChannelInitSuccessfulTypeAdvanced() {
|
||||||
|
return new ClientHandleUdpDistributeClientTransferClientPermeateChannelInitSuccessfulTypeAdvanced();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ClientHandleUdpDistributeClientTransferClientRequestTypeAdvanced clientHandleUdpDistributeClientTransferClientRequestTypeAdvanced() {
|
||||||
|
return new ClientHandleUdpDistributeClientTransferClientRequestTypeAdvanced();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ClientHandleUdpDistributeServicePermeateClientTransferClientResponseTypeAdvanced clientHandleUdpDistributeServicePermeateClientTransferClientResponseTypeAdvanced() {
|
||||||
|
return new ClientHandleUdpDistributeServicePermeateClientTransferClientResponseTypeAdvanced();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ClientHandleUdpDistributeSingleClientRealCloseVisitorTypeAdvanced clientHandleUdpDistributeSingleClientRealCloseVisitorTypeAdvanced() {
|
||||||
|
return new ClientHandleUdpDistributeSingleClientRealCloseVisitorTypeAdvanced();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ClientHandleUdpChannelTransferTypeAdvancedHandleDistribute clientHandleUdpChannelTransferTypeAdvancedHandleDistribute(NettyClientProperties nettyClientProperties) {
|
||||||
|
return new ClientHandleUdpChannelTransferTypeAdvancedHandleDistribute(nettyClientProperties);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ClientHandleUdpDistributeConnectSuccessNotificationTypeAdvancedHandle clientHandleUdpDistributeConnectSuccessNotificationTypeAdvancedHandle(ClientChangeEvent clientChangeEvent) {
|
||||||
|
return new ClientHandleUdpDistributeConnectSuccessNotificationTypeAdvancedHandle(clientChangeEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ClientHandleUdpClientChannelActiveAdvanced clientHandleUdpClientChannelActiveAdvanced(NettyClientProperties nettyClientProperties) {
|
||||||
|
return new ClientHandleUdpClientChannelActiveAdvanced(nettyClientProperties);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ClientHandleUdpDistributeDisconnectTypeAdvancedHandle clientHandleUdpDistributeDisconnectTypeAdvancedHandle(ClientChangeEvent clientChangeEvent) {
|
||||||
|
return new ClientHandleUdpDistributeDisconnectTypeAdvancedHandle(clientChangeEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ClientHandleUdpDistributeStagingClosedTypeAdvanced clientHandleUdpDistributeStagingClosedTypeAdvanced() {
|
||||||
|
return new ClientHandleUdpDistributeStagingClosedTypeAdvanced();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ClientHandleUdpDistributeStagingOpenedTypeAdvanced clientHandleUdpDistributeStagingOpenedTypeAdvanced() {
|
||||||
|
return new ClientHandleUdpDistributeStagingOpenedTypeAdvanced();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理 客户端渗透服务端init信息
|
||||||
|
*
|
||||||
|
* @return ClientHandleUdpDistributeClientPermeateServerInitTypeAdvanced
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public ClientHandleUdpDistributeClientPermeateServerInitTypeAdvanced clientHandleUdpDistributeClientPermeateServerInitTypeAdvanced(NettyClientProperties nettyClientProperties) {
|
||||||
|
return new ClientHandleUdpDistributeClientPermeateServerInitTypeAdvanced(nettyClientProperties);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理 客户端渗透服务端init close 信息
|
||||||
|
*
|
||||||
|
* @return ClientHandleUdpDistributeClientPermeateServerCloseTypeAdvanced
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public ClientHandleUdpDistributeClientPermeateServerCloseTypeAdvanced clientHandleUdpDistributeClientPermeateServerCloseTypeAdvanced() {
|
||||||
|
return new ClientHandleUdpDistributeClientPermeateServerCloseTypeAdvanced();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ClientHandleUdpDistributeClientPermeateServerTransferTypeAdvanced clientHandleUdpDistributeClientPermeateServerTransferTypeAdvanced() {
|
||||||
|
return new ClientHandleUdpDistributeClientPermeateServerTransferTypeAdvanced();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ClientHandleUdpDistributeClientPermeateClientCloseTypeAdvanced clientHandleUdpDistributeClientPermeateClientCloseTypeAdvanced() {
|
||||||
|
return new ClientHandleUdpDistributeClientPermeateClientCloseTypeAdvanced();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ClientHandleUdpDistributeClientPermeateClientInitTypeAdvanced clientHandleUdpDistributeClientPermeateClientInitTypeAdvanced() {
|
||||||
|
return new ClientHandleUdpDistributeClientPermeateClientInitTypeAdvanced();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ClientHandleUdpDistributeClientPermeateClientTransferCloseTypeAdvanced clientHandleUdpDistributeClientPermeateClientTransferCloseTypeAdvanced() {
|
||||||
|
return new ClientHandleUdpDistributeClientPermeateClientTransferCloseTypeAdvanced();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ClientHandleUdpDistributeServicePermeateClientRealConnectTypeAdvanced clientHandleUdpDistributeServicePermeateClientRealConnectTypeAdvanced(
|
||||||
|
NettyClientProperties nettyClientProperties) {
|
||||||
|
return new ClientHandleUdpDistributeServicePermeateClientRealConnectTypeAdvanced(nettyClientProperties);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ClientHandleUdpDistributeClientPermeateServerTransferCloseTypeAdvanced clientHandleUdpDistributeClientPermeateServerTransferCloseTypeAdvanced() {
|
||||||
|
return new ClientHandleUdpDistributeClientPermeateServerTransferCloseTypeAdvanced();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Configuration
|
||||||
* @param args
|
static class HttpProxyConfiguration {
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void run(String... args) throws Exception {
|
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ClientHandleDistributeHttpClientProxyServerTransferTypeAdvanced clientHandleDistributeHttpClientProxyServerTypeAdvanced() {
|
||||||
|
return new ClientHandleDistributeHttpClientProxyServerTransferTypeAdvanced();
|
||||||
|
}
|
||||||
|
|
||||||
String inetHost = nettyClientProperties.getInetHost();
|
@Bean
|
||||||
int inetPort = nettyClientProperties.getInetPort();
|
public ClientHandleHttpClientProxyClientTypeAdvanced clientHandleHttpClientClientProxyClientTypeAdvanced() {
|
||||||
String clientId = nettyClientProperties.getClientId();
|
return new ClientHandleHttpClientProxyClientTypeAdvanced();
|
||||||
NettyClientSocket nettyClientSocket = new NettyClientSocket(
|
}
|
||||||
inetHost, inetPort,
|
|
||||||
clientId, NormalUsedString.DEFAULT,
|
|
||||||
clientChangeEvent, handleChannelTypeAdvancedList);
|
|
||||||
Thread thread = new Thread(() -> {
|
|
||||||
try {
|
|
||||||
nettyClientSocket.newConnect2Server();
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
@Bean
|
||||||
log.info("当前服务连接Netty客户端:{},Netty端口:{}", inetHost, inetPort);
|
public ClientHandleHttpClientProxyServerTypeAdvanced clientHandleHttpClientClientProxyServerTypeAdvanced() {
|
||||||
NETTY_CLIENT_EXECUTOR.execute(thread);
|
return new ClientHandleHttpClientProxyServerTypeAdvanced();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ClientHandleDistributeHttpClientProxyServerServerRouteTypeAdvanced clientHandleDistributeHttpClientProxyServerServerRouteTypeAdvanced() {
|
||||||
|
return new ClientHandleDistributeHttpClientProxyServerServerRouteTypeAdvanced();
|
||||||
|
}
|
||||||
|
@Bean
|
||||||
|
public ClientHandleDistributeHttpClientProxyServerServerRouteCloseTypeAdvanced clientHandleDistributeHttpClientProxyServerServerRouteCloseTypeAdvanced(){
|
||||||
|
return new ClientHandleDistributeHttpClientProxyServerServerRouteCloseTypeAdvanced();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ClientHandleDistributeHttpClientProxyServerClientRouteTypeAdvanced clientHandleDistributeHttpClientProxyServerClientRouteTypeAdvanced() {
|
||||||
|
return new ClientHandleDistributeHttpClientProxyServerClientRouteTypeAdvanced();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ClientHandleDistributeHttpClientProxyServerClientRouteCloseTypeAdvanced clientHandleDistributeHttpClientProxyServerClientRouteCloseTypeAdvanced(){
|
||||||
|
return new ClientHandleDistributeHttpClientProxyServerClientRouteCloseTypeAdvanced();
|
||||||
|
}
|
||||||
|
@Bean
|
||||||
|
public ClientHandleDistributeHttpClientProxyClientConnectionTransferSuccessfulAdvanced clientHandleDistributeHttpClientProxyClientConnectionTransferSuccessfulAdvanced() {
|
||||||
|
return new ClientHandleDistributeHttpClientProxyClientConnectionTransferSuccessfulAdvanced();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ClientHandleDistributeHttpClientProxyClientTransferRequestAdvanced clientHandleDistributeHttpClientProxyClientTransferRequestAdvanced() {
|
||||||
|
return new ClientHandleDistributeHttpClientProxyClientTransferRequestAdvanced();
|
||||||
|
}
|
||||||
|
@Bean
|
||||||
|
public ClientHandleHttpDistributeClientProxyClientTransferResponseTypeAdvanced clientHandleHttpDistributeClientProxyClientTransferResponseTypeAdvanced(){
|
||||||
|
return new ClientHandleHttpDistributeClientProxyClientTransferResponseTypeAdvanced();
|
||||||
|
}
|
||||||
|
@Bean
|
||||||
|
public ClientHandleHttpDistributeClientProxyClientTransferCLoseTypeAdvanced clientHandleHttpDistributeClientProxyClientTransferCLoseTypeAdvanced(){
|
||||||
|
return new ClientHandleHttpDistributeClientProxyClientTransferCLoseTypeAdvanced();
|
||||||
|
}
|
||||||
|
@Bean
|
||||||
|
public ClientHandleDistributeHttpServerProxyClientConnectionSuccessfulTypeAdvanced clientHandleDistributeHttpServerProxyClientConnectionSuccessfulTypeAdvanced(){
|
||||||
|
return new ClientHandleDistributeHttpServerProxyClientConnectionSuccessfulTypeAdvanced();
|
||||||
|
}
|
||||||
|
@Bean
|
||||||
|
public ClientHandleDistributeHttpServerProxyClientTransferRequestAdvanced clientHandleDistributeHttpServerProxyClientTransferRequestAdvanced(){
|
||||||
|
return new ClientHandleDistributeHttpServerProxyClientTransferRequestAdvanced();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
static class SocksProxyConfiguration {
|
||||||
|
@Bean
|
||||||
|
public ClientHandleNettySocketProtocolHandleSocketClientProxyServerStartTypeAdvanced nettySocketProtocolHandleSocketClientProxyServerTypeAdvanced() {
|
||||||
|
return new ClientHandleNettySocketProtocolHandleSocketClientProxyServerStartTypeAdvanced();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ClientHandleDistributeSocksClientProxyServerConnectionTransferSuccessfulAdvanced clientHandleDistributeSocksClientProxyServerConnectionTransferSuccessfulAdvanced() {
|
||||||
|
return new ClientHandleDistributeSocksClientProxyServerConnectionTransferSuccessfulAdvanced();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ClientHandleDistributeSocksClientProxyServerConnectionTransferFailAdvanced clientHandleDistributeSocksClientProxyServerConnectionTransferFailAdvanced() {
|
||||||
|
return new ClientHandleDistributeSocksClientProxyServerConnectionTransferFailAdvanced();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ClientHandleDistributeSocksClientProxyServerTransferTransferResponseAdvanced clientHandleDistributeSocksClientProxyServerTransferTransferResponseAdvanced() {
|
||||||
|
return new ClientHandleDistributeSocksClientProxyServerTransferTransferResponseAdvanced();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ClientHandleDistributeSocksClientProxyServerTransferCloseAdvanced clientHandleDistributeSocksClientProxyServerTransferCloseAdvanced() {
|
||||||
|
return new ClientHandleDistributeSocksClientProxyServerTransferCloseAdvanced();
|
||||||
|
}
|
||||||
|
@Bean
|
||||||
|
public ClientHandleDistributeSocksClientProxyClientConnectionTransferFailAdvanced clientHandleDistributeSocksClientProxyClientConnectionTransferFailAdvanced(){
|
||||||
|
return new ClientHandleDistributeSocksClientProxyClientConnectionTransferFailAdvanced();
|
||||||
|
}
|
||||||
|
@Bean
|
||||||
|
public ClientHandleDistributeSocksClientProxyClientConnectionTransferSuccessfulAdvanced clientHandleDistributeSocksClientProxyClientConnectionTransferSuccessfulAdvanced(){
|
||||||
|
return new ClientHandleDistributeSocksClientProxyClientConnectionTransferSuccessfulAdvanced();
|
||||||
|
}
|
||||||
|
@Bean
|
||||||
|
public ClientHandleDistributeSocksClientProxyClientTransferCloseAdvanced clientHandleDistributeSocksClientProxyClientTransferCloseAdvanced(){
|
||||||
|
return new ClientHandleDistributeSocksClientProxyClientTransferCloseAdvanced();
|
||||||
|
}
|
||||||
|
@Bean
|
||||||
|
public ClientHandleDistributeSocksClientProxyClientTransferTransferResponseAdvanced clientHandleDistributeSocksClientProxyClientTransferTransferResponseAdvanced(){
|
||||||
|
return new ClientHandleDistributeSocksClientProxyClientTransferTransferResponseAdvanced();
|
||||||
|
}
|
||||||
|
@Bean
|
||||||
|
public ClientHandleDistributeSocksClientProxyClientOtherConnectionTransferAdvanced clientHandleDistributeSocksClientProxyClientOtherConnectionTransferAdvanced1(){
|
||||||
|
return new ClientHandleDistributeSocksClientProxyClientOtherConnectionTransferAdvanced();
|
||||||
|
}
|
||||||
|
@Bean
|
||||||
|
public ClientHandleDistributeSocksClientProxyClientTransferTransferRequestAdvanced clientHandleDistributeSocksClientProxyClientTransferTransferRequestAdvanced(){
|
||||||
|
return new ClientHandleDistributeSocksClientProxyClientTransferTransferRequestAdvanced();
|
||||||
|
}
|
||||||
|
@Bean
|
||||||
|
public ClientHandleSocksDistributeServerProxyClientConnectionInitTypeAdvanced clientHandleSocksDistributeServerProxyClientConnectionInitTypeAdvanced(){
|
||||||
|
return new ClientHandleSocksDistributeServerProxyClientConnectionInitTypeAdvanced();
|
||||||
|
}
|
||||||
|
@Bean
|
||||||
|
public ClientHandleSocksDistributeServerProxyClientRequestTypeAdvanced clientHandleSocksDistributeServerProxyClientRequestTypeAdvanced(){
|
||||||
|
return new ClientHandleSocksDistributeServerProxyClientRequestTypeAdvanced();
|
||||||
|
}
|
||||||
|
@Bean
|
||||||
|
public ClientHandleSocksDistributeServerProxyClientTransferCloseAdvanced clientHandleSocksDistributeServerProxyClientTransferCloseAdvanced(){
|
||||||
|
return new ClientHandleSocksDistributeServerProxyClientTransferCloseAdvanced();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,165 +0,0 @@
|
|||||||
package org.framework.lazy.cloud.network.heartbeat.client.config;
|
|
||||||
|
|
||||||
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.client.netty.advanced.*;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.client.netty.event.ClientChangeEvent;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.advanced.HandleChannelTypeAdvanced;
|
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Role;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
|
||||||
@ConditionalOnProperty(prefix = NettyClientProperties.PREFIX, name = "enabled", havingValue = "true", matchIfMissing = true)
|
|
||||||
public class HeartbeatClientConfiguration {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 服务端 处理客户端心跳
|
|
||||||
*
|
|
||||||
* @return ClientHandleChannelHeartbeatTypeAdvanced
|
|
||||||
*/
|
|
||||||
@Bean
|
|
||||||
public ClientHandleChannelHeartbeatTypeAdvanced clientChannelHeartbeatTypeAdvanced() {
|
|
||||||
return new ClientHandleChannelHeartbeatTypeAdvanced();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理 客户端代理的真实端口自动读写
|
|
||||||
*
|
|
||||||
* @return ClientHandleDistributeSingleClientRealAutoReadConnectTypeAdvanced
|
|
||||||
*/
|
|
||||||
@Bean
|
|
||||||
public ClientHandleDistributeSingleClientRealAutoReadConnectTypeAdvanced handleDistributeSingleClientRealAutoReadConnectTypeAdvanced() {
|
|
||||||
return new ClientHandleDistributeSingleClientRealAutoReadConnectTypeAdvanced();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理 接收服务端发送过来的聊天信息
|
|
||||||
*
|
|
||||||
* @return ClientHandleDistributeSingleClientMessageTypeAdvanced
|
|
||||||
*/
|
|
||||||
@Bean
|
|
||||||
public ClientHandleDistributeSingleClientMessageTypeAdvanced handleDistributeSingleClientMessageTypeAdvanced() {
|
|
||||||
return new ClientHandleDistributeSingleClientMessageTypeAdvanced();
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* 处理 客户端渗透服务端数据传输通道连接成功
|
|
||||||
*
|
|
||||||
* @return ClientHandleDistributeClientTransferServerPermeateChannelConnectionSuccessfulTypeAdvanced
|
|
||||||
*/
|
|
||||||
@Bean
|
|
||||||
public ClientHandleDistributeClientTransferServerPermeateChannelConnectionSuccessfulTypeAdvanced clientHandleDistributeClientTransferServerPermeateChannelConnectionSuccessfulTypeAdvanced() {
|
|
||||||
return new ClientHandleDistributeClientTransferServerPermeateChannelConnectionSuccessfulTypeAdvanced();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理 客户端渗透客户端数据传输通道连接成功
|
|
||||||
*
|
|
||||||
* @return ClientHandleDistributeClientTransferClientPermeateChannelConnectionSuccessfulTypeAdvanced
|
|
||||||
*/
|
|
||||||
@Bean
|
|
||||||
public ClientHandleDistributeClientTransferClientPermeateChannelConnectionSuccessfulTypeAdvanced clientHandleDistributeClientTransferClientPermeateChannelConnectionSuccessfulTypeAdvanced() {
|
|
||||||
return new ClientHandleDistributeClientTransferClientPermeateChannelConnectionSuccessfulTypeAdvanced();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public ClientHandleDistributeClientTransferClientPermeateChannelInitSuccessfulTypeAdvanced clientHandleDistributeClientTransferClientPermeateChannelInitSuccessfulTypeAdvanced() {
|
|
||||||
return new ClientHandleDistributeClientTransferClientPermeateChannelInitSuccessfulTypeAdvanced();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public ClientHandleDistributeClientTransferClientRequestTypeAdvanced clientHandleDistributeClientTransferClientTypeAdvanced() {
|
|
||||||
return new ClientHandleDistributeClientTransferClientRequestTypeAdvanced();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public ClientHandleDistributeServicePermeateClientTransferClientResponseTypeAdvanced clientHandleDistributeClientTransferClientResponseTypeAdvanced() {
|
|
||||||
return new ClientHandleDistributeServicePermeateClientTransferClientResponseTypeAdvanced();
|
|
||||||
}
|
|
||||||
@Bean
|
|
||||||
public ClientHandleDistributeSingleClientRealCloseVisitorTypeAdvanced handleDistributeSingleClientRealCloseVisitorTypeAdvanced() {
|
|
||||||
return new ClientHandleDistributeSingleClientRealCloseVisitorTypeAdvanced();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public ClientHandleChannelTransferTypeAdvancedHandleDistributeDistribute handleChannelTransferTypeAdvancedHandleDistribute(NettyClientProperties nettyClientProperties) {
|
|
||||||
return new ClientHandleChannelTransferTypeAdvancedHandleDistributeDistribute(nettyClientProperties);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public HandleDistributeConnectSuccessNotificationTypeAdvancedHandle handleDistributeConnectSuccessNotificationTypeAdvancedHandle(ClientChangeEvent clientChangeEvent) {
|
|
||||||
return new HandleDistributeConnectSuccessNotificationTypeAdvancedHandle(clientChangeEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public HandleClientChannelActiveAdvanced handleClientChannelActiveAdvanced(NettyClientProperties nettyClientProperties) {
|
|
||||||
return new HandleClientChannelActiveAdvanced(nettyClientProperties);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public HandleDistributeDisconnectTypeAdvancedHandle handleDistributeDisconnectTypeAdvancedHandle(ClientChangeEvent clientChangeEvent) {
|
|
||||||
return new HandleDistributeDisconnectTypeAdvancedHandle(clientChangeEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public HandleDistributeStagingClosedTypeAdvanced handleDistributeStagingClosedTypeAdvanced() {
|
|
||||||
return new HandleDistributeStagingClosedTypeAdvanced();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public HandleDistributeStagingOpenedTypeAdvanced handleDistributeStagingOpenedTypeAdvanced() {
|
|
||||||
return new HandleDistributeStagingOpenedTypeAdvanced();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理 客户端渗透服务端init信息
|
|
||||||
*
|
|
||||||
* @return ClientHandleDistributeClientPermeateServerInitTypeAdvanced
|
|
||||||
*/
|
|
||||||
@Bean
|
|
||||||
public ClientHandleDistributeClientPermeateServerInitTypeAdvanced clientHandleDistributeClientPermeateServerInitTypeAdvanced(NettyClientProperties nettyClientProperties) {
|
|
||||||
return new ClientHandleDistributeClientPermeateServerInitTypeAdvanced(nettyClientProperties);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* 处理 客户端渗透服务端init close 信息
|
|
||||||
*
|
|
||||||
* @return ClientHandleDistributeClientPermeateServerCloseTypeAdvanced
|
|
||||||
*/
|
|
||||||
@Bean
|
|
||||||
public ClientHandleDistributeClientPermeateServerCloseTypeAdvanced clientHandleDistributeClientPermeateServerCloseTypeAdvanced( ) {
|
|
||||||
return new ClientHandleDistributeClientPermeateServerCloseTypeAdvanced();
|
|
||||||
}
|
|
||||||
@Bean
|
|
||||||
public ClientHandleDistributeClientPermeateServerTransferTypeAdvanced clientHandleDistributeClientPermeateServerTransferTypeAdvanced( ) {
|
|
||||||
return new ClientHandleDistributeClientPermeateServerTransferTypeAdvanced();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public ClientHandleDistributeClientPermeateClientCloseTypeAdvanced clientHandleDistributeClientPermeateClientCloseTypeAdvanced() {
|
|
||||||
return new ClientHandleDistributeClientPermeateClientCloseTypeAdvanced();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public ClientHandleDistributeClientPermeateClientInitTypeAdvanced clientHandleDistributeClientPermeateClientInitTypeAdvanced() {
|
|
||||||
return new ClientHandleDistributeClientPermeateClientInitTypeAdvanced();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public ClientHandleDistributeClientPermeateClientTransferCloseTypeAdvanced clientHandleDistributeClientPermeateClientTransferCloseTypeAdvanced() {
|
|
||||||
return new ClientHandleDistributeClientPermeateClientTransferCloseTypeAdvanced();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public ClientHandleDistributeServicePermeateClientRealConnectTypeAdvanced clientHandleDistributeSingleClientRealConnectTypeAdvanced(NettyClientProperties nettyClientProperties,
|
|
||||||
List<HandleChannelTypeAdvanced> handleChannelTypeAdvancedList) {
|
|
||||||
return new ClientHandleDistributeServicePermeateClientRealConnectTypeAdvanced(nettyClientProperties, handleChannelTypeAdvancedList);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public ClientHandleHandleDistributeClientPermeateServerTransferCloseTypeAdvanced clientHandleHandleDistributeClientPermeateServerTransferCloseTypeAdvanced() {
|
|
||||||
return new ClientHandleHandleDistributeClientPermeateServerTransferCloseTypeAdvanced();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,86 +0,0 @@
|
|||||||
package org.framework.lazy.cloud.network.heartbeat.client.config;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.client.infrastructure.entity.LazyNettyServerPropertiesDO;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.client.application.LazyNettyServerPropertiesApplication;
|
|
||||||
import org.springframework.beans.factory.DisposableBean;
|
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
|
||||||
import org.springframework.boot.CommandLineRunner;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.context.annotation.Role;
|
|
||||||
import org.wu.framework.lazy.orm.database.lambda.stream.lambda.LazyLambdaStream;
|
|
||||||
import org.wu.framework.lazy.orm.database.lambda.stream.wrapper.LazyWrappers;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 初始化配置
|
|
||||||
*/
|
|
||||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
|
||||||
@Slf4j
|
|
||||||
@Configuration
|
|
||||||
public class InitConfig implements CommandLineRunner, DisposableBean {
|
|
||||||
|
|
||||||
private final NettyClientProperties nettyClientProperties;
|
|
||||||
private final LazyLambdaStream lazyLambdaStream;
|
|
||||||
|
|
||||||
private final LazyNettyServerPropertiesApplication lazyNettyServerPropertiesApplication;
|
|
||||||
|
|
||||||
public InitConfig(NettyClientProperties nettyClientProperties, LazyLambdaStream lazyLambdaStream, LazyNettyServerPropertiesApplication lazyNettyServerPropertiesApplication) {
|
|
||||||
this.nettyClientProperties = nettyClientProperties;
|
|
||||||
this.lazyLambdaStream = lazyLambdaStream;
|
|
||||||
this.lazyNettyServerPropertiesApplication = lazyNettyServerPropertiesApplication;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run(String... args) throws Exception {
|
|
||||||
try {
|
|
||||||
// 存储配置到db
|
|
||||||
initDb2Config();
|
|
||||||
// 启动客户端连接
|
|
||||||
lazyNettyServerPropertiesApplication.starterAllClientSocket();
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 存储配置到db
|
|
||||||
*/
|
|
||||||
public void initDb2Config() {
|
|
||||||
|
|
||||||
String clientId = nettyClientProperties.getClientId();
|
|
||||||
String inetHost = nettyClientProperties.getInetHost();
|
|
||||||
int inetPort = nettyClientProperties.getInetPort();
|
|
||||||
if (Objects.isNull(clientId) ||
|
|
||||||
Objects.isNull(inetHost)) {
|
|
||||||
log.warn("配置信息为空,请通过页面添加配置信息:{}", nettyClientProperties);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
LazyNettyServerPropertiesDO lazyNettyServerPropertiesDO = new LazyNettyServerPropertiesDO();
|
|
||||||
lazyNettyServerPropertiesDO.setClientId(clientId);
|
|
||||||
lazyNettyServerPropertiesDO.setInetHost(inetHost);
|
|
||||||
lazyNettyServerPropertiesDO.setInetPort(inetPort);
|
|
||||||
lazyNettyServerPropertiesDO.setType(PropertiesType.CONFIG);
|
|
||||||
lazyNettyServerPropertiesDO.setIsDeleted(false);
|
|
||||||
// 根据服务端端口、port 唯一性验证
|
|
||||||
boolean exists = lazyLambdaStream.exists(LazyWrappers.<LazyNettyServerPropertiesDO>lambdaWrapper()
|
|
||||||
.eq(LazyNettyServerPropertiesDO::getInetHost, inetHost)
|
|
||||||
.eq(LazyNettyServerPropertiesDO::getInetPort, inetPort)
|
|
||||||
.eq(LazyNettyServerPropertiesDO::getClientId, clientId)
|
|
||||||
);
|
|
||||||
if (!exists) {
|
|
||||||
lazyLambdaStream.insert(lazyNettyServerPropertiesDO);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 程序关闭后执行
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void destroy() {
|
|
||||||
lazyNettyServerPropertiesApplication.destroyClientSocket();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
package org.framework.lazy.cloud.network.heartbeat.client.config;
|
package org.framework.lazy.cloud.network.heartbeat.client.config;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.common.enums.ProtocolType;
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.wu.framework.core.NormalUsedString;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* netty 客户服务端地址配置属性
|
* netty 客户服务端地址配置属性
|
||||||
@@ -13,6 +14,7 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
@Data
|
@Data
|
||||||
public class NettyClientProperties {
|
public class NettyClientProperties {
|
||||||
public static final String PREFIX = "spring.lazy.netty.client";
|
public static final String PREFIX = "spring.lazy.netty.client";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 服务端地址 如:127.0.0.1
|
* 服务端地址 如:127.0.0.1
|
||||||
*/
|
*/
|
||||||
@@ -30,7 +32,10 @@ public class NettyClientProperties {
|
|||||||
*/
|
*/
|
||||||
private String clientId;
|
private String clientId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 协议类型
|
||||||
|
*/
|
||||||
|
private ProtocolType protocolType = ProtocolType.TCP;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* 令牌key
|
* 令牌key
|
||||||
|
|||||||
@@ -0,0 +1,116 @@
|
|||||||
|
package org.framework.lazy.cloud.network.heartbeat.client.context;
|
||||||
|
|
||||||
|
import jakarta.annotation.PreDestroy;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.client.application.LazyNettyServerPropertiesApplication;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.client.config.NettyClientProperties;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.client.config.PropertiesType;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.client.infrastructure.entity.LazyNettyServerPropertiesDO;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.common.enums.ProtocolType;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.protocol.token.AuthenticationToken;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.protocol.token.AuthenticationTokenContext;
|
||||||
|
import org.springframework.beans.factory.DisposableBean;
|
||||||
|
import org.springframework.boot.context.event.ApplicationStartedEvent;
|
||||||
|
import org.springframework.context.ApplicationListener;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.wu.framework.lazy.orm.database.lambda.stream.lambda.LazyLambdaStream;
|
||||||
|
import org.wu.framework.lazy.orm.database.lambda.stream.wrapper.LazyWrappers;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class NettyClientSocketApplicationListener implements ApplicationListener<ApplicationStartedEvent>, DisposableBean {
|
||||||
|
|
||||||
|
|
||||||
|
private final NettyClientProperties nettyClientProperties;
|
||||||
|
private final LazyLambdaStream lazyLambdaStream;
|
||||||
|
|
||||||
|
private final LazyNettyServerPropertiesApplication lazyNettyServerPropertiesApplication;
|
||||||
|
|
||||||
|
public NettyClientSocketApplicationListener(NettyClientProperties nettyClientProperties,
|
||||||
|
LazyLambdaStream lazyLambdaStream,
|
||||||
|
LazyNettyServerPropertiesApplication lazyNettyServerPropertiesApplication) {
|
||||||
|
this.nettyClientProperties = nettyClientProperties;
|
||||||
|
this.lazyLambdaStream = lazyLambdaStream;
|
||||||
|
this.lazyNettyServerPropertiesApplication = lazyNettyServerPropertiesApplication;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 存储配置到db
|
||||||
|
*/
|
||||||
|
public void initDb2Config() {
|
||||||
|
|
||||||
|
try {
|
||||||
|
String clientId = nettyClientProperties.getClientId();
|
||||||
|
String inetHost = nettyClientProperties.getInetHost();
|
||||||
|
int inetPort = nettyClientProperties.getInetPort();
|
||||||
|
String appKey = nettyClientProperties.getAppKey();
|
||||||
|
String appSecret = nettyClientProperties.getAppSecret();
|
||||||
|
ProtocolType protocolType = nettyClientProperties.getProtocolType();
|
||||||
|
if (Objects.isNull(clientId) ||
|
||||||
|
Objects.isNull(inetHost)) {
|
||||||
|
log.warn("配置信息为空,请通过页面添加配置信息:{}", nettyClientProperties);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LazyNettyServerPropertiesDO lazyNettyServerPropertiesDO = new LazyNettyServerPropertiesDO();
|
||||||
|
|
||||||
|
lazyNettyServerPropertiesDO.setClientId(clientId);
|
||||||
|
lazyNettyServerPropertiesDO.setInetHost(inetHost);
|
||||||
|
lazyNettyServerPropertiesDO.setInetPort(inetPort);
|
||||||
|
lazyNettyServerPropertiesDO.setType(PropertiesType.CONFIG);
|
||||||
|
lazyNettyServerPropertiesDO.setIsDeleted(false);
|
||||||
|
lazyNettyServerPropertiesDO.setAppKey(appKey);
|
||||||
|
lazyNettyServerPropertiesDO.setAppSecret(appSecret);
|
||||||
|
lazyNettyServerPropertiesDO.setProtocolType(protocolType);
|
||||||
|
|
||||||
|
|
||||||
|
// 根据服务端端口、port 唯一性验证
|
||||||
|
boolean exists = lazyLambdaStream.exists(LazyWrappers.<LazyNettyServerPropertiesDO>lambdaWrapper()
|
||||||
|
.eq(LazyNettyServerPropertiesDO::getInetHost, inetHost)
|
||||||
|
.eq(LazyNettyServerPropertiesDO::getInetPort, inetPort)
|
||||||
|
.eq(LazyNettyServerPropertiesDO::getClientId, clientId)
|
||||||
|
.eq(LazyNettyServerPropertiesDO::getProtocolType, protocolType)
|
||||||
|
);
|
||||||
|
if (!exists) {
|
||||||
|
lazyLambdaStream.insert(lazyNettyServerPropertiesDO);
|
||||||
|
}
|
||||||
|
// 添加本地token
|
||||||
|
AuthenticationToken authenticationToken = new AuthenticationToken();
|
||||||
|
authenticationToken.setUsedByClientId(clientId);
|
||||||
|
authenticationToken.setAppKey(appKey);
|
||||||
|
authenticationToken.setAppSecret(appSecret);
|
||||||
|
AuthenticationTokenContext.setAuthenticationToken(clientId, appKey, appSecret);
|
||||||
|
}catch (Exception e){
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle an application event.
|
||||||
|
*
|
||||||
|
* @param event the event to respond to
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onApplicationEvent(ApplicationStartedEvent event) {
|
||||||
|
try {
|
||||||
|
// 存储配置到db
|
||||||
|
initDb2Config();
|
||||||
|
// 启动客户端连接
|
||||||
|
lazyNettyServerPropertiesApplication.starterAllClientSocket();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@PreDestroy
|
||||||
|
@Override
|
||||||
|
public void destroy() throws Exception {
|
||||||
|
lazyNettyServerPropertiesApplication.destroyClientSocket();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,14 +1,14 @@
|
|||||||
package org.framework.lazy.cloud.network.heartbeat.client.domain.model.lazy.netty.server.properties;
|
package org.framework.lazy.cloud.network.heartbeat.client.domain.model.lazy.netty.server.properties;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.enums.NettyClientStatus;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.client.config.PropertiesType;
|
import org.framework.lazy.cloud.network.heartbeat.client.config.PropertiesType;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.common.enums.NettyClientStatus;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.common.enums.ProtocolType;
|
||||||
|
import org.wu.framework.core.NormalUsedString;
|
||||||
|
|
||||||
import java.lang.String;
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.lang.Integer;
|
|
||||||
/**
|
/**
|
||||||
* describe 服务端配置信息
|
* describe 服务端配置信息
|
||||||
*
|
*
|
||||||
@@ -22,6 +22,7 @@ import java.lang.Integer;
|
|||||||
public class LazyNettyServerProperties {
|
public class LazyNettyServerProperties {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* 客户身份ID
|
* 客户身份ID
|
||||||
@@ -66,6 +67,22 @@ public class LazyNettyServerProperties {
|
|||||||
@Schema(description ="类型(配置、DB)",name ="type",example = "")
|
@Schema(description ="类型(配置、DB)",name ="type",example = "")
|
||||||
private PropertiesType type;
|
private PropertiesType type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 协议类型
|
||||||
|
*/
|
||||||
|
@Schema(description = "协议类型", name = "protocol_type", example = "")
|
||||||
|
private ProtocolType protocolType;
|
||||||
|
/**
|
||||||
|
* 令牌key
|
||||||
|
*/
|
||||||
|
@Schema(description = "令牌key", name = "appKey", example = "")
|
||||||
|
private String appKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 令牌密钥
|
||||||
|
*/
|
||||||
|
@Schema(description = "令牌密钥", name = "appSecret", example = "")
|
||||||
|
private String appSecret;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* 更新时间
|
* 更新时间
|
||||||
|
|||||||
@@ -2,47 +2,46 @@ package org.framework.lazy.cloud.network.heartbeat.client.infrastructure.convert
|
|||||||
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.client.domain.model.lazy.netty.server.properties.LazyNettyServerProperties;
|
import org.framework.lazy.cloud.network.heartbeat.client.domain.model.lazy.netty.server.properties.LazyNettyServerProperties;
|
||||||
import org.framework.lazy.cloud.network.heartbeat.client.infrastructure.entity.LazyNettyServerPropertiesDO;
|
import org.framework.lazy.cloud.network.heartbeat.client.infrastructure.entity.LazyNettyServerPropertiesDO;
|
||||||
import org.mapstruct.factory.Mappers;
|
import org.wu.framework.core.mapper.LazyStructMapper;
|
||||||
import org.mapstruct.Mapper;
|
import org.wu.framework.core.mapper.LazyStructMappers;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* describe 服务端配置信息
|
* describe 服务端配置信息
|
||||||
*
|
*
|
||||||
* @author Jia wei Wu
|
* @author Jia wei Wu
|
||||||
* @date 2024/04/03 03:00 下午
|
* @date 2024/04/03 03:00 下午
|
||||||
* @see org.wu.framework.lazy.orm.core.persistence.reverse.lazy.ddd.DefaultDDDLazyInfrastructureConverter
|
* @see org.wu.framework.lazy.orm.core.persistence.reverse.lazy.ddd.DefaultDDDLazyInfrastructureConverter
|
||||||
**/
|
**/
|
||||||
@Mapper
|
@LazyStructMapper
|
||||||
public interface LazyNettyServerPropertiesConverter {
|
public interface LazyNettyServerPropertiesConverter {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* describe MapStruct 创建的代理对象
|
* describe MapStruct 创建的代理对象
|
||||||
*
|
*
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
* @author Jia wei Wu
|
* @author Jia wei Wu
|
||||||
* @date 2024/04/03 03:00 下午
|
* @date 2024/04/03 03:00 下午
|
||||||
**/
|
**/
|
||||||
LazyNettyServerPropertiesConverter INSTANCE = Mappers.getMapper(LazyNettyServerPropertiesConverter.class);
|
LazyNettyServerPropertiesConverter INSTANCE = LazyStructMappers.getMapper(LazyNettyServerPropertiesConverter.class);
|
||||||
|
// LazyNettyServerPropertiesConverter INSTANCE = new LazyNettyServerPropertiesConverterImpl();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* describe 实体对象 转换成领域对象
|
* describe 实体对象 转换成领域对象
|
||||||
*
|
*
|
||||||
* @param lazyNettyServerPropertiesDO 服务端配置信息实体对象
|
* @param lazyNettyServerPropertiesDO 服务端配置信息实体对象
|
||||||
* @return {@link LazyNettyServerProperties} 服务端配置信息领域对象
|
* @return {@link LazyNettyServerProperties} 服务端配置信息领域对象
|
||||||
|
|
||||||
* @author Jia wei Wu
|
* @author Jia wei Wu
|
||||||
* @date 2024/04/03 03:00 下午
|
* @date 2024/04/03 03:00 下午
|
||||||
**/
|
**/
|
||||||
LazyNettyServerProperties toLazyNettyServerProperties(LazyNettyServerPropertiesDO lazyNettyServerPropertiesDO);
|
LazyNettyServerProperties toLazyNettyServerProperties(LazyNettyServerPropertiesDO lazyNettyServerPropertiesDO);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* describe 领域对象 转换成实体对象
|
* describe 领域对象 转换成实体对象
|
||||||
*
|
*
|
||||||
* @param lazyNettyServerProperties 服务端配置信息领域对象
|
* @param lazyNettyServerProperties 服务端配置信息领域对象
|
||||||
* @return {@link LazyNettyServerPropertiesDO} 服务端配置信息实体对象
|
* @return {@link LazyNettyServerPropertiesDO} 服务端配置信息实体对象
|
||||||
|
|
||||||
* @author Jia wei Wu
|
* @author Jia wei Wu
|
||||||
* @date 2024/04/03 03:00 下午
|
* @date 2024/04/03 03:00 下午
|
||||||
**/
|
**/
|
||||||
LazyNettyServerPropertiesDO fromLazyNettyServerProperties(LazyNettyServerProperties lazyNettyServerProperties);
|
LazyNettyServerPropertiesDO fromLazyNettyServerProperties(LazyNettyServerProperties lazyNettyServerProperties);
|
||||||
}
|
}
|
||||||
@@ -1,17 +1,18 @@
|
|||||||
package org.framework.lazy.cloud.network.heartbeat.client.infrastructure.entity;
|
package org.framework.lazy.cloud.network.heartbeat.client.infrastructure.entity;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.enums.NettyClientStatus;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.client.config.PropertiesType;
|
import org.framework.lazy.cloud.network.heartbeat.client.config.PropertiesType;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.common.enums.NettyClientStatus;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.common.enums.ProtocolType;
|
||||||
|
import org.wu.framework.core.NormalUsedString;
|
||||||
import org.wu.framework.lazy.orm.core.stereotype.LazyTable;
|
import org.wu.framework.lazy.orm.core.stereotype.LazyTable;
|
||||||
import org.wu.framework.lazy.orm.core.stereotype.LazyTableField;
|
import org.wu.framework.lazy.orm.core.stereotype.LazyTableField;
|
||||||
import org.wu.framework.lazy.orm.core.stereotype.*;
|
import org.wu.framework.lazy.orm.core.stereotype.LazyTableFieldId;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import org.wu.framework.lazy.orm.core.stereotype.LazyTableFieldUnique;
|
||||||
|
|
||||||
import java.lang.String;
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.lang.Integer;
|
|
||||||
/**
|
/**
|
||||||
* describe 服务端配置信息
|
* describe 服务端配置信息
|
||||||
*
|
*
|
||||||
@@ -26,12 +27,20 @@ import java.lang.Integer;
|
|||||||
public class LazyNettyServerPropertiesDO {
|
public class LazyNettyServerPropertiesDO {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 主键ID
|
||||||
|
*/
|
||||||
|
@Schema(description ="主键ID",name ="id",example = "")
|
||||||
|
@LazyTableFieldId(name = "id", comment = "主键ID")
|
||||||
|
private Long id;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* 客户身份ID
|
* 客户身份ID
|
||||||
*/
|
*/
|
||||||
@Schema(description ="客户身份ID",name ="clientId",example = "")
|
@Schema(description ="客户身份ID",name ="clientId",example = "")
|
||||||
@LazyTableFieldUnique(name="client_id",comment="客户身份ID",columnType="varchar(255)")
|
@LazyTableFieldUnique(name="client_id",comment="客户身份ID",columnType="varchar(25)")
|
||||||
private String clientId;
|
private String clientId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -75,6 +84,20 @@ public class LazyNettyServerPropertiesDO {
|
|||||||
@LazyTableField(name="is_deleted",comment="是否删除")
|
@LazyTableField(name="is_deleted",comment="是否删除")
|
||||||
private Boolean isDeleted;
|
private Boolean isDeleted;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 令牌key
|
||||||
|
*/
|
||||||
|
@Schema(description = "令牌key", name = "appKey", example = "")
|
||||||
|
@LazyTableField(name = "app_key", comment = "令牌key")
|
||||||
|
private String appKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 令牌密钥
|
||||||
|
*/
|
||||||
|
@Schema(description = "令牌密钥", name = "appSecret", example = "")
|
||||||
|
@LazyTableField(name = "app_secret", comment = "令牌密钥")
|
||||||
|
private String appSecret;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* 类型(配置、DB)
|
* 类型(配置、DB)
|
||||||
@@ -83,6 +106,13 @@ public class LazyNettyServerPropertiesDO {
|
|||||||
@LazyTableField(name="type",comment="类型(配置、DB)",columnType="varchar(255)")
|
@LazyTableField(name="type",comment="类型(配置、DB)",columnType="varchar(255)")
|
||||||
private PropertiesType type;
|
private PropertiesType type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 协议类型
|
||||||
|
*/
|
||||||
|
@Schema(description ="协议类型",name ="protocol_type",example = "")
|
||||||
|
@LazyTableField(name="protocol_type",comment="协议类型",columnType="varchar(255)")
|
||||||
|
private ProtocolType protocolType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* 更新时间
|
* 更新时间
|
||||||
|
|||||||
@@ -1,22 +1,19 @@
|
|||||||
package org.framework.lazy.cloud.network.heartbeat.client.infrastructure.persistence;
|
package org.framework.lazy.cloud.network.heartbeat.client.infrastructure.persistence;
|
||||||
|
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
import org.framework.lazy.cloud.network.heartbeat.client.domain.model.lazy.netty.server.properties.LazyNettyServerProperties;
|
import org.framework.lazy.cloud.network.heartbeat.client.domain.model.lazy.netty.server.properties.LazyNettyServerProperties;
|
||||||
import org.framework.lazy.cloud.network.heartbeat.client.domain.model.lazy.netty.server.properties.LazyNettyServerPropertiesRepository;
|
import org.framework.lazy.cloud.network.heartbeat.client.domain.model.lazy.netty.server.properties.LazyNettyServerPropertiesRepository;
|
||||||
import org.framework.lazy.cloud.network.heartbeat.client.infrastructure.entity.LazyNettyServerPropertiesDO;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.client.infrastructure.converter.LazyNettyServerPropertiesConverter;
|
import org.framework.lazy.cloud.network.heartbeat.client.infrastructure.converter.LazyNettyServerPropertiesConverter;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.client.infrastructure.entity.LazyNettyServerPropertiesDO;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
import org.wu.framework.lazy.orm.database.lambda.domain.LazyPage;
|
||||||
import java.util.stream.Collectors;
|
import org.wu.framework.lazy.orm.database.lambda.stream.lambda.LazyLambdaStream;
|
||||||
|
|
||||||
import org.wu.framework.lazy.orm.database.lambda.stream.wrapper.LazyWrappers;
|
import org.wu.framework.lazy.orm.database.lambda.stream.wrapper.LazyWrappers;
|
||||||
import org.wu.framework.web.response.Result;
|
import org.wu.framework.web.response.Result;
|
||||||
import org.wu.framework.web.response.ResultFactory;
|
import org.wu.framework.web.response.ResultFactory;
|
||||||
import jakarta.annotation.Resource;
|
|
||||||
import org.wu.framework.lazy.orm.database.lambda.stream.lambda.LazyLambdaStream;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
import org.wu.framework.lazy.orm.database.lambda.domain.LazyPage;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* describe 服务端配置信息
|
* describe 服务端配置信息
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
package org.framework.lazy.cloud.network.heartbeat.client.netty.advanced;
|
|
||||||
|
|
||||||
|
|
||||||
import io.netty.channel.Channel;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.MessageType;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.NettyProxyMsg;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.advanced.AbstractHandleChannelHeartbeatTypeAdvanced;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 服务端 处理客户端心跳
|
|
||||||
* TYPE_HEARTBEAT
|
|
||||||
*/
|
|
||||||
public class ClientHandleChannelHeartbeatTypeAdvanced extends AbstractHandleChannelHeartbeatTypeAdvanced<NettyProxyMsg> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理当前数据
|
|
||||||
*
|
|
||||||
* @param channel 当前通道
|
|
||||||
* @param msg 通道数据
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void doHandler(Channel channel, NettyProxyMsg msg) {
|
|
||||||
NettyProxyMsg hb = new NettyProxyMsg();
|
|
||||||
hb.setType(MessageType.TYPE_HEARTBEAT);
|
|
||||||
// channel.writeAndFlush(hb);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
package org.framework.lazy.cloud.network.heartbeat.client.netty.advanced;
|
|
||||||
|
|
||||||
|
|
||||||
import io.netty.channel.Channel;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.client.config.NettyClientProperties;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.client.netty.socket.NettyClientPermeateClientVisitorSocket;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.NettyProxyMsg;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.advanced.HandleChannelTypeAdvanced;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.advanced.client.AbstractHandleDistributeClientPermeateClientInitTypeAdvanced;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.enums.MessageTypeEnums;
|
|
||||||
import org.wu.framework.spring.utils.SpringContextHolder;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 客户端渗透客户端init信息
|
|
||||||
*
|
|
||||||
* @see MessageTypeEnums#DISTRIBUTE_CLIENT_PERMEATE_CLIENT_INIT
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
public class ClientHandleDistributeClientPermeateClientInitTypeAdvanced extends AbstractHandleDistributeClientPermeateClientInitTypeAdvanced<NettyProxyMsg> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理当前数据
|
|
||||||
*
|
|
||||||
* @param channel 当前通道
|
|
||||||
* @param nettyProxyMsg 通道数据
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void doHandler(Channel channel, NettyProxyMsg nettyProxyMsg) {
|
|
||||||
// 初始化 客户端渗透服务端socket
|
|
||||||
byte[] fromClientIdBytes = nettyProxyMsg.getClientId();
|
|
||||||
byte[] visitorPortBytes = nettyProxyMsg.getVisitorPort();
|
|
||||||
byte[] clientTargetIpBytes = nettyProxyMsg.getClientTargetIp();
|
|
||||||
byte[] clientTargetPortBytes = nettyProxyMsg.getClientTargetPort();
|
|
||||||
byte[] toClientIdBytes = nettyProxyMsg.getData();
|
|
||||||
|
|
||||||
String fromClientId = new String(fromClientIdBytes);
|
|
||||||
String toClientId = new String(toClientIdBytes);
|
|
||||||
Integer visitorPort = Integer.parseInt(new String(visitorPortBytes));
|
|
||||||
String clientTargetIp = new String(clientTargetIpBytes);
|
|
||||||
Integer clientTargetPort = Integer.parseInt(new String(clientTargetPortBytes));
|
|
||||||
|
|
||||||
List<HandleChannelTypeAdvanced> handleChannelTypeAdvancedList = new ArrayList<>(SpringContextHolder.getApplicationContext().getBeansOfType(HandleChannelTypeAdvanced.class).values());
|
|
||||||
// ChannelFlowAdapter channelFlowAdapter = SpringContextHolder.getBean(ChannelFlowAdapter.class);
|
|
||||||
NettyClientProperties nettyClientProperties = SpringContextHolder.getBean(NettyClientProperties.class);
|
|
||||||
log.info("client permeate client from client_id:【{}】 to_client_id【{}】with visitor_port【{}】, clientTargetIp:【{}】clientTargetPort:【{}】",
|
|
||||||
fromClientId, toClientId, visitorPort, clientTargetIp, clientTargetPort);
|
|
||||||
NettyClientPermeateClientVisitorSocket nettyClientPermeateClientVisitorSocket =
|
|
||||||
NettyClientPermeateClientVisitorSocket.NettyClientPermeateClientVisitorSocketBuilder.builder()
|
|
||||||
.builderClientId(fromClientId)
|
|
||||||
.builderClientTargetIp(clientTargetIp)
|
|
||||||
.builderClientTargetPort(clientTargetPort)
|
|
||||||
.builderVisitorPort(visitorPort)
|
|
||||||
.builderNettyClientProperties(nettyClientProperties)
|
|
||||||
// .builderChannelFlowAdapter(channelFlowAdapter)
|
|
||||||
.builderToClientId(toClientId)
|
|
||||||
.builderHandleChannelTypeAdvancedList(handleChannelTypeAdvancedList)
|
|
||||||
|
|
||||||
.build();
|
|
||||||
try {
|
|
||||||
nettyClientPermeateClientVisitorSocket.start();
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
package org.framework.lazy.cloud.network.heartbeat.client.netty.advanced;
|
|
||||||
|
|
||||||
|
|
||||||
import io.netty.channel.Channel;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.client.config.NettyClientProperties;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.client.netty.socket.NettyClientPermeateClientVisitorSocket;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.NettyProxyMsg;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.advanced.HandleChannelTypeAdvanced;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.advanced.client.AbstractHandleDistributeClientPermeateClientTransferCloseTypeAdvanced;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.enums.MessageTypeEnums;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.utils.ChannelAttributeKeyUtils;
|
|
||||||
import org.wu.framework.spring.utils.SpringContextHolder;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 下发客户端渗透客户端通信通道关闭
|
|
||||||
*
|
|
||||||
* @see MessageTypeEnums#DISTRIBUTE_CLIENT_PERMEATE_CLIENT_TRANSFER_CLOSE
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
public class ClientHandleDistributeClientPermeateClientTransferCloseTypeAdvanced extends AbstractHandleDistributeClientPermeateClientTransferCloseTypeAdvanced<NettyProxyMsg> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理当前数据
|
|
||||||
*
|
|
||||||
* @param channel 当前通道
|
|
||||||
* @param nettyProxyMsg 通道数据
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void doHandler(Channel channel, NettyProxyMsg nettyProxyMsg) {
|
|
||||||
// 关闭客户端真实通道、访客通道
|
|
||||||
Channel realChannel = ChannelAttributeKeyUtils.getNextChannel(channel);
|
|
||||||
realChannel.close();// 真实通道关闭
|
|
||||||
channel.close(); // 数据传输通道关闭
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
package org.framework.lazy.cloud.network.heartbeat.client.netty.advanced;
|
|
||||||
|
|
||||||
|
|
||||||
import io.netty.channel.Channel;
|
|
||||||
import io.netty.channel.ChannelOption;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.client.netty.socket.NettyClientPermeateClientRealSocket;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.NettyProxyMsg;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.advanced.client.AbstractHandleDistributeClientTransferClientPermeateChannelConnectionSuccessfulTypeAdvanced;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.advanced.client.AbstractHandleDistributeClientTransferClientPermeateChannelInitSuccessfulTypeAdvanced;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.enums.MessageTypeEnums;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.utils.ChannelAttributeKeyUtils;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 下发 客户端渗透客户端数据传输通道init 成功
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @see MessageTypeEnums#DISTRIBUTE_CLIENT_TRANSFER_CLIENT_PERMEATE_CHANNEL_CONNECTION_SUCCESSFUL
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
public class ClientHandleDistributeClientTransferClientPermeateChannelInitSuccessfulTypeAdvanced extends AbstractHandleDistributeClientTransferClientPermeateChannelInitSuccessfulTypeAdvanced<NettyProxyMsg> {
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理当前数据
|
|
||||||
*
|
|
||||||
* @param channel 当前通道
|
|
||||||
* @param nettyProxyMsg 通道数据
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void doHandler(Channel channel, NettyProxyMsg nettyProxyMsg) {
|
|
||||||
// 连接成功 开启自动读取写
|
|
||||||
byte[] msgClientId = nettyProxyMsg.getClientId();
|
|
||||||
byte[] msgClientTargetIp = nettyProxyMsg.getClientTargetIp();
|
|
||||||
byte[] msgClientTargetPort = nettyProxyMsg.getClientTargetPort();
|
|
||||||
byte[] msgVisitorId = nettyProxyMsg.getVisitorId();
|
|
||||||
byte[] msgVisitorPort = nettyProxyMsg.getVisitorPort();
|
|
||||||
|
|
||||||
Channel nextChannel = ChannelAttributeKeyUtils.getNextChannel(channel);
|
|
||||||
nextChannel.config().setOption(ChannelOption.AUTO_READ, true);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
package org.framework.lazy.cloud.network.heartbeat.client.netty.advanced;
|
|
||||||
|
|
||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
|
||||||
import io.netty.channel.Channel;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.NettyProxyMsg;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.advanced.client.AbstractHandleDistributeClientTransferClientRequestTypeAdvanced;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.enums.MessageTypeEnums;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.utils.ChannelAttributeKeyUtils;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 下发客户端渗透客户端数据传输
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @see MessageTypeEnums#DISTRIBUTE_CLIENT_PERMEATE_CLIENT_TRANSFER_REQUEST
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
public class ClientHandleDistributeClientTransferClientRequestTypeAdvanced extends AbstractHandleDistributeClientTransferClientRequestTypeAdvanced<NettyProxyMsg> {
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理当前数据
|
|
||||||
*
|
|
||||||
* @param channel 当前通道
|
|
||||||
* @param nettyProxyMsg 通道数据
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void doHandler(Channel channel, NettyProxyMsg nettyProxyMsg) {
|
|
||||||
Channel nextChannel = ChannelAttributeKeyUtils.getNextChannel(channel);
|
|
||||||
// 把数据转到真实服务
|
|
||||||
ByteBuf buf = channel.config().getAllocator().buffer(nettyProxyMsg.getData().length);
|
|
||||||
buf.writeBytes(nettyProxyMsg.getData());
|
|
||||||
log.info("client permeate client send request to real socket byte:{} ",new String(nettyProxyMsg.getData()));
|
|
||||||
nextChannel.writeAndFlush(buf);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
package org.framework.lazy.cloud.network.heartbeat.client.netty.advanced;
|
|
||||||
|
|
||||||
|
|
||||||
import io.netty.channel.Channel;
|
|
||||||
import io.netty.channel.ChannelOption;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.client.netty.handler.NettyClientPermeateServerVisitorHandler;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.client.netty.socket.NettyClientPermeateServerVisitorTransferSocket;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.NettyProxyMsg;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.advanced.client.AbstractHandleDistributeClientTransferServerPermeateChannelConnectionSuccessfulTypeAdvanced;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.enums.MessageTypeEnums;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.utils.ChannelAttributeKeyUtils;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 客户端渗透服务端数据传输通道连接成功
|
|
||||||
* @see NettyClientPermeateServerVisitorTransferSocket
|
|
||||||
* @see NettyClientPermeateServerVisitorHandler
|
|
||||||
*
|
|
||||||
* @see MessageTypeEnums#DISTRIBUTE_CLIENT_TRANSFER_SERVER_PERMEATE_CHANNEL_CONNECTION_SUCCESSFUL
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
public class ClientHandleDistributeClientTransferServerPermeateChannelConnectionSuccessfulTypeAdvanced extends AbstractHandleDistributeClientTransferServerPermeateChannelConnectionSuccessfulTypeAdvanced<NettyProxyMsg> {
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理当前数据
|
|
||||||
*
|
|
||||||
* @param transferChannel 当前通道
|
|
||||||
* @param nettyProxyMsg 通道数据
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void doHandler(Channel transferChannel, NettyProxyMsg nettyProxyMsg) {
|
|
||||||
// 连接成功 开启自动读取写
|
|
||||||
byte[] msgVisitorId = nettyProxyMsg.getVisitorId();
|
|
||||||
String visitorId = new String(msgVisitorId);
|
|
||||||
Channel nextChannel = ChannelAttributeKeyUtils.getNextChannel(transferChannel);
|
|
||||||
nextChannel.config().setOption(ChannelOption.AUTO_READ, true);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
package org.framework.lazy.cloud.network.heartbeat.client.netty.advanced;
|
|
||||||
|
|
||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
|
||||||
import io.netty.channel.Channel;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.NettyProxyMsg;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.advanced.client.AbstractHandleDistributeServicePermeateClientTransferClientResponseTypeAdvanced;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.enums.MessageTypeEnums;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.utils.ChannelAttributeKeyUtils;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 下发客户端渗透客户端数据传输响应
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @see MessageTypeEnums#DISTRIBUTE_CLIENT_PERMEATE_CLIENT_TRANSFER_RESPONSE
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
public class ClientHandleDistributeServicePermeateClientTransferClientResponseTypeAdvanced extends AbstractHandleDistributeServicePermeateClientTransferClientResponseTypeAdvanced<NettyProxyMsg> {
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理当前数据
|
|
||||||
*
|
|
||||||
* @param channel 当前通道
|
|
||||||
* @param nettyProxyMsg 通道数据
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void doHandler(Channel channel, NettyProxyMsg nettyProxyMsg) {
|
|
||||||
Channel nextChannel = ChannelAttributeKeyUtils.getNextChannel(channel);
|
|
||||||
// 把数据转到真实服务
|
|
||||||
ByteBuf buf = channel.config().getAllocator().buffer(nettyProxyMsg.getData().length);
|
|
||||||
buf.writeBytes(nettyProxyMsg.getData());
|
|
||||||
|
|
||||||
nextChannel.writeAndFlush(buf);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
package org.framework.lazy.cloud.network.heartbeat.client.netty.advanced;
|
|
||||||
|
|
||||||
import io.netty.channel.Channel;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.NettyProxyMsg;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.advanced.client.AbstractHandleDistributeSingleClientMessageTypeAdvanced;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 接收服务端发送过来的聊天信息
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
public class ClientHandleDistributeSingleClientMessageTypeAdvanced extends AbstractHandleDistributeSingleClientMessageTypeAdvanced<NettyProxyMsg> {
|
|
||||||
/**
|
|
||||||
* 处理当前数据
|
|
||||||
*
|
|
||||||
* @param channel 当前通道
|
|
||||||
* @param nettyProxyMsg 通道数据
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected void doHandler(Channel channel, NettyProxyMsg nettyProxyMsg) {
|
|
||||||
byte[] clientId = nettyProxyMsg.getClientId();
|
|
||||||
byte[] data = nettyProxyMsg.getData();
|
|
||||||
log.info("接收客户端:{},发送过来的聊天信息:{}", new String(clientId), new String(data));
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
package org.framework.lazy.cloud.network.heartbeat.client.netty.advanced;
|
|
||||||
|
|
||||||
import io.netty.channel.Channel;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.NettyCommunicationIdContext;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.NettyProxyMsg;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.NettyRealIdContext;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.advanced.client.AbstractHandleDistributeSingleClientRealCloseVisitorTypeAdvanced;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
public class ClientHandleDistributeSingleClientRealCloseVisitorTypeAdvanced extends AbstractHandleDistributeSingleClientRealCloseVisitorTypeAdvanced<NettyProxyMsg> {
|
|
||||||
/**
|
|
||||||
* 处理当前数据
|
|
||||||
*
|
|
||||||
* @param channel 当前通道
|
|
||||||
* @param nettyProxyMsg 通道数据
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected void doHandler(Channel channel, NettyProxyMsg nettyProxyMsg) {
|
|
||||||
// 关闭代理的真实通道
|
|
||||||
byte[] visitorId = nettyProxyMsg.getVisitorId();
|
|
||||||
NettyRealIdContext.clear(visitorId);
|
|
||||||
NettyCommunicationIdContext.clear(visitorId);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
package org.framework.lazy.cloud.network.heartbeat.client.netty.advanced;
|
|
||||||
|
|
||||||
|
|
||||||
import io.netty.channel.Channel;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.client.config.NettyClientProperties;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.NettyProxyMsg;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.advanced.client.AbstractHandleDistributeClientPermeateServerTransferCloseTypeAdvanced;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.enums.MessageTypeEnums;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.utils.ChannelAttributeKeyUtils;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 下发 客户端渗透服务端通信通道关闭
|
|
||||||
*
|
|
||||||
* @see MessageTypeEnums#DISTRIBUTE_CLIENT_PERMEATE_SERVER_TRANSFER_CLOSE
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
public class ClientHandleHandleDistributeClientPermeateServerTransferCloseTypeAdvanced extends AbstractHandleDistributeClientPermeateServerTransferCloseTypeAdvanced<NettyProxyMsg> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理当前数据
|
|
||||||
*
|
|
||||||
* @param channel 当前通道
|
|
||||||
* @param nettyProxyMsg 通道数据
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void doHandler(Channel channel, NettyProxyMsg nettyProxyMsg) {
|
|
||||||
// 关闭本地通信通道
|
|
||||||
Channel nextChannel = ChannelAttributeKeyUtils.getNextChannel(channel);
|
|
||||||
channel.close();
|
|
||||||
nextChannel.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
package org.framework.lazy.cloud.network.heartbeat.client.netty.advanced;
|
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSONObject;
|
|
||||||
import io.netty.channel.Channel;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.client.netty.event.ClientChangeEvent;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.NettyProxyMsg;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.advanced.client.AbstractHandleDistributeConnectSuccessNotificationTypeAdvancedHandle;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 客户端连接成功通知
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
public class HandleDistributeConnectSuccessNotificationTypeAdvancedHandle extends AbstractHandleDistributeConnectSuccessNotificationTypeAdvancedHandle<NettyProxyMsg> {
|
|
||||||
|
|
||||||
private final ClientChangeEvent clientChangeEvent;
|
|
||||||
|
|
||||||
|
|
||||||
public HandleDistributeConnectSuccessNotificationTypeAdvancedHandle(ClientChangeEvent clientChangeEvent) {
|
|
||||||
this.clientChangeEvent = clientChangeEvent;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理当前数据
|
|
||||||
*
|
|
||||||
* @param channel 当前通道
|
|
||||||
* @param msg 通道数据
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected void doHandler(Channel channel, NettyProxyMsg msg) {
|
|
||||||
// 客户端ID:{},客户端:{}连接成功
|
|
||||||
log.warn("Client ID: {}, Client Data : {} Connection successful", new String(msg.getClientId()), new String(msg.getData()));
|
|
||||||
|
|
||||||
|
|
||||||
// 存储其他客户端状态
|
|
||||||
List<String> clientIdList = JSONObject.parseArray(new String(msg.getData()), String.class);
|
|
||||||
for (String tenantId : clientIdList) {
|
|
||||||
clientChangeEvent.clientOnLine(tenantId);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
package org.framework.lazy.cloud.network.heartbeat.client.netty.advanced;
|
|
||||||
|
|
||||||
|
|
||||||
import io.netty.channel.Channel;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.client.netty.event.ClientChangeEvent;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.NettyProxyMsg;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.advanced.client.AbstractHandleDistributeDisconnectTypeAdvancedHandle;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 服务端处理客户端断开连接处理
|
|
||||||
* TYPE_DISCONNECT
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
public class HandleDistributeDisconnectTypeAdvancedHandle extends AbstractHandleDistributeDisconnectTypeAdvancedHandle<NettyProxyMsg> {
|
|
||||||
|
|
||||||
|
|
||||||
private final ClientChangeEvent clientChangeEvent;
|
|
||||||
|
|
||||||
public HandleDistributeDisconnectTypeAdvancedHandle(ClientChangeEvent clientChangeEvent) {
|
|
||||||
this.clientChangeEvent = clientChangeEvent;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理当前数据
|
|
||||||
*
|
|
||||||
* @param channel 当前通道
|
|
||||||
* @param msg 通道数据
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void doHandler(Channel channel, NettyProxyMsg msg) {
|
|
||||||
// 服务下线
|
|
||||||
byte[] data = msg.getData();
|
|
||||||
byte[] clientId = msg.getClientId();
|
|
||||||
String tenantId = new String(clientId);
|
|
||||||
//客户端:{}下线
|
|
||||||
log.warn("Client: {} Offline", tenantId);
|
|
||||||
clientChangeEvent.clientOffLine(tenantId);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
package org.framework.lazy.cloud.network.heartbeat.client.netty.advanced;
|
|
||||||
|
|
||||||
import io.netty.channel.Channel;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.NettyProxyMsg;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.advanced.client.AbstractHandleDistributeStagingClosedTypeAdvanced;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 服务端下发暂存关闭消息处理
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
public class HandleDistributeStagingClosedTypeAdvanced extends AbstractHandleDistributeStagingClosedTypeAdvanced<NettyProxyMsg> {
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理当前数据
|
|
||||||
*
|
|
||||||
* @param channel 当前通道
|
|
||||||
* @param msg 通道数据
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected void doHandler(Channel channel, NettyProxyMsg msg) {
|
|
||||||
String clientId = new String(msg.getClientId());
|
|
||||||
log.info("客户端:{}离线暂存关闭", clientId);
|
|
||||||
// 修改redis 客户端暂存状态
|
|
||||||
// String stagingStatusKey = StagingConfigKeyConstant.getStagingStatusKey(clientId);
|
|
||||||
// stringRedisTemplate.opsForValue().set(stagingStatusKey, StagingStatus.CLOSED.name());
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
package org.framework.lazy.cloud.network.heartbeat.client.netty.advanced;
|
|
||||||
|
|
||||||
import io.netty.channel.Channel;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.NettyProxyMsg;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.advanced.client.AbstractHandleDistributeStagingOpenedTypeAdvanced;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 服务端下发暂存开启消息处理
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
public class HandleDistributeStagingOpenedTypeAdvanced extends AbstractHandleDistributeStagingOpenedTypeAdvanced<NettyProxyMsg> {
|
|
||||||
|
|
||||||
|
|
||||||
public HandleDistributeStagingOpenedTypeAdvanced() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理当前数据
|
|
||||||
*
|
|
||||||
* @param channel 当前通道
|
|
||||||
* @param msg 通道数据
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected void doHandler(Channel channel, NettyProxyMsg msg) {
|
|
||||||
String clientId = new String(msg.getClientId());
|
|
||||||
//客户端:{}离线暂存开启
|
|
||||||
log.warn("Client: {} Offline temporary storage enabled", new String(msg.getClientId()));
|
|
||||||
// 修改redis 客户端暂存状态
|
|
||||||
// String stagingStatusKey = StagingConfigKeyConstant.getStagingStatusKey(clientId);
|
|
||||||
// stringRedisTemplate.opsForValue().set(stagingStatusKey, StagingStatus.OPENED.name());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.framework.lazy.cloud.network.heartbeat.client.netty;
|
package org.framework.lazy.cloud.network.heartbeat.client.netty.permeate;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
@@ -11,16 +11,17 @@ import java.util.List;
|
|||||||
|
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@Data
|
@Data
|
||||||
public class InternalNetworkClientPermeateClientVisitor implements InternalNetworkPermeate {
|
public class NettyClientPermeateClientVisitor implements InternalNetworkPermeate {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 当前客户端ID
|
* 当前客户端ID
|
||||||
*/
|
*/
|
||||||
private String fromClientId;
|
private String originClientId;
|
||||||
/**
|
/**
|
||||||
* 目标客户端ID
|
* 目标客户端ID
|
||||||
*/
|
*/
|
||||||
private String toClientId;
|
private String targetClientId;
|
||||||
/**
|
/**
|
||||||
* 目标地址
|
* 目标地址
|
||||||
*/
|
*/
|
||||||
@@ -1,17 +1,16 @@
|
|||||||
package org.framework.lazy.cloud.network.heartbeat.client.netty;
|
package org.framework.lazy.cloud.network.heartbeat.client.netty.permeate;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import org.framework.lazy.cloud.network.heartbeat.client.config.NettyClientProperties;
|
import org.framework.lazy.cloud.network.heartbeat.client.config.NettyClientProperties;
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.InternalNetworkPermeate;
|
import org.framework.lazy.cloud.network.heartbeat.common.InternalNetworkPermeate;
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.adapter.ChannelFlowAdapter;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.advanced.HandleChannelTypeAdvanced;
|
import org.framework.lazy.cloud.network.heartbeat.common.advanced.HandleChannelTypeAdvanced;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@Data
|
@Data
|
||||||
public class InternalNetworkPermeateServerVisitor implements InternalNetworkPermeate {
|
public class NettyClientPermeateServerVisitor implements InternalNetworkPermeate {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 目标地址
|
* 目标地址
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package org.framework.lazy.cloud.network.heartbeat.client.netty.permeate;
|
||||||
|
|
||||||
|
public interface NettyClientSocket {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建客户端链接服务端
|
||||||
|
* @throws InterruptedException 异常信息
|
||||||
|
*/
|
||||||
|
void newConnect2Server() throws InterruptedException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关闭链接
|
||||||
|
*/
|
||||||
|
void shutdown();
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.framework.lazy.cloud.network.heartbeat.client.netty.event;
|
package org.framework.lazy.cloud.network.heartbeat.client.netty.permeate.event;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 客户端状态变更事件
|
* 客户端状态变更事件
|
||||||
@@ -13,12 +13,12 @@ public interface ClientChangeEvent {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 推送客户端在线
|
* 推送客户端在线
|
||||||
* @param clientId 客户端
|
*
|
||||||
* @param inetHost 服务端ip
|
* @param inetHost 服务端ip
|
||||||
* @param inetPort 服务端端口
|
* @param inetPort 服务端端口
|
||||||
* @param serverId 服务端ID
|
* @param clientId 客户端
|
||||||
*/
|
*/
|
||||||
void clientOnLine(String inetHost, int inetPort,String serverId ,String clientId);
|
void clientOnLine(String inetHost, int inetPort,String clientId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 推送客户端离线
|
* 推送客户端离线
|
||||||
@@ -30,10 +30,9 @@ public interface ClientChangeEvent {
|
|||||||
*
|
*
|
||||||
* @param inetHost 服务端ip
|
* @param inetHost 服务端ip
|
||||||
* @param inetPort 服务端端口
|
* @param inetPort 服务端端口
|
||||||
* @param serverId 服务端ID
|
|
||||||
* @param clientId 客户端
|
* @param clientId 客户端
|
||||||
*/
|
*/
|
||||||
void clientOffLine(String inetHost, int inetPort,String serverId,String clientId);
|
void clientOffLine(String inetHost, int inetPort,String clientId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 暂存开启
|
* 暂存开启
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.framework.lazy.cloud.network.heartbeat.client.netty.event;
|
package org.framework.lazy.cloud.network.heartbeat.client.netty.permeate.event;
|
||||||
|
|
||||||
|
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
@@ -51,11 +51,10 @@ public class DefaultClientChangeEventImpl implements ClientChangeEvent {
|
|||||||
*
|
*
|
||||||
* @param inetHost 服务端ip
|
* @param inetHost 服务端ip
|
||||||
* @param inetPort 服务端端口
|
* @param inetPort 服务端端口
|
||||||
* @param serverId 服务端ID
|
|
||||||
* @param clientId 客户端
|
* @param clientId 客户端
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void clientOnLine(String inetHost, int inetPort, String serverId, String clientId) {
|
public void clientOnLine(String inetHost, int inetPort, String clientId) {
|
||||||
LazyNettyServerProperties lazyNettyServerProperties = new LazyNettyServerProperties();
|
LazyNettyServerProperties lazyNettyServerProperties = new LazyNettyServerProperties();
|
||||||
lazyNettyServerProperties.setClientId(clientId);
|
lazyNettyServerProperties.setClientId(clientId);
|
||||||
lazyNettyServerProperties.setInetHost(inetHost);
|
lazyNettyServerProperties.setInetHost(inetHost);
|
||||||
@@ -92,11 +91,10 @@ public class DefaultClientChangeEventImpl implements ClientChangeEvent {
|
|||||||
*
|
*
|
||||||
* @param inetHost 服务端ip
|
* @param inetHost 服务端ip
|
||||||
* @param inetPort 服务端端口
|
* @param inetPort 服务端端口
|
||||||
* @param serverId
|
|
||||||
* @param clientId 客户端
|
* @param clientId 客户端
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void clientOffLine(String inetHost, int inetPort, String serverId, String clientId) {
|
public void clientOffLine(String inetHost, int inetPort, String clientId) {
|
||||||
LazyNettyServerProperties lazyNettyServerProperties = new LazyNettyServerProperties();
|
LazyNettyServerProperties lazyNettyServerProperties = new LazyNettyServerProperties();
|
||||||
lazyNettyServerProperties.setClientId(clientId);
|
lazyNettyServerProperties.setClientId(clientId);
|
||||||
lazyNettyServerProperties.setInetHost(inetHost);
|
lazyNettyServerProperties.setInetHost(inetHost);
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package org.framework.lazy.cloud.network.heartbeat.client.netty.permeate.tcp.advanced;
|
||||||
|
|
||||||
|
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.common.advanced.payload.NettyChannelContext;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.common.advanced.payload.NettyProxyMsg;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.common.advanced.permeate.tcp.AbstractTcpHandleChannelHeartbeatTypeAdvanced;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.common.constant.TcpMessageType;
|
||||||
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
|
import org.springframework.context.annotation.Role;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 服务端 处理客户端心跳
|
||||||
|
* TCP_TYPE_HEARTBEAT
|
||||||
|
*/
|
||||||
|
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||||
|
public class ClientHandleTcpChannelHeartbeatTypeAdvanced extends AbstractTcpHandleChannelHeartbeatTypeAdvanced<NettyProxyMsg> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理当前数据
|
||||||
|
*
|
||||||
|
* @param nettyChannelContext 当前通道
|
||||||
|
* @param msg 通道数据
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void doHandler(NettyChannelContext nettyChannelContext, NettyProxyMsg msg) {
|
||||||
|
NettyProxyMsg hb = new NettyProxyMsg();
|
||||||
|
hb.setType(TcpMessageType.TCP_TYPE_HEARTBEAT);
|
||||||
|
// nettyChannelContext.writeAndFlush(hb);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
package org.framework.lazy.cloud.network.heartbeat.client.netty.permeate.tcp.advanced;
|
||||||
|
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.channel.Channel;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.client.config.NettyClientProperties;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.common.advanced.payload.NettyChannelContext;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.common.advanced.payload.NettyProxyMsg;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.common.advanced.permeate.tcp.client.AbstractHandleTcpDistributeServicePermeateClientTransferTypeAdvanced;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.common.enums.TcpMessageTypeEnums;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.common.utils.ChannelAttributeKeyUtils;
|
||||||
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
|
import org.springframework.context.annotation.Role;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 服务端处理客户端数据传输
|
||||||
|
*
|
||||||
|
* @see TcpMessageTypeEnums#TCP_DISTRIBUTE_CLIENT_TRANSFER
|
||||||
|
*/
|
||||||
|
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||||
|
@Slf4j
|
||||||
|
public class ClientHandleTcpChannelTransferTypeAdvancedHandleDistributeTcpDistribute extends AbstractHandleTcpDistributeServicePermeateClientTransferTypeAdvanced<NettyProxyMsg> {
|
||||||
|
|
||||||
|
private final NettyClientProperties nettyClientProperties;
|
||||||
|
|
||||||
|
public ClientHandleTcpChannelTransferTypeAdvancedHandleDistributeTcpDistribute(NettyClientProperties nettyClientProperties) {
|
||||||
|
this.nettyClientProperties = nettyClientProperties;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理当前数据
|
||||||
|
*
|
||||||
|
* @param nettyChannelContext 当前通道
|
||||||
|
* @param nettyProxyMsg 通道数据
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void doHandler(NettyChannelContext nettyChannelContext, NettyProxyMsg nettyProxyMsg) {
|
||||||
|
Channel channel = nettyChannelContext.channel();
|
||||||
|
log.debug("接收到服务端需要内网穿透的数据:{}" , nettyProxyMsg);
|
||||||
|
String clientId = nettyClientProperties.getClientId();
|
||||||
|
byte[] visitorPort = nettyProxyMsg.getVisitorPort();
|
||||||
|
byte[] clientTargetIp = nettyProxyMsg.getTargetIp();
|
||||||
|
byte[] clientTargetPort = nettyProxyMsg.getTargetPort();
|
||||||
|
byte[] visitorId = nettyProxyMsg.getVisitorId();
|
||||||
|
// 真实服务通道
|
||||||
|
// Channel realChannel = NettyRealIdContext.getReal(new String(visitorId));
|
||||||
|
Channel nextChannel = ChannelAttributeKeyUtils.getNextChannel(channel);
|
||||||
|
if (nextChannel == null) {
|
||||||
|
log.error("无法获取访客:{} 真实服务", new String(visitorId));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 把数据转到真实服务
|
||||||
|
ByteBuf buf = channel.config().getAllocator().buffer(nettyProxyMsg.getData().length);
|
||||||
|
buf.writeBytes(nettyProxyMsg.getData());
|
||||||
|
|
||||||
|
nextChannel.writeAndFlush(buf);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package org.framework.lazy.cloud.network.heartbeat.client.netty.permeate.tcp.advanced;
|
||||||
|
|
||||||
|
import io.netty.channel.Channel;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.client.config.NettyClientProperties;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.common.ChannelContext;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.common.advanced.payload.NettyChannelContext;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.common.advanced.payload.NettyProxyMsg;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.common.advanced.permeate.tcp.client.AbstractHandleTcpClientChannelActiveAdvanced;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.common.utils.ChannelAttributeKeyUtils;
|
||||||
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
|
import org.springframework.context.annotation.Role;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 客户端通道 is active
|
||||||
|
*/
|
||||||
|
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||||
|
public class ClientHandleTcpClientChannelActiveAdvanced extends AbstractHandleTcpClientChannelActiveAdvanced<NettyProxyMsg> {
|
||||||
|
private final NettyClientProperties nettyClientProperties;
|
||||||
|
|
||||||
|
public ClientHandleTcpClientChannelActiveAdvanced(NettyClientProperties nettyClientProperties) {
|
||||||
|
this.nettyClientProperties = nettyClientProperties;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理当前数据
|
||||||
|
*
|
||||||
|
* @param nettyChannelContext 当前通道
|
||||||
|
* @param nettyProxyMsg 通道数据
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void doHandler(NettyChannelContext nettyChannelContext, NettyProxyMsg nettyProxyMsg) {
|
||||||
|
Channel channel = nettyChannelContext.channel();
|
||||||
|
// 缓存当前通道
|
||||||
|
String clientId = nettyProxyMsg.clientId();
|
||||||
|
|
||||||
|
ChannelContext.push(channel, clientId);
|
||||||
|
ChannelAttributeKeyUtils.buildClientId(channel, clientId);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,33 +1,35 @@
|
|||||||
package org.framework.lazy.cloud.network.heartbeat.client.netty.advanced;
|
package org.framework.lazy.cloud.network.heartbeat.client.netty.permeate.tcp.advanced;
|
||||||
|
|
||||||
|
|
||||||
import io.netty.channel.Channel;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.NettyProxyMsg;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.NettyVisitorPortContext;
|
import org.framework.lazy.cloud.network.heartbeat.common.NettyVisitorPortContext;
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.advanced.client.AbstractHandleDistributeClientPermeateClientCloseTypeAdvanced;
|
import org.framework.lazy.cloud.network.heartbeat.common.advanced.payload.NettyChannelContext;
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.advanced.client.AbstractHandleDistributeClientPermeateServerCloseTypeAdvanced;
|
import org.framework.lazy.cloud.network.heartbeat.common.advanced.payload.NettyProxyMsg;
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.enums.MessageTypeEnums;
|
import org.framework.lazy.cloud.network.heartbeat.common.advanced.permeate.tcp.client.AbstractHandleTcpDistributeClientPermeateClientCloseTypeAdvanced;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.common.enums.TcpMessageTypeEnums;
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.socket.PermeateVisitorSocket;
|
import org.framework.lazy.cloud.network.heartbeat.common.socket.PermeateVisitorSocket;
|
||||||
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
|
import org.springframework.context.annotation.Role;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 客户端渗透客户端init close 信息
|
* 客户端渗透客户端init close 信息
|
||||||
*
|
*
|
||||||
* @see MessageTypeEnums#DISTRIBUTE_CLIENT_PERMEATE_CLIENT_CLOSE
|
* @see TcpMessageTypeEnums#TCP_DISTRIBUTE_CLIENT_PERMEATE_CLIENT_CLOSE
|
||||||
*/
|
*/
|
||||||
|
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class ClientHandleDistributeClientPermeateClientCloseTypeAdvanced extends AbstractHandleDistributeClientPermeateClientCloseTypeAdvanced<NettyProxyMsg> {
|
public class ClientHandleTcpDistributeClientPermeateClientCloseTypeAdvanced extends AbstractHandleTcpDistributeClientPermeateClientCloseTypeAdvanced<NettyProxyMsg> {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理当前数据
|
* 处理当前数据
|
||||||
*
|
*
|
||||||
* @param channel 当前通道
|
* @param nettyChannelContext 当前通道
|
||||||
* @param nettyProxyMsg 通道数据
|
* @param nettyProxyMsg 通道数据
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void doHandler(Channel channel, NettyProxyMsg nettyProxyMsg) {
|
public void doHandler(NettyChannelContext nettyChannelContext, NettyProxyMsg nettyProxyMsg) {
|
||||||
// 初始化 客户端渗透服务端socket
|
// 初始化 客户端渗透服务端socket
|
||||||
byte[] msgVisitorPort = nettyProxyMsg.getVisitorPort();
|
byte[] msgVisitorPort = nettyProxyMsg.getVisitorPort();
|
||||||
Integer visitorPort = Integer.parseInt(new String(msgVisitorPort));
|
Integer visitorPort = Integer.parseInt(new String(msgVisitorPort));
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
package org.framework.lazy.cloud.network.heartbeat.client.netty.permeate.tcp.advanced;
|
||||||
|
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.client.config.NettyClientProperties;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.client.netty.permeate.tcp.socket.NettyTcpClientPermeateClientVisitorSocket;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.common.advanced.HandleChannelTypeAdvanced;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.common.advanced.payload.NettyChannelContext;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.common.advanced.payload.NettyProxyMsg;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.common.advanced.permeate.tcp.client.AbstractHandleTcpDistributeClientPermeateClientInitTypeAdvanced;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.common.enums.TcpMessageTypeEnums;
|
||||||
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
|
import org.springframework.context.annotation.Role;
|
||||||
|
import org.wu.framework.spring.utils.SpringContextHolder;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 客户端渗透客户端init信息
|
||||||
|
*
|
||||||
|
* @see TcpMessageTypeEnums#TCP_DISTRIBUTE_CLIENT_PERMEATE_CLIENT_INIT
|
||||||
|
*/
|
||||||
|
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||||
|
@Slf4j
|
||||||
|
public class ClientHandleTcpDistributeClientPermeateClientInitTypeAdvanced
|
||||||
|
extends AbstractHandleTcpDistributeClientPermeateClientInitTypeAdvanced<NettyProxyMsg> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理当前数据
|
||||||
|
*
|
||||||
|
* @param nettyChannelContext 当前通道
|
||||||
|
* @param nettyProxyMsg 通道数据
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void doHandler(NettyChannelContext nettyChannelContext, NettyProxyMsg nettyProxyMsg) {
|
||||||
|
// 初始化 客户端渗透服务端socket
|
||||||
|
byte[] originClientIdBytes = nettyProxyMsg.getClientId();
|
||||||
|
byte[] visitorPortBytes = nettyProxyMsg.getVisitorPort();
|
||||||
|
byte[] clientTargetIpBytes = nettyProxyMsg.getTargetIp();
|
||||||
|
byte[] clientTargetPortBytes = nettyProxyMsg.getTargetPort();
|
||||||
|
byte[] targetClientIdBytes = nettyProxyMsg.getData();
|
||||||
|
|
||||||
|
String originClientId = new String(originClientIdBytes);
|
||||||
|
String targetClientId = new String(targetClientIdBytes);
|
||||||
|
Integer visitorPort = Integer.parseInt(new String(visitorPortBytes));
|
||||||
|
String clientTargetIp = new String(clientTargetIpBytes);
|
||||||
|
Integer clientTargetPort = Integer.parseInt(new String(clientTargetPortBytes));
|
||||||
|
|
||||||
|
List<HandleChannelTypeAdvanced> handleChannelTypeAdvancedList = new ArrayList<>(SpringContextHolder.getApplicationContext().getBeansOfType(HandleChannelTypeAdvanced.class).values());
|
||||||
|
// ChannelFlowAdapter channelFlowAdapter = SpringContextHolder.getBean(ChannelFlowAdapter.class);
|
||||||
|
NettyClientProperties nettyClientProperties = SpringContextHolder.getBean(NettyClientProperties.class);
|
||||||
|
log.info("client permeate client from client_id:【{}】 target_client_id【{}】with visitor_port【{}】, clientTargetIp:【{}】clientTargetPort:【{}】",
|
||||||
|
originClientId, targetClientId, visitorPort, clientTargetIp, clientTargetPort);
|
||||||
|
NettyTcpClientPermeateClientVisitorSocket nettyTcpClientPermeateClientVisitorSocket =
|
||||||
|
NettyTcpClientPermeateClientVisitorSocket.NettyClientPermeateClientVisitorSocketBuilder.builder()
|
||||||
|
.builderClientId(originClientId)
|
||||||
|
.builderClientTargetIp(clientTargetIp)
|
||||||
|
.builderClientTargetPort(clientTargetPort)
|
||||||
|
.builderVisitorPort(visitorPort)
|
||||||
|
.builderNettyClientProperties(nettyClientProperties)
|
||||||
|
//.builderChannelFlowAdapter(channelFlowAdapter)
|
||||||
|
.builderToClientId(targetClientId)
|
||||||
|
.builderHandleChannelTypeAdvancedList(handleChannelTypeAdvancedList)
|
||||||
|
|
||||||
|
.build();
|
||||||
|
try {
|
||||||
|
nettyTcpClientPermeateClientVisitorSocket.start();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package org.framework.lazy.cloud.network.heartbeat.client.netty.permeate.tcp.advanced;
|
||||||
|
|
||||||
|
|
||||||
|
import io.netty.channel.Channel;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.common.advanced.payload.NettyChannelContext;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.common.advanced.payload.NettyProxyMsg;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.common.advanced.permeate.tcp.client.AbstractHandleTcpDistributeClientPermeateClientTransferCloseTypeAdvanced;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.common.enums.TcpMessageTypeEnums;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.common.utils.ChannelAttributeKeyUtils;
|
||||||
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
|
import org.springframework.context.annotation.Role;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下发客户端渗透客户端通信通道关闭
|
||||||
|
*
|
||||||
|
* @see TcpMessageTypeEnums#TCP_DISTRIBUTE_CLIENT_PERMEATE_CLIENT_TRANSFER_CLOSE
|
||||||
|
*/
|
||||||
|
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||||
|
@Slf4j
|
||||||
|
public class ClientHandleTcpDistributeClientPermeateClientTransferCloseTypeAdvanced extends AbstractHandleTcpDistributeClientPermeateClientTransferCloseTypeAdvanced<NettyProxyMsg> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理当前数据
|
||||||
|
*
|
||||||
|
* @param nettyChannelContext 当前通道
|
||||||
|
* @param nettyProxyMsg 通道数据
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void doHandler(NettyChannelContext nettyChannelContext, NettyProxyMsg nettyProxyMsg) {
|
||||||
|
Channel channel = nettyChannelContext.channel();
|
||||||
|
// 关闭客户端真实通道、访客通道
|
||||||
|
Channel realChannel = ChannelAttributeKeyUtils.getNextChannel(channel);
|
||||||
|
realChannel.close();// 真实通道关闭
|
||||||
|
channel.close(); // 数据传输通道关闭
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,33 +1,35 @@
|
|||||||
package org.framework.lazy.cloud.network.heartbeat.client.netty.advanced;
|
package org.framework.lazy.cloud.network.heartbeat.client.netty.permeate.tcp.advanced;
|
||||||
|
|
||||||
|
|
||||||
import io.netty.channel.Channel;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.framework.lazy.cloud.network.heartbeat.client.netty.socket.NettyClientPermeateServerVisitorSocket;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.NettyProxyMsg;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.NettyVisitorPortContext;
|
import org.framework.lazy.cloud.network.heartbeat.common.NettyVisitorPortContext;
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.advanced.client.AbstractHandleDistributeClientPermeateServerCloseTypeAdvanced;
|
import org.framework.lazy.cloud.network.heartbeat.common.advanced.payload.NettyChannelContext;
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.enums.MessageTypeEnums;
|
import org.framework.lazy.cloud.network.heartbeat.common.advanced.payload.NettyProxyMsg;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.common.advanced.permeate.tcp.client.AbstractHandleTcpDistributeClientPermeateServerCloseTypeAdvanced;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.common.enums.TcpMessageTypeEnums;
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.socket.PermeateVisitorSocket;
|
import org.framework.lazy.cloud.network.heartbeat.common.socket.PermeateVisitorSocket;
|
||||||
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
|
import org.springframework.context.annotation.Role;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 客户端渗透服务端init close 信息
|
* 客户端渗透服务端init close 信息
|
||||||
*
|
*
|
||||||
* @see MessageTypeEnums#DISTRIBUTE_CLIENT_PERMEATE_SERVER_CLOSE
|
* @see TcpMessageTypeEnums#TCP_DISTRIBUTE_CLIENT_PERMEATE_SERVER_CLOSE
|
||||||
*/
|
*/
|
||||||
|
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class ClientHandleDistributeClientPermeateServerCloseTypeAdvanced extends AbstractHandleDistributeClientPermeateServerCloseTypeAdvanced<NettyProxyMsg> {
|
public class ClientHandleTcpDistributeClientPermeateServerCloseTypeAdvanced extends AbstractHandleTcpDistributeClientPermeateServerCloseTypeAdvanced<NettyProxyMsg> {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理当前数据
|
* 处理当前数据
|
||||||
*
|
*
|
||||||
* @param channel 当前通道
|
* @param nettyChannelContext 当前通道
|
||||||
* @param nettyProxyMsg 通道数据
|
* @param nettyProxyMsg 通道数据
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void doHandler(Channel channel, NettyProxyMsg nettyProxyMsg) {
|
public void doHandler(NettyChannelContext nettyChannelContext, NettyProxyMsg nettyProxyMsg) {
|
||||||
// 初始化 客户端渗透服务端socket
|
// 初始化 客户端渗透服务端socket
|
||||||
byte[] msgVisitorPort = nettyProxyMsg.getVisitorPort();
|
byte[] msgVisitorPort = nettyProxyMsg.getVisitorPort();
|
||||||
Integer visitorPort = Integer.parseInt(new String(msgVisitorPort));
|
Integer visitorPort = Integer.parseInt(new String(msgVisitorPort));
|
||||||
@@ -1,53 +1,53 @@
|
|||||||
package org.framework.lazy.cloud.network.heartbeat.client.netty.advanced;
|
package org.framework.lazy.cloud.network.heartbeat.client.netty.permeate.tcp.advanced;
|
||||||
|
|
||||||
|
|
||||||
import io.netty.channel.Channel;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.framework.lazy.cloud.network.heartbeat.client.config.NettyClientProperties;
|
import org.framework.lazy.cloud.network.heartbeat.client.config.NettyClientProperties;
|
||||||
import org.framework.lazy.cloud.network.heartbeat.client.netty.socket.NettyClientPermeateServerVisitorSocket;
|
import org.framework.lazy.cloud.network.heartbeat.client.netty.permeate.tcp.socket.NettyTcpClientPermeateServerVisitorSocket;
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.NettyProxyMsg;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.adapter.ChannelFlowAdapter;
|
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.advanced.HandleChannelTypeAdvanced;
|
import org.framework.lazy.cloud.network.heartbeat.common.advanced.HandleChannelTypeAdvanced;
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.advanced.client.AbstractHandleDistributeClientPermeateServerInitTypeAdvanced;
|
import org.framework.lazy.cloud.network.heartbeat.common.advanced.payload.NettyChannelContext;
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.enums.MessageTypeEnums;
|
import org.framework.lazy.cloud.network.heartbeat.common.advanced.payload.NettyProxyMsg;
|
||||||
import org.wu.framework.inner.lazy.orm.spring.SpringConnectionHandler;
|
import org.framework.lazy.cloud.network.heartbeat.common.advanced.permeate.tcp.client.AbstractHandleTcpDistributeClientPermeateServerInitTypeAdvanced;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.common.enums.TcpMessageTypeEnums;
|
||||||
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
|
import org.springframework.context.annotation.Role;
|
||||||
import org.wu.framework.spring.utils.SpringContextHolder;
|
import org.wu.framework.spring.utils.SpringContextHolder;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 客户端渗透服务端init信息
|
* 客户端渗透服务端init信息
|
||||||
*
|
*
|
||||||
* @see MessageTypeEnums#DISTRIBUTE_CLIENT_PERMEATE_SERVER_INIT
|
* @see TcpMessageTypeEnums#TCP_DISTRIBUTE_CLIENT_PERMEATE_SERVER_INIT
|
||||||
*/
|
*/
|
||||||
|
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class ClientHandleDistributeClientPermeateServerInitTypeAdvanced extends AbstractHandleDistributeClientPermeateServerInitTypeAdvanced<NettyProxyMsg> {
|
public class ClientHandleTcpDistributeClientPermeateServerInitTypeAdvanced extends AbstractHandleTcpDistributeClientPermeateServerInitTypeAdvanced<NettyProxyMsg> {
|
||||||
|
|
||||||
private final NettyClientProperties nettyClientProperties;
|
private final NettyClientProperties nettyClientProperties;
|
||||||
|
|
||||||
public ClientHandleDistributeClientPermeateServerInitTypeAdvanced(NettyClientProperties nettyClientProperties) {
|
public ClientHandleTcpDistributeClientPermeateServerInitTypeAdvanced(NettyClientProperties nettyClientProperties) {
|
||||||
this.nettyClientProperties = nettyClientProperties;
|
this.nettyClientProperties = nettyClientProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理当前数据
|
* 处理当前数据
|
||||||
*
|
*
|
||||||
* @param channel 当前通道
|
* @param nettyChannelContext 当前通道
|
||||||
* @param nettyProxyMsg 通道数据
|
* @param nettyProxyMsg 通道数据
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void doHandler(Channel channel, NettyProxyMsg nettyProxyMsg) {
|
public void doHandler(NettyChannelContext nettyChannelContext, NettyProxyMsg nettyProxyMsg) {
|
||||||
// 初始化 客户端渗透服务端socket
|
// 初始化 客户端渗透服务端socket
|
||||||
byte[] clientIdBytes = nettyProxyMsg.getClientId();
|
byte[] clientIdBytes = nettyProxyMsg.getClientId();
|
||||||
byte[] visitorPort = nettyProxyMsg.getVisitorPort();
|
byte[] visitorPort = nettyProxyMsg.getVisitorPort();
|
||||||
byte[] clientTargetIp = nettyProxyMsg.getClientTargetIp();
|
byte[] clientTargetIp = nettyProxyMsg.getTargetIp();
|
||||||
byte[] clientTargetPort = nettyProxyMsg.getClientTargetPort();
|
byte[] clientTargetPort = nettyProxyMsg.getTargetPort();
|
||||||
|
|
||||||
List<HandleChannelTypeAdvanced> handleChannelTypeAdvancedList = new ArrayList<>(SpringContextHolder.getApplicationContext().getBeansOfType(HandleChannelTypeAdvanced.class).values());
|
List<HandleChannelTypeAdvanced> handleChannelTypeAdvancedList = new ArrayList<>(SpringContextHolder.getApplicationContext().getBeansOfType(HandleChannelTypeAdvanced.class).values());
|
||||||
NettyClientPermeateServerVisitorSocket nettyClientPermeateServerVisitorSocket = NettyClientPermeateServerVisitorSocket.NettyVisitorSocketBuilder.builder()
|
NettyTcpClientPermeateServerVisitorSocket nettyTcpClientPermeateServerVisitorSocket = NettyTcpClientPermeateServerVisitorSocket.NettyVisitorSocketBuilder.builder()
|
||||||
.builderClientId(new String(clientIdBytes))
|
.builderClientId(new String(clientIdBytes))
|
||||||
.builderClientTargetIp(new String(clientTargetIp))
|
.builderClientTargetIp(new String(clientTargetIp))
|
||||||
.builderClientTargetPort(Integer.parseInt(new String(clientTargetPort)))
|
.builderClientTargetPort(Integer.parseInt(new String(clientTargetPort)))
|
||||||
@@ -56,8 +56,9 @@ public class ClientHandleDistributeClientPermeateServerInitTypeAdvanced extends
|
|||||||
.builderHandleChannelTypeAdvancedList(handleChannelTypeAdvancedList)
|
.builderHandleChannelTypeAdvancedList(handleChannelTypeAdvancedList)
|
||||||
.build();
|
.build();
|
||||||
try {
|
try {
|
||||||
nettyClientPermeateServerVisitorSocket.start();
|
nettyTcpClientPermeateServerVisitorSocket.start();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
log.error(e.getMessage(), e);
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package org.framework.lazy.cloud.network.heartbeat.client.netty.permeate.tcp.advanced;
|
||||||
|
|
||||||
|
|
||||||
|
import io.netty.channel.Channel;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.common.advanced.payload.NettyChannelContext;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.common.advanced.payload.NettyProxyMsg;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.common.advanced.permeate.tcp.client.AbstractHandleTcpDistributeClientPermeateServerTransferCloseTypeAdvanced;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.common.enums.TcpMessageTypeEnums;
|
||||||
|
import org.framework.lazy.cloud.network.heartbeat.common.utils.ChannelAttributeKeyUtils;
|
||||||
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
|
import org.springframework.context.annotation.Role;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下发 客户端渗透服务端通信通道关闭
|
||||||
|
*
|
||||||
|
* @see TcpMessageTypeEnums#TCP_DISTRIBUTE_CLIENT_PERMEATE_SERVER_TRANSFER_CLOSE
|
||||||
|
*/
|
||||||
|
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||||
|
@Slf4j
|
||||||
|
public class ClientHandleTcpDistributeClientPermeateServerTransferCloseTypeAdvanced extends AbstractHandleTcpDistributeClientPermeateServerTransferCloseTypeAdvanced<NettyProxyMsg> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理当前数据
|
||||||
|
*
|
||||||
|
* @param nettyChannelContext 当前通道
|
||||||
|
* @param nettyProxyMsg 通道数据
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void doHandler(NettyChannelContext nettyChannelContext, NettyProxyMsg nettyProxyMsg) {
|
||||||
|
Channel channel = nettyChannelContext.channel();
|
||||||
|
// 关闭本地通信通道
|
||||||
|
Channel nextChannel = ChannelAttributeKeyUtils.getNextChannel(channel);
|
||||||
|
channel.close();
|
||||||
|
nextChannel.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,37 +1,41 @@
|
|||||||
package org.framework.lazy.cloud.network.heartbeat.client.netty.advanced;
|
package org.framework.lazy.cloud.network.heartbeat.client.netty.permeate.tcp.advanced;
|
||||||
|
|
||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.channel.Channel;
|
import io.netty.channel.Channel;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.framework.lazy.cloud.network.heartbeat.client.config.NettyClientProperties;
|
import org.framework.lazy.cloud.network.heartbeat.common.advanced.payload.NettyChannelContext;
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.NettyProxyMsg;
|
import org.framework.lazy.cloud.network.heartbeat.common.advanced.payload.NettyProxyMsg;
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.advanced.client.AbstractHandleDistributeClientPermeateServerTransferTypeAdvanced;
|
import org.framework.lazy.cloud.network.heartbeat.common.advanced.permeate.tcp.client.AbstractHandleTcpDistributeClientPermeateServerTransferTypeAdvanced;
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.enums.MessageTypeEnums;
|
import org.framework.lazy.cloud.network.heartbeat.common.enums.TcpMessageTypeEnums;
|
||||||
import org.framework.lazy.cloud.network.heartbeat.common.utils.ChannelAttributeKeyUtils;
|
import org.framework.lazy.cloud.network.heartbeat.common.utils.ChannelAttributeKeyUtils;
|
||||||
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
|
import org.springframework.context.annotation.Role;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 服务端处理客户端数据传输
|
* 服务端处理客户端数据传输
|
||||||
*
|
*
|
||||||
* @see MessageTypeEnums#DISTRIBUTE_CLIENT_TRANSFER
|
* @see TcpMessageTypeEnums#TCP_DISTRIBUTE_CLIENT_TRANSFER
|
||||||
*/
|
*/
|
||||||
|
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class ClientHandleDistributeClientPermeateServerTransferTypeAdvanced extends AbstractHandleDistributeClientPermeateServerTransferTypeAdvanced<NettyProxyMsg> {
|
public class ClientHandleTcpDistributeClientPermeateServerTransferTypeAdvanced extends AbstractHandleTcpDistributeClientPermeateServerTransferTypeAdvanced<NettyProxyMsg> {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理当前数据
|
* 处理当前数据
|
||||||
*
|
*
|
||||||
* @param channel 当前通道
|
* @param nettyChannelContext 当前通道
|
||||||
* @param nettyProxyMsg 通道数据
|
* @param nettyProxyMsg 通道数据
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void doHandler(Channel channel, NettyProxyMsg nettyProxyMsg) {
|
public void doHandler(NettyChannelContext nettyChannelContext, NettyProxyMsg nettyProxyMsg) {
|
||||||
|
Channel channel = nettyChannelContext.channel();
|
||||||
log.debug("客户端渗透服务端返回数据:{}" , new String(nettyProxyMsg.getData()));
|
log.debug("客户端渗透服务端返回数据:{}" , new String(nettyProxyMsg.getData()));
|
||||||
byte[] visitorPort = nettyProxyMsg.getVisitorPort();
|
byte[] visitorPort = nettyProxyMsg.getVisitorPort();
|
||||||
byte[] clientTargetIp = nettyProxyMsg.getClientTargetIp();
|
byte[] clientTargetIp = nettyProxyMsg.getTargetIp();
|
||||||
byte[] clientTargetPort = nettyProxyMsg.getClientTargetPort();
|
byte[] clientTargetPort = nettyProxyMsg.getTargetPort();
|
||||||
byte[] visitorId = nettyProxyMsg.getVisitorId();
|
byte[] visitorId = nettyProxyMsg.getVisitorId();
|
||||||
// 真实服务通道
|
// 真实服务通道
|
||||||
// Channel realChannel = NettyRealIdContext.getReal(new String(visitorId));
|
// Channel realChannel = NettyRealIdContext.getReal(new String(visitorId));
|
||||||