[fix] 修改bean 创建,添加网络榴莲监控

This commit is contained in:
wujiawei 2024-01-24 14:25:44 +08:00
parent 20f3f9307c
commit 1ee7021aa1
32 changed files with 799 additions and 109 deletions

View File

@ -2,11 +2,11 @@
#### 模块说明
| 模块 | 所属层级 | 描述 | 端口 |
|----------------------------------------------------------------------------------------|------|------------------------|----------------------------------------------------------------|
| [middleground-cloud-heartbeat-common](middleground-cloud-heartbeat-common) | 基础模块 | 基于Netty数据解码、编码、通道处理器声明 | 无 |
| [middleground-on-cloud-heartbeat-server](middleground-on-cloud-heartbeat-server) | 启动模块 | 内网穿透服务端 | http端口6001、tcp端口:7001 (默认tcp端口=http端口+1000 如6001+1000=7001) |
| [middleground-under-cloud-heartbeat-client](middleground-under-cloud-heartbeat-client) | 启动模块 | 内网穿透客户端 | 6004 |
| 模块 | 所属层级 | 描述 | 端口 |
|------------------------------------------------------------------|------|------------------------|----------------------------------------------------------------|
| [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-client](wu-lazy-cloud-heartbeat-client) | 启动模块 | 内网穿透客户端 | 6004 |
#### 功能
@ -52,13 +52,13 @@ spring:
如果云端需要部署云上暂存+内网穿透功能:需要部署 内网穿透服务端、暂存服务、内网穿透客户端、云上离线网关
```
| 模块 | 说明 | 部署内网穿透必须 | 部署内网穿透+云上暂存必须 |
|----------------------------------------------------------------------------------------|------------|----------|---------------|
| [middleground-on-cloud-heartbeat-server](middleground-on-cloud-heartbeat-server) | 内网穿透+心跳服务端 | ☑️ | ☑️ |
| [middleground-under-cloud-heartbeat-client](middleground-under-cloud-heartbeat-client) | 内网穿透+心跳客户端 | ✖️ | ☑️ |
| [middleground-cloud-staging-provider](middleground-cloud-staging-provider) | 暂存服务 | ✖️ | ☑️ |
| [middleground-on-cloud-central-gateway](middleground-on-cloud-central-gateway) | 云上暂存网关 | ✖️ | ☑️ |
| [middleground-under-cloud-central-gateway](middleground-under-cloud-central-gateway) | 云下暂存网关 | ✖️ | ✖️ |
| 模块 | 说明 | 部署内网穿透必须 | 部署内网穿透+云上暂存必须 |
|------------------------------------------------------------------|------------|----------|---------------|
| [wu-lazy-cloud-heartbeat-server](wu-lazy-cloud-heartbeat-server) | 内网穿透+心跳服务端 | ☑️ | ☑️ |
| [wu-lazy-cloud-heartbeat-client](wu-lazy-cloud-heartbeat-client) | 内网穿透+心跳客户端 | ✖️ | ☑️ |
| [wu-lazy-cloud-staging-provider](wu-lazy-cloud-staging-provider) | 暂存服务 | ✖️ | ☑️ |
| [wu-lazy-cloud-central-gateway](wu-lazy-cloud-central-gateway) | 云上暂存网关 | ✖️ | ☑️ |
| [wu-lazy-cloud-central-gateway](wu-lazy-cloud-central-gateway) | 云下暂存网关 | ✖️ | ✖️ |
##### 云网关部署
@ -66,13 +66,13 @@ spring:
云网关部署内网穿透客户端
```
| 模块 | 说明 | 部署内网穿透必须 | 部署内网穿透+云上暂存必须 |
|----------------------------------------------------------------------------------------|------------|----------|---------------|
| [middleground-on-cloud-heartbeat-server](middleground-on-cloud-heartbeat-server) | 内网穿透+心跳服务端 | ✖️ | ✖️ |
| [middleground-under-cloud-heartbeat-client](middleground-under-cloud-heartbeat-client) | 内网穿透+心跳客户端 | ✖️ | ☑️ |
| [middleground-cloud-staging-provider](middleground-cloud-staging-provider) | 暂存服务 | ✖️ | ✖️ |
| [middleground-on-cloud-central-gateway](middleground-on-cloud-central-gateway) | 云上暂存网关 | ✖️ | ☑️ |
| [middleground-under-cloud-central-gateway](middleground-under-cloud-central-gateway) | 云下暂存网关 | ✖️ | ✖️ |
| 模块 | 说明 | 部署内网穿透必须 | 部署内网穿透+云上暂存必须 |
|------------------------------------------------------------------|------------|----------|---------------|
| [wu-lazy-cloud-heartbeat-server](wu-lazy-cloud-heartbeat-server) | 内网穿透+心跳服务端 | ✖️ | ✖️ |
| [wu-lazy-cloud-heartbeat-client](wu-lazy-cloud-heartbeat-client) | 内网穿透+心跳客户端 | ✖️ | ☑️ |
| [wu-lazy-cloud-staging-provider](wu-lazy-cloud-staging-provider) | 暂存服务 | ✖️ | ✖️ |
| [wu-lazy-cloud-central-gateway](wu-lazy-cloud-central-gateway) | 云上暂存网关 | ✖️ | ☑️ |
| [wu-lazy-cloud-central-gateway](wu-lazy-cloud-central-gateway) | 云下暂存网关 | ✖️ | ✖️ |
##### 独立租户部署
@ -81,12 +81,12 @@ spring:
内网穿透+离线暂存能力: 需要部署内网穿透客户端、离线网关、离线暂存服务
```
| 模块 | 说明 | 部署内网穿透必须 | 部署内网穿透+云上暂存必须 |
|----------------------------------------------------------------------------------------|------------|----------|---------------|
| [middleground-on-cloud-heartbeat-server](middleground-on-cloud-heartbeat-server) | 内网穿透+心跳服务端 | ✖️ | ✖️ |
| [middleground-under-cloud-heartbeat-client](middleground-under-cloud-heartbeat-client) | 内网穿透+心跳客户端 | ☑️ | ☑️ |
| [middleground-cloud-staging-provider](middleground-cloud-staging-provider) | 暂存服务 | ✖️ | ☑️ |
| [middleground-on-cloud-central-gateway](middleground-on-cloud-central-gateway) | 云上暂存网关 | ✖️ | ✖️ |
| [middleground-under-cloud-central-gateway](middleground-under-cloud-central-gateway) | 云下暂存网关 | ✖️ | ☑️ |
| 模块 | 说明 | 部署内网穿透必须 | 部署内网穿透+云上暂存必须 |
|------------------------------------------------------------------|------------|----------|---------------|
| [wu-lazy-cloud-heartbeat-server](wu-lazy-cloud-heartbeat-server) | 内网穿透+心跳服务端 | ✖️ | ✖️ |
| [wu-lazy-cloud-heartbeat-client](wu-lazy-cloud-heartbeat-client) | 内网穿透+心跳客户端 | ☑️ | ☑️ |
| [wu-lazy-cloud-staging-provider](wu-lazy-cloud-staging-provider) | 暂存服务 | ✖️ | ☑️ |
| [wu-lazy-cloud-central-gateway](wu-lazy-cloud-central-gateway) | 云上暂存网关 | ✖️ | ✖️ |
| [wu-lazy-cloud-central-gateway](wu-lazy-cloud-central-gateway) | 云下暂存网关 | ✖️ | ☑️ |

View File

@ -6,8 +6,8 @@ metadata:
k8s.kuboard.cn/displayName: 【云上云下】云上心跳服务端(新)
labels:
k8s.kuboard.cn/layer: monitor
k8s.kuboard.cn/name: middleground-on-cloud-heartbeat-server
name: middleground-on-cloud-heartbeat-server
k8s.kuboard.cn/name: wu-lazy-cloud-heartbeat-server
name: wu-lazy-cloud-heartbeat-server
namespace: middleground-management
spec:
progressDeadlineSeconds: 600
@ -16,7 +16,7 @@ spec:
selector:
matchLabels:
k8s.kuboard.cn/layer: monitor
k8s.kuboard.cn/name: middleground-on-cloud-heartbeat-server
k8s.kuboard.cn/name: wu-lazy-cloud-heartbeat-server
strategy:
rollingUpdate:
maxSurge: 25%
@ -26,16 +26,16 @@ spec:
metadata:
labels:
k8s.kuboard.cn/layer: monitor
k8s.kuboard.cn/name: middleground-on-cloud-heartbeat-server
k8s.kuboard.cn/name: wu-lazy-cloud-heartbeat-server
spec:
containers:
- envFrom:
- configMapRef:
name: common-cnf
image: >-
docker-registry.laihui.com/middleground/middleground-on-cloud-heartbeat-server:master_latest
docker-registry.laihui.com/middleground/wu-lazy-cloud-heartbeat-server:master_latest
imagePullPolicy: Always
name: middleground-on-cloud-heartbeat-server
name: wu-lazy-cloud-heartbeat-server
resources:
limits:
memory: 512Mi
@ -57,8 +57,8 @@ metadata:
k8s.kuboard.cn/displayName: 【云上云下】云上中心网关(新)
labels:
k8s.kuboard.cn/layer: gateway
k8s.kuboard.cn/name: middleground-on-cloud-central-gateway
name: middleground-on-cloud-central-gateway
k8s.kuboard.cn/name: wu-lazy-cloud-central-gateway
name: wu-lazy-cloud-central-gateway
namespace: middleground-management
spec:
progressDeadlineSeconds: 600
@ -67,7 +67,7 @@ spec:
selector:
matchLabels:
k8s.kuboard.cn/layer: gateway
k8s.kuboard.cn/name: middleground-on-cloud-central-gateway
k8s.kuboard.cn/name: wu-lazy-cloud-central-gateway
strategy:
rollingUpdate:
maxSurge: 25%
@ -77,16 +77,16 @@ spec:
metadata:
labels:
k8s.kuboard.cn/layer: gateway
k8s.kuboard.cn/name: middleground-on-cloud-central-gateway
k8s.kuboard.cn/name: wu-lazy-cloud-central-gateway
spec:
containers:
- envFrom:
- configMapRef:
name: common-cnf
image: >-
docker-registry.laihui.com/middleground/middleground-on-cloud-central-gateway:master_latest
docker-registry.laihui.com/middleground/wu-lazy-cloud-central-gateway:master_latest
imagePullPolicy: Always
name: middleground-on-cloud-central-gateway
name: wu-lazy-cloud-central-gateway
resources:
limits:
memory: 384Mi
@ -108,8 +108,8 @@ metadata:
k8s.kuboard.cn/displayName: 【云上云下】暂存服务(新)
labels:
k8s.kuboard.cn/layer: svc
k8s.kuboard.cn/name: middleground-cloud-staging-provider
name: middleground-cloud-staging-provider
k8s.kuboard.cn/name: wu-lazy-cloud-staging-provider
name: wu-lazy-cloud-staging-provider
namespace: middleground-management
spec:
progressDeadlineSeconds: 600
@ -118,7 +118,7 @@ spec:
selector:
matchLabels:
k8s.kuboard.cn/layer: svc
k8s.kuboard.cn/name: middleground-cloud-staging-provider
k8s.kuboard.cn/name: wu-lazy-cloud-staging-provider
strategy:
rollingUpdate:
maxSurge: 25%
@ -128,16 +128,16 @@ spec:
metadata:
labels:
k8s.kuboard.cn/layer: svc
k8s.kuboard.cn/name: middleground-cloud-staging-provider
k8s.kuboard.cn/name: wu-lazy-cloud-staging-provider
spec:
containers:
- envFrom:
- configMapRef:
name: common-cnf
image: >-
docker-registry.laihui.com/middleground/middleground-cloud-staging-provider:master_latest
docker-registry.laihui.com/middleground/wu-lazy-cloud-staging-provider:master_latest
imagePullPolicy: Always
name: middleground-cloud-staging-provider
name: wu-lazy-cloud-staging-provider
resources:
limits:
memory: 384Mi

View File

@ -7,8 +7,8 @@ metadata:
k8s.kuboard.cn/displayName: 【云上云下】云下心跳客户端(新)
labels:
k8s.kuboard.cn/layer: monitor
k8s.kuboard.cn/name: middleground-under-cloud-heartbeat-client
name: middleground-under-cloud-heartbeat-client
k8s.kuboard.cn/name: wu-lazy-cloud-heartbeat-client
name: wu-lazy-cloud-heartbeat-client
namespace: middleground-tenant-share
spec:
progressDeadlineSeconds: 600
@ -17,7 +17,7 @@ spec:
selector:
matchLabels:
k8s.kuboard.cn/layer: monitor
k8s.kuboard.cn/name: middleground-under-cloud-heartbeat-client
k8s.kuboard.cn/name: wu-lazy-cloud-heartbeat-client
strategy:
rollingUpdate:
maxSurge: 25%
@ -27,16 +27,16 @@ spec:
metadata:
labels:
k8s.kuboard.cn/layer: monitor
k8s.kuboard.cn/name: middleground-under-cloud-heartbeat-client
k8s.kuboard.cn/name: wu-lazy-cloud-heartbeat-client
spec:
containers:
- envFrom:
- configMapRef:
name: common-cnf
image: >-
docker-registry.laihui.com/middleground/middleground-under-cloud-heartbeat-client:master_latest
docker-registry.laihui.com/middleground/wu-lazy-cloud-heartbeat-client:master_latest
imagePullPolicy: Always
name: middleground-under-cloud-heartbeat-client
name: wu-lazy-cloud-heartbeat-client
resources:
limits:
memory: 384Mi
@ -58,8 +58,8 @@ metadata:
k8s.kuboard.cn/displayName: 【云上云下】云下中心网关(新)
labels:
k8s.kuboard.cn/layer: gateway
k8s.kuboard.cn/name: middleground-under-cloud-central-gateway
name: middleground-under-cloud-central-gateway
k8s.kuboard.cn/name: wu-lazy-cloud-central-gateway
name: wu-lazy-cloud-central-gateway
namespace: middleground-tenant-share
spec:
progressDeadlineSeconds: 600
@ -68,7 +68,7 @@ spec:
selector:
matchLabels:
k8s.kuboard.cn/layer: gateway
k8s.kuboard.cn/name: middleground-under-cloud-central-gateway
k8s.kuboard.cn/name: wu-lazy-cloud-central-gateway
strategy:
rollingUpdate:
maxSurge: 25%
@ -78,16 +78,16 @@ spec:
metadata:
labels:
k8s.kuboard.cn/layer: gateway
k8s.kuboard.cn/name: middleground-under-cloud-central-gateway
k8s.kuboard.cn/name: wu-lazy-cloud-central-gateway
spec:
containers:
- envFrom:
- configMapRef:
name: common-cnf
image: >-
docker-registry.laihui.com/middleground/middleground-under-cloud-central-gateway:master_latest
docker-registry.laihui.com/middleground/wu-lazy-cloud-central-gateway:master_latest
imagePullPolicy: Always
name: middleground-under-cloud-central-gateway
name: wu-lazy-cloud-central-gateway
resources:
limits:
memory: 384Mi
@ -109,8 +109,8 @@ metadata:
k8s.kuboard.cn/displayName: 【云上云下】云下暂存服务(新)
labels:
k8s.kuboard.cn/layer: svc
k8s.kuboard.cn/name: middleground-cloud-staging-provider
name: middleground-cloud-staging-provider
k8s.kuboard.cn/name: wu-lazy-cloud-staging-provider
name: wu-lazy-cloud-staging-provider
namespace: middleground-tenant-share
spec:
progressDeadlineSeconds: 600
@ -119,7 +119,7 @@ spec:
selector:
matchLabels:
k8s.kuboard.cn/layer: svc
k8s.kuboard.cn/name: middleground-cloud-staging-provider
k8s.kuboard.cn/name: wu-lazy-cloud-staging-provider
strategy:
rollingUpdate:
maxSurge: 25%
@ -129,16 +129,16 @@ spec:
metadata:
labels:
k8s.kuboard.cn/layer: svc
k8s.kuboard.cn/name: middleground-cloud-staging-provider
k8s.kuboard.cn/name: wu-lazy-cloud-staging-provider
spec:
containers:
- envFrom:
- configMapRef:
name: common-cnf
image: >-
docker-registry.laihui.com/middleground/middleground-cloud-staging-provider:master_latest
docker-registry.laihui.com/middleground/wu-lazy-cloud-staging-provider:master_latest
imagePullPolicy: Always
name: middleground-cloud-staging-provider
name: wu-lazy-cloud-staging-provider
resources:
limits:
memory: 384Mi

View File

@ -1,15 +1,14 @@
package wu.framework.lazy.cloud.heartbeat.client.netty.filter;
import wu.framework.lazy.cloud.heartbeat.client.netty.handler.NettyClientVisitorRealHandler;
import wu.framework.lazy.cloud.heartbeat.common.adapter.ChannelTypeAdapter;
import wu.framework.lazy.cloud.heartbeat.common.decoder.NettyProxyMsgDecoder;
import wu.framework.lazy.cloud.heartbeat.common.encoder.NettMsgEncoder;
import wu.framework.lazy.cloud.heartbeat.common.encoder.NettyProxyMsgEncoder;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import wu.framework.lazy.cloud.heartbeat.client.netty.handler.NettyClientVisitorRealHandler;
import wu.framework.lazy.cloud.heartbeat.common.adapter.ChannelTypeAdapter;
import wu.framework.lazy.cloud.heartbeat.common.decoder.NettyProxyMsgDecoder;
import wu.framework.lazy.cloud.heartbeat.common.encoder.NettyProxyMsgEncoder;
/**
* netty 客户端连接真实服服务端访客拦截器
@ -34,8 +33,8 @@ public class NettyClientVisitorRealFilter extends ChannelInitializer<SocketChann
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
// // 解码编码
pipeline.addLast(new NettyProxyMsgDecoder(Integer.MAX_VALUE, 0, 4, -4, 0));
pipeline.addLast(new NettMsgEncoder());
// pipeline.addLast(new NettyProxyMsgDecoder(Integer.MAX_VALUE, 0, 4, -4, 0));
// pipeline.addLast(new NettMsgEncoder());
pipeline.addLast(new NettyProxyMsgDecoder(Integer.MAX_VALUE, 0, 4, -4, 0));
pipeline.addLast(new NettyProxyMsgEncoder());
pipeline.addLast(new NettyClientVisitorRealHandler(channelTypeAdapter));

View File

@ -46,8 +46,11 @@ public class NettyClientRealSocket {
NettyServerProperties nettyServerProperties,
List<HandleChannelTypeAdvanced> handleChannelTypeAdvancedList) {
try {
String clientId = internalNetworkPenetrationRealClient.getClientId();
String clientTargetIp = internalNetworkPenetrationRealClient.getClientTargetIp();
Integer clientTargetPort = internalNetworkPenetrationRealClient.getClientTargetPort();
Integer visitorPort = internalNetworkPenetrationRealClient.getVisitorPort();
String visitorId = internalNetworkPenetrationRealClient.getVisitorId();
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(eventLoopGroup).channel(NioSocketChannel.class)
.handler(new NettyClientRealFilter());
@ -56,12 +59,8 @@ public class NettyClientRealSocket {
// 客户端链接真实服务成功 设置自动读写false 等待访客连接成功后设置成true
Channel realChannel = future.channel();
realChannel.config().setOption(ChannelOption.AUTO_READ, false);
String clientId = internalNetworkPenetrationRealClient.getClientId();// 客户端ID
String clientTargetIp1 = internalNetworkPenetrationRealClient.getClientTargetIp();
Integer clientTargetPort1 = internalNetworkPenetrationRealClient.getClientTargetPort();
Integer visitorPort = internalNetworkPenetrationRealClient.getVisitorPort();
String visitorId = internalNetworkPenetrationRealClient.getVisitorId();
log.info("访客通过 客户端:【{}】,绑定本地服务,IP:{},端口:{} 新建通道成功", clientId, clientTargetIp1, clientTargetPort1);
log.info("访客通过 客户端:【{}】,绑定本地服务,IP:{},端口:{} 新建通道成功", clientId, clientTargetIp, clientTargetPort);
// 客户端真实通道
NettyRealIdContext.pushReal(realChannel, visitorId);
// 绑定访客ID到当前真实通道属性
@ -99,6 +98,8 @@ public class NettyClientRealSocket {
// future.channel().attr(Constant.VID).set(internalNetworkPenetrationRealClient);
// Constant.vrc.put(internalNetworkPenetrationRealClient, future.channel());
// ProxySocket.connectProxyServer(internalNetworkPenetrationRealClient);
}else {
log.error("客户:【{}】,无法连接当前网络内的目标IP【{}】,目标端口:【{}】",clientId,clientTargetIp,clientTargetPort);
}
});
} catch (Exception e) {

View File

@ -1,5 +1,6 @@
package wu.framework.lazy.cloud.heartbeat.common;
import lombok.Builder;
import lombok.Data;
import lombok.experimental.Accessors;
@ -9,6 +10,7 @@ import lombok.experimental.Accessors;
* @author Jia wei Wu
* @date 2023/12/29 05:21 下午
**/
@Builder
@Data
@Accessors(chain = true)
public class InternalNetworkPenetrationRealClient {

View File

@ -7,7 +7,8 @@ import wu.framework.lazy.cloud.heartbeat.common.enums.MessageTypeEnums;
/**
* @see MessageTypeEnums
* -128~ 127
* 数据取值范围 -128~ 127
* 当前约束范围 -100100
*/
public class MessageType {
/**
@ -79,7 +80,7 @@ public class MessageType {
*/
public static final byte REPORT_SINGLE_CLIENT_MESSAGE = 0X09;
/**
* 服务端通道 is active
* 服务端通道 is active
*
* @see MessageTypeEnums#SERVER_CHANNEL_ACTIVE
* @see AbstractHandleServerChannelActiveTypeAdvanced

View File

@ -1,6 +1,8 @@
package wu.framework.lazy.cloud.heartbeat.common;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import java.nio.charset.StandardCharsets;
@ -8,6 +10,7 @@ import java.nio.charset.StandardCharsets;
/**
* netty 代理请求数据
*/
@NoArgsConstructor
@Setter
@Getter
public class NettyProxyMsg {

View File

@ -0,0 +1,41 @@
package wu.framework.lazy.cloud.heartbeat.common.adapter;
import io.netty.channel.Channel;
import lombok.extern.slf4j.Slf4j;
import wu.framework.lazy.cloud.heartbeat.common.advanced.flow.ChannelFlow;
import wu.framework.lazy.cloud.heartbeat.common.advanced.flow.HandleChannelFlowAdvanced;
import java.util.List;
/**
* 通道流量适配器
*
* @see HandleChannelFlowAdvanced
*/
@Slf4j
public class ChannelFlowAdapter {
protected final List<HandleChannelFlowAdvanced> handleChannelFlowAdvancedList;
public ChannelFlowAdapter(List<HandleChannelFlowAdvanced> handleChannelFlowAdvancedList) {
this.handleChannelFlowAdvancedList = handleChannelFlowAdvancedList;
}
/**
* 处理当前数据
*
* @param channelFlow 通道数据
*/
public void handler(Channel channel, ChannelFlow channelFlow) {
for (HandleChannelFlowAdvanced handleChannelTypeAdvanced : handleChannelFlowAdvancedList) {
if (handleChannelTypeAdvanced.support(channelFlow)) {
try {
handleChannelTypeAdvanced.handler(channel, channelFlow);
} catch (Exception e) {
log.error("流量统计失败:{}", e.getMessage());
}
return;
}
}
}
}

View File

@ -27,7 +27,12 @@ public abstract class AbstractHandleChannelTypeAdvanced<MSG> implements HandleCh
public void handler(Channel channel, Object msg) {
doHandler(channel, (MSG) msg);
}
/**
* 是否支持当前类型
*
* @param msg 通道数据
* @return 布尔类型
*/
protected abstract boolean doSupport(MSG msg);
/**

View File

@ -0,0 +1,47 @@
package wu.framework.lazy.cloud.heartbeat.common.advanced.flow;
import io.netty.channel.Channel;
/**
* 处理通道流量适配者 抽象类
*
* @see HandleChannelFlowAdvanced
*/
public abstract class AbstractHandleChannelFlowAdvanced implements HandleChannelFlowAdvanced {
/**
* 是否支持当前这种类型
*
* @param channelFlow 数据
* @return boolean
*/
@Override
public boolean support(ChannelFlow channelFlow) {
return doSupport(channelFlow);
}
/**
* 处理是否支持这种类型
* @param channelFlow 数据
* @return boolean
*/
abstract boolean doSupport(ChannelFlow channelFlow);
/**
* 处理当前数据
*
* @param channel 当前通道
* @param channelFlow 通道数据
*/
@Override
public void handler(Channel channel, ChannelFlow channelFlow) {
doHandler(channel, channelFlow);
}
/**
* 处理当前数据
*
* @param channel 当前通道
* @param channelFlow 通道数据
*/
abstract void doHandler(Channel channel, ChannelFlow channelFlow);
}

View File

@ -0,0 +1,36 @@
package wu.framework.lazy.cloud.heartbeat.common.advanced.flow;
import wu.framework.lazy.cloud.heartbeat.common.enums.ChannelFlowEnum;
public interface ChannelFlow {
/**
* 通道客户端ID
*
* @return 通道客户端ID
*/
String clientId();
/**
* 通道使用的端口服务端访客端口客户端真实端口
*
* @return 端口
*/
Integer port();
/**
* 通道流量类型
*
* @return ChannelFlowEnum
* @see ChannelFlowEnum
*/
ChannelFlowEnum channelFlowEnum();
/**
* 流量
* @return 流量
*/
Integer flow();
}

View File

@ -0,0 +1,25 @@
package wu.framework.lazy.cloud.heartbeat.common.advanced.flow;
import io.netty.channel.Channel;
/**
* 处理通道流量适配者
*/
public interface HandleChannelFlowAdvanced {
/**
* 是否支持当前这种类型
*
* @param channelFlow 数据
* @return boolean
*/
boolean support(ChannelFlow channelFlow);
/**
* 处理当前数据
*
* @param channel 当前通道
* @param channelFlow 通道数据
*/
void handler(Channel channel, ChannelFlow channelFlow);
}

View File

@ -9,6 +9,7 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
* @see NettyMsg
* NettyMsg 对象解码
*/
@Deprecated
public class NettyMsgDecoder extends LengthFieldBasedFrameDecoder {
public NettyMsgDecoder(int maxFrameLength, int lengthFieldOffset, int lengthFieldLength, int lengthAdjustment,

View File

@ -10,6 +10,7 @@ import io.netty.handler.codec.MessageToByteEncoder;
* @see NettyProxyMsg
* NettyProxyMsg 对象编码
*/
@Deprecated
public class NettMsgEncoder extends MessageToByteEncoder<NettyMsg> {
public NettMsgEncoder() {

View File

@ -0,0 +1,17 @@
package wu.framework.lazy.cloud.heartbeat.common.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 通道流量类型
*/
@Getter
@AllArgsConstructor
public enum ChannelFlowEnum {
// 出口流量
OUT_FLOW,
// 进口流量
IN_FLOW
}

View File

@ -10,6 +10,8 @@ public class ChannelAttributeKeyUtils {
private static final AttributeKey<String> VISITOR_ID = AttributeKey.newInstance("visitorId");
private static final AttributeKey<String> CLIENT_ID = AttributeKey.newInstance("clientId");
private static final AttributeKey<Integer> OUT_FLOW = AttributeKey.newInstance("outFlow");
private static final AttributeKey<Integer> IN_FLOW = AttributeKey.newInstance("inFlow");
/**
@ -34,7 +36,8 @@ public class ChannelAttributeKeyUtils {
/**
* 获取 通道中访客ID
* @param channel 通道
*
* @param channel 通道
*/
public static String getVisitorId(Channel channel) {
return channel.attr(VISITOR_ID).get();
@ -44,16 +47,17 @@ public class ChannelAttributeKeyUtils {
/**
* 为通道绑定 访客属性
*
* @param channel 通道
* @param channel 通道
* @param clientId 客户端ID
*/
public static void buildClientId(Channel channel, byte[] clientId) {
channel.attr(CLIENT_ID).set(new String(clientId));
}
/**
* 为通道绑定 访客属性
*
* @param channel 通道
* @param channel 通道
* @param clientId 客户端ID
*/
public static void buildClientId(Channel channel, String clientId) {
@ -62,9 +66,49 @@ public class ChannelAttributeKeyUtils {
/**
* 获取 通道中访客ID
* @param channel 通道
*
* @param channel 通道
*/
public static String getClientId(Channel channel) {
return channel.attr(CLIENT_ID).get();
}
/**
* 为通道绑定 出口流量
*
* @param channel 通道
* @param outFlow 出口流量
*/
public static void buildOutFlow(Channel channel, Integer outFlow) {
channel.attr(OUT_FLOW).set(outFlow);
}
/**
* 获取 通道中出口流量
*
* @param channel 通道
*/
public static Integer getOutFlow(Channel channel) {
return channel.attr(OUT_FLOW).get();
}
/**
* 为通道绑定 进口流量
*
* @param channel 通道
* @param inFlow 进口流量
*/
public static void buildInFlow(Channel channel, Integer inFlow) {
channel.attr(IN_FLOW).set(inFlow);
}
/**
* 获取 通道中进口流量
*
* @param channel 通道
*/
public static Integer getInFlow(Channel channel) {
return channel.attr(IN_FLOW).get();
}
}

View File

@ -5,7 +5,7 @@ MAINTAINER wujiawei <1207537021@qq.com>
RUN echo "Asia/Shanghai" > /etc/timezone
COPY target/middleground-under-cloud-heartbeat-client /native-app
COPY target/wu-lazy-cloud-heartbeat-client /native-app
ENTRYPOINT ["/bin/sh" ,"-c", "exec ./native-app"]

View File

@ -9,8 +9,8 @@ mvn native:build -Pnative
```
### 构建docker镜像
```shell
docker build -t docker-registry.laihui.com/middleground/middleground-under-cloud-heartbeat-client:middleground-2.4.2-native-SNAPSHOT_latest -f Native-Dockerfile .
docker push docker-registry.laihui.com/middleground/middleground-under-cloud-heartbeat-client:middleground-2.4.2-native-SNAPSHOT_latest
docker build -t docker-registry.laihui.com/middleground/wu-lazy-cloud-heartbeat-client:middleground-2.4.2-native-SNAPSHOT_latest -f Native-Dockerfile .
docker push docker-registry.laihui.com/middleground/wu-lazy-cloud-heartbeat-client:middleground-2.4.2-native-SNAPSHOT_latest
```

View File

@ -3,10 +3,10 @@ spring:
netty:
# inet-host: 127.0.0.1
# inet-port: 7001
# inet-path: middleground-on-cloud-heartbeat-server
# inet-path: wu-lazy-cloud-heartbeat-server
inet-host: 124.222.48.62 # 服务端地址
inet-port: 30676 #服务端端口
# inet-path: middleground-on-cloud-heartbeat-server
# inet-path: wu-lazy-cloud-heartbeat-server
client-id: wujiawei # 客户端ID
data:
redis:

View File

@ -2,6 +2,7 @@ package wu.framework.lazy.cloud.heartbeat.server.application.impl;
import lombok.extern.slf4j.Slf4j;
import wu.framework.lazy.cloud.heartbeat.common.InternalNetworkPenetrationRealClient;
import wu.framework.lazy.cloud.heartbeat.common.adapter.ChannelFlowAdapter;
import wu.framework.lazy.cloud.heartbeat.server.application.InternalNetworkPenetrationMappingApplication;
import wu.framework.lazy.cloud.heartbeat.server.application.assembler.InternalNetworkPenetrationMappingDTOAssembler;
import wu.framework.lazy.cloud.heartbeat.server.application.command.internal.network.penetration.mapping.*;
@ -34,6 +35,9 @@ public class InternalNetworkPenetrationMappingApplicationImpl implements Interna
@Resource
InternalNetworkPenetrationMappingRepository internalNetworkPenetrationMappingRepository;
@Resource
ChannelFlowAdapter channelFlowAdapter;
/**
* describe 新增内网穿透映射
@ -160,20 +164,28 @@ public class InternalNetworkPenetrationMappingApplicationImpl implements Interna
String clientTargetIp = networkPenetrationMapping.getClientTargetIp();
Integer clientTargetPort = networkPenetrationMapping.getClientTargetPort();
InternalNetworkPenetrationRealClient internalNetworkPenetrationRealClient = new InternalNetworkPenetrationRealClient();
internalNetworkPenetrationRealClient.setClientTargetIp(clientTargetIp);
internalNetworkPenetrationRealClient.setClientTargetPort(clientTargetPort);
internalNetworkPenetrationRealClient.setClientId(clientId);
internalNetworkPenetrationRealClient.setVisitorPort(visitorPort);
// InternalNetworkPenetrationRealClient internalNetworkPenetrationRealClient = new InternalNetworkPenetrationRealClient();
// internalNetworkPenetrationRealClient.setClientTargetIp(clientTargetIp);
// internalNetworkPenetrationRealClient.setClientTargetPort(clientTargetPort);
// internalNetworkPenetrationRealClient.setClientId(clientId);
// internalNetworkPenetrationRealClient.setVisitorPort(visitorPort);
// 创建服务端代理连接
VisitorFilter visitorFilter = new VisitorFilter(internalNetworkPenetrationRealClient);
NettyVisitorSocket nettyVisitorSocket = new NettyVisitorSocket(visitorFilter);
// VisitorFilter visitorFilter = new VisitorFilter(internalNetworkPenetrationRealClient);
// NettyVisitorSocket nettyVisitorSocket = new NettyVisitorSocket(visitorFilter);
NettyVisitorSocket nettyVisitorSocket = NettyVisitorSocket.NettyVisitorSocketBuilder
.builder()
.builderClientId(clientId)
.builderClientTargetIp(clientTargetIp)
.builderClientTargetPort(clientTargetPort)
.builderVisitorPort(visitorPort)
.builderChannelFlowAdapter(channelFlowAdapter)
.build();
try {
nettyVisitorSocket.startServer(visitorPort);
} catch (Exception e) {
log.error("客户端:{},网络端口:{},开放失败",clientId,visitorPort);
log.error("客户端:{},网络端口:{},开放失败", clientId, visitorPort);
}

View File

@ -0,0 +1,32 @@
package wu.framework.lazy.cloud.heartbeat.server.netty.config;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Role;
import wu.framework.lazy.cloud.heartbeat.common.adapter.ChannelFlowAdapter;
import wu.framework.lazy.cloud.heartbeat.common.advanced.flow.HandleChannelFlowAdvanced;
import java.util.List;
/**
* @see ChannelFlowAdapter
* @see HandleChannelFlowAdvanced
*/
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class ServerFlowConfiguration {
/**
* 服务端流量适配器
* @param handleChannelFlowAdvancedList 服务端流量适配者
* @return 服务端流量适配器
*/
@ConditionalOnMissingBean(ChannelFlowAdapter.class)
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public ChannelFlowAdapter channelFlowAdapter(List<HandleChannelFlowAdvanced> handleChannelFlowAdvancedList){
return new ChannelFlowAdapter(handleChannelFlowAdvancedList);
}
}

View File

@ -3,13 +3,16 @@ package wu.framework.lazy.cloud.heartbeat.server.netty.filter;
import wu.framework.lazy.cloud.heartbeat.common.InternalNetworkPenetrationRealClient;
import io.netty.channel.*;
import io.netty.channel.socket.SocketChannel;
import wu.framework.lazy.cloud.heartbeat.common.adapter.ChannelFlowAdapter;
import wu.framework.lazy.cloud.heartbeat.server.netty.handler.VisitorHandler;
public class VisitorFilter extends ChannelInitializer<SocketChannel> {
private final InternalNetworkPenetrationRealClient internalNetworkPenetrationRealClient;
private final ChannelFlowAdapter channelFlowAdapter;
public VisitorFilter(InternalNetworkPenetrationRealClient internalNetworkPenetrationRealClient) {
public VisitorFilter(InternalNetworkPenetrationRealClient internalNetworkPenetrationRealClient, ChannelFlowAdapter channelFlowAdapter) {
this.internalNetworkPenetrationRealClient = internalNetworkPenetrationRealClient;
this.channelFlowAdapter = channelFlowAdapter;
}
/**
@ -25,7 +28,7 @@ public class VisitorFilter extends ChannelInitializer<SocketChannel> {
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(new ChannelDuplexHandler());
pipeline.addLast(new VisitorHandler(internalNetworkPenetrationRealClient));
pipeline.addLast(new VisitorHandler(internalNetworkPenetrationRealClient,channelFlowAdapter));
}
}

View File

@ -0,0 +1,56 @@
package wu.framework.lazy.cloud.heartbeat.server.netty.flow;
import lombok.Builder;
import lombok.Data;
import wu.framework.lazy.cloud.heartbeat.common.advanced.flow.ChannelFlow;
import wu.framework.lazy.cloud.heartbeat.common.enums.ChannelFlowEnum;
@Builder
@Data
public class ServerChannelFlow implements ChannelFlow {
private String clientId;
private Integer port;
private ChannelFlowEnum channelFlowEnum;
private Integer flow;
/**
* 通道客户端ID
*
* @return 通道客户端ID
*/
@Override
public String clientId() {
return clientId;
}
/**
* 通道使用的端口服务端访客端口客户端真实端口
*
* @return 端口
*/
@Override
public Integer port() {
return port;
}
/**
* 通道流量类型
*
* @return ChannelFlowEnum
* @see ChannelFlowEnum
*/
@Override
public ChannelFlowEnum channelFlowEnum() {
return channelFlowEnum;
}
/**
* 流量
*
* @return 流量
*/
@Override
public Integer flow() {
return flow;
}
}

View File

@ -2,6 +2,8 @@ package wu.framework.lazy.cloud.heartbeat.server.netty.handler;
import wu.framework.lazy.cloud.heartbeat.common.*;
import wu.framework.lazy.cloud.heartbeat.common.adapter.ChannelFlowAdapter;
import wu.framework.lazy.cloud.heartbeat.common.enums.ChannelFlowEnum;
import wu.framework.lazy.cloud.heartbeat.common.utils.ChannelAttributeKeyUtils;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
@ -10,15 +12,18 @@ import io.netty.channel.ChannelOption;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.internal.StringUtil;
import lombok.extern.slf4j.Slf4j;
import wu.framework.lazy.cloud.heartbeat.server.netty.flow.ServerChannelFlow;
import java.util.UUID;
@Slf4j
public class VisitorHandler extends SimpleChannelInboundHandler<ByteBuf> {
private final InternalNetworkPenetrationRealClient internalNetworkPenetrationRealClient;
private final ChannelFlowAdapter channelFlowAdapter;// 流量适配器
public VisitorHandler(InternalNetworkPenetrationRealClient internalNetworkPenetrationRealClient) {
public VisitorHandler(InternalNetworkPenetrationRealClient internalNetworkPenetrationRealClient, ChannelFlowAdapter channelFlowAdapter) {
this.internalNetworkPenetrationRealClient = internalNetworkPenetrationRealClient;
this.channelFlowAdapter = channelFlowAdapter;
}
@Override
@ -52,10 +57,10 @@ public class VisitorHandler extends SimpleChannelInboundHandler<ByteBuf> {
// 客户端心跳通道
ChannelContext.ClientChannel clientChannel = ChannelContext.get(clientId);
if (clientChannel != null) {
log.info("通过客户端:{},获取通道而后创建连接",clientId);
log.info("通过客户端:{},获取通道而后创建连接", clientId);
Channel channel = clientChannel.getChannel();
channel.writeAndFlush(nettyProxyMsg);
}else {
} else {
log.error("无法通过客户端ID获取客户端通道");
}
@ -70,11 +75,12 @@ public class VisitorHandler extends SimpleChannelInboundHandler<ByteBuf> {
@Override
public void channelRead0(ChannelHandlerContext ctx, ByteBuf buf) {
Channel realChannel = ctx.channel();
String clientId = internalNetworkPenetrationRealClient.getClientId();
String clientTargetIp = internalNetworkPenetrationRealClient.getClientTargetIp();
Integer clientTargetPort = internalNetworkPenetrationRealClient.getClientTargetPort();
Integer visitorPort = internalNetworkPenetrationRealClient.getVisitorPort();
String visitorId = ChannelAttributeKeyUtils.getVisitorId(ctx.channel());
String visitorId = ChannelAttributeKeyUtils.getVisitorId(realChannel);
if (StringUtil.isNullOrEmpty(clientId)) {
return;
}
@ -82,9 +88,11 @@ public class VisitorHandler extends SimpleChannelInboundHandler<ByteBuf> {
buf.readBytes(bytes);
// 获取客户端通道而后进行数据下发
log.debug("服务端访客端口成功接收数据:{}", new String(bytes));
// 使用访客的通信通道
Channel visitorCommunicationChannel = NettyCommunicationIdContext.getVisitor(visitorId);
// 绑定数据流量
ChannelAttributeKeyUtils.buildInFlow(visitorCommunicationChannel, bytes.length);
NettyProxyMsg nettyProxyMsg = new NettyProxyMsg();
nettyProxyMsg.setType(MessageType.DISTRIBUTE_CLIENT_TRANSFER);
nettyProxyMsg.setClientId(clientId);
@ -94,6 +102,15 @@ public class VisitorHandler extends SimpleChannelInboundHandler<ByteBuf> {
nettyProxyMsg.setVisitorId(visitorId);
nettyProxyMsg.setData(bytes);
visitorCommunicationChannel.writeAndFlush(nettyProxyMsg);
// 处理访客流量
ServerChannelFlow serverChannelFlow = ServerChannelFlow
.builder()
.channelFlowEnum(ChannelFlowEnum.IN_FLOW)
.port(visitorPort)
.clientId(clientId)
.flow(bytes.length)
.build();
channelFlowAdapter.handler(realChannel, serverChannelFlow);
log.debug("服务端访客端口成功发送数据了");
}

View File

@ -1,5 +1,6 @@
package wu.framework.lazy.cloud.heartbeat.server.netty.socket;
import wu.framework.lazy.cloud.heartbeat.common.InternalNetworkPenetrationRealClient;
import wu.framework.lazy.cloud.heartbeat.common.NettyVisitorPortContext;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
@ -9,6 +10,7 @@ import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import lombok.extern.slf4j.Slf4j;
import wu.framework.lazy.cloud.heartbeat.common.adapter.ChannelFlowAdapter;
import wu.framework.lazy.cloud.heartbeat.server.netty.filter.VisitorFilter;
/**
@ -17,10 +19,11 @@ import wu.framework.lazy.cloud.heartbeat.server.netty.filter.VisitorFilter;
@Slf4j
public class NettyVisitorSocket {
private final VisitorFilter visitorFilter;
private static final EventLoopGroup bossGroup = new NioEventLoopGroup();
private static final EventLoopGroup workerGroup = new NioEventLoopGroup();
public NettyVisitorSocket(VisitorFilter visitorFilter) {
public NettyVisitorSocket(VisitorFilter visitorFilter ) {
this.visitorFilter = visitorFilter;
}
@ -39,7 +42,7 @@ public class NettyVisitorSocket {
.childHandler(visitorFilter);
ChannelFuture sync = b.bind(visitorPort).sync();
sync.addListener((ChannelFutureListener) future -> {
if(future.isSuccess()){
if (future.isSuccess()) {
Channel channel = future.channel();
log.info("访客端口:{} 开启", visitorPort);
NettyVisitorPortContext.pushVisitor(visitorPort, channel);
@ -52,4 +55,133 @@ public class NettyVisitorSocket {
}
public static final class NettyVisitorSocketBuilder {
/**
* 客户端ID
*/
private String clientId;
/**
* 客户端目标地址
*/
private String clientTargetIp;
/**
* 客户端目标端口
*/
private Integer clientTargetPort;
/**
* 访问端口
*/
private Integer visitorPort;
/**
* 访客ID
*/
private String visitorId;
/**
* 流量适配器
*/
private ChannelFlowAdapter channelFlowAdapter;
/**
* 填充客户端
*
* @param clientId 客户端
* @return 返回当前对象
*/
public NettyVisitorSocketBuilder builderClientId(String clientId) {
this.clientId = clientId;
return this;
}
/**
* 绑定客户端目标IP
*
* @param clientTargetIp 客户端目标IP
* @return 当前对象
*/
public NettyVisitorSocketBuilder builderClientTargetIp(String clientTargetIp) {
this.clientTargetIp = clientTargetIp;
return this;
}
/**
* 绑定客户端目标端口
*
* @param clientTargetPort 客户端目标端口
* @return 当前对象
*/
public NettyVisitorSocketBuilder builderClientTargetPort(Integer clientTargetPort) {
this.clientTargetPort = clientTargetPort;
return this;
}
/**
* 绑定访客端口
*
* @param visitorPort 访客端口
* @return 当前对象
*/
public NettyVisitorSocketBuilder builderVisitorPort(Integer visitorPort) {
this.visitorPort = visitorPort;
return this;
}
/**
* 绑定流量适配器
* @param channelFlowAdapter 流量适配器
* @return 当前对象
*/
public NettyVisitorSocketBuilder builderChannelFlowAdapter(ChannelFlowAdapter channelFlowAdapter) {
this.channelFlowAdapter = channelFlowAdapter;
return this;
}
/**
* 绑定访客ID
*
* @param visitorId 访客ID
* @return 当前对象
*/
public NettyVisitorSocketBuilder builderVisitorId(String visitorId) {
this.visitorId = visitorId;
return this;
}
public static NettyVisitorSocketBuilder builder() {
return new NettyVisitorSocketBuilder();
}
public NettyVisitorSocket build() {
if (clientId == null) {
throw new IllegalArgumentException("clientId must not null");
}
if (clientTargetIp == null) {
throw new IllegalArgumentException("clientTargetIp must not null");
}
if (clientTargetPort == null) {
throw new IllegalArgumentException("clientTargetPort must not null");
}
if (visitorPort == null) {
throw new IllegalArgumentException("visitorPort must not null");
}
InternalNetworkPenetrationRealClient internalNetworkPenetrationRealClient = InternalNetworkPenetrationRealClient
.builder()
.clientId(clientId)
.clientTargetIp(clientTargetIp)
.clientTargetPort(clientTargetPort)
.visitorPort(visitorPort)
.visitorId(visitorId).build();
VisitorFilter visitorFilter = new VisitorFilter(internalNetworkPenetrationRealClient,channelFlowAdapter);
return new NettyVisitorSocket(visitorFilter);
}
}
}

View File

@ -2,4 +2,5 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
wu.framework.lazy.cloud.heartbeat.server.EnableHeartbeatServerAutoConfiguration,\
wu.framework.lazy.cloud.heartbeat.server.netty.config.HeartbeatServerConfiguration,\
wu.framework.lazy.cloud.heartbeat.server.netty.config.ServerAutoConfiguration
wu.framework.lazy.cloud.heartbeat.server.netty.config.ServerAutoConfiguration,\
wu.framework.lazy.cloud.heartbeat.server.netty.config.ServerFlowConfiguration

View File

@ -1,3 +1,4 @@
wu.framework.lazy.cloud.heartbeat.server.EnableHeartbeatServerAutoConfiguration
wu.framework.lazy.cloud.heartbeat.server.netty.config.HeartbeatServerConfiguration
wu.framework.lazy.cloud.heartbeat.server.netty.config.ServerAutoConfiguration
wu.framework.lazy.cloud.heartbeat.server.netty.config.ServerFlowConfiguration

View File

@ -1 +1 @@
<!doctype html><html lang="zh-cn"><head><meta charset="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><link rel="icon" href="favicon.ico"/><title>lazy-ui</title><script defer="defer" src="js/chunk-elementPlusIcon.7f775a37.js"></script><script defer="defer" src="js/chunk-elementPlus.51ee9f03.js"></script><script defer="defer" src="js/chunk-mockjs.208b5e15.js"></script><script defer="defer" src="js/chunk-vendors.4fee82e9.js"></script><script defer="defer" src="js/app.ae95a4ac.js"></script><link href="css/chunk-elementPlus.e89c9935.css" rel="stylesheet"><link href="css/app.4ce91422.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but lazy-ui doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>
<!doctype html><html lang="zh-cn"><head><meta charset="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><link rel="icon" href="favicon.ico"/><title>lazy-ui</title><script defer="defer" src="js/chunk-elementPlusIcon.7f775a37.js"></script><script defer="defer" src="js/chunk-elementPlus.51ee9f03.js"></script><script defer="defer" src="js/chunk-mockjs.208b5e15.js"></script><script defer="defer" src="js/chunk-vendors.4fee82e9.js"></script><script defer="defer" src="js/app.2f951f67.js"></script><link href="css/chunk-elementPlus.e89c9935.css" rel="stylesheet"><link href="css/app.4ce91422.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but lazy-ui doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>

View File

@ -273,8 +273,18 @@ VE_API [ fileName ][ portName ] (params,{Global:false) //没有全局loading
```shell
npm config set registry http://registry.npm.taobao.org/
```
### 打包
```shell
yarn run build
```
### 拷贝前端
```shell
echo "开始拷贝前端UI"
rm -rf ../wu-lazy-cloud-heartbeat-server/src/resources/static
cp -r ../wu-lazy-cloud-network-ui/dist/* ../wu-lazy-cloud-heartbeat-server/src/main/resources/static/
```

View File

@ -0,0 +1,203 @@
<template>
<div class="ve_container">
<!-- 搜索 -->
<el-form ref="queryForm" :inline="true" :model="params">
<el-form-item label="客户端ID" prop="clientId">
<el-input
clearable
v-model="clientId"
placeholder="客户端ID"
></el-input>
</el-form-item>
<el-form-item>
<el-button
type="primary"
@click="onSubmit(params, getDataList)"
>
{{ buttons.search.name }}
</el-button>
<el-button @click="resetForm(queryForm, params, getDataList)">
重置
</el-button>
</el-form-item>
</el-form>
<!-- 列表 -->
<ve-table
:table="{
data: tableData,
}"
:pagination="{
onSizeChange: (val) =>
handleSizeChange(val, params, getDataList),
onCurrentChange: (val) =>
handleCurrentChange(val, params, getDataList),
currentPage: current,
pageSize: size,
total: total,
}"
>
<template #tool_bar>
<el-button
title="弹窗式"
v-permission="['add']"
size="small"
type="primary"
@click="handleEdit(buttons.add.name)"
>
{{ buttons.add.name }}
</el-button>
</template>
<el-table-column prop="clientId" label="客户端ID"></el-table-column>
<el-table-column prop="onLineState" label="客户端在线状态">
</el-table-column>
<el-table-column prop="stagingState" label="暂存状态">
</el-table-column>
<el-table-column fixed="right" label="操作">
<template v-slot:default="{ row }">
<el-button
v-permission="['offLine']"
@click.prevent="handleOffLine(row.clientId)"
type="danger"
size="small"
>
{{ buttons.offLine.name }}
</el-button>
<el-button
v-permission="['sendMessage']"
@click.prevent="handleArouse2SendMessage(row)"
type="primary"
size="small"
>
{{ buttons.sendMessage.name }}
</el-button>
</template>
</el-table-column>
</ve-table>
<!--发送消息到客户端-->
<cloud-server-send-message2-clinet
v-if="showDialog"
:rowData="rowData"
:showDialog="showDialog"
@closeDialog="handelDialog($event)"
/>
</div>
</template>
<script>
import cloudNetworkMenu from "@/views/layoutpages/cloud_network/components/CloudNetworkMenu";
export default {
data: () => ({
description: "客户端流量管理",
buttons: {
search: { name: "查询" },
add: { name: "添加" },
edit: { name: "编辑" },
offLine: { name: "下线" },
sendMessage: { name: "发送消息" },
export: { name: "导出用户" },
},
// type 0: 1 2
type: "1",
icon: "Avatar",
name: "客户端流量管理",
parentMenu: cloudNetworkMenu,
}),
};
</script>
<script setup>
import { reactive, toRefs, ref, onMounted, getCurrentInstance } from "vue";
//?
import {
onSubmit,
resetForm,
handleSizeChange,
handleCurrentChange,
} from "@/views/layoutpages/common";
import CloudServerSendMessage2Clinet from "@/views/layoutpages/cloud_network/components/CloudServerSendMessage2Clinet.vue";
const { proxy } = getCurrentInstance();
const queryForm = ref(null);
const tableData = ref([]);
const rowData = ref(null);
const showDialog = ref(false);
const params = reactive({
clientId: "",
size: 10,
current: 1,
total: 0,
});
const { clientId, size, current, total } = toRefs(params);
/**
* @description: dialog事件
* @param {*}
* @return {*}
*/
const handelDialog = (e) => {
showDialog.value = e;
getDataList();
};
/**
* @description:添加or编辑事件
* @param {*}
* @return {*}
*/
const handleArouse2SendMessage = (row = null) => {
showDialog.value = true;
rowData.value = row;
};
/**
* @description:
* @param {*}
* @return {*}
*/
const handleOffLine = (clientId) => {
proxy
.$confirm("此操作将永久删除该数据, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "error",
})
.then(async () => {
const { code } = await VE_API.cloudNetwork.cloudClientDelete({
clientId,
});
if (code == "00") {
getDataList();
}
})
.catch(() => {
proxy.$message({
type: "info",
message: "已取消删除",
});
});
};
/**
* @description: 获取列表数据
* @param {*}
* @return {*}
*/
const getDataList = async () => {
const { code, data } =
await VE_API.cloudNetwork.cloudClientFindPage(params);
if (code === 0) {
const { size, current, total, record } = data;
params.size = size;
params.current = current;
params.total = total;
tableData.value = record;
}
};
onMounted(async () => {
await getDataList();
// maxHeight(pagination, queryForm, toolBar, ve_max_height);
});
</script>
<style lang="scss" scoped></style>

View File

@ -56,12 +56,12 @@
<el-table-column fixed="right" label="操作">
<template v-slot:default="{ row }">
<el-button
v-permission="['off_line']"
v-permission="['offLine']"
@click.prevent="handleOffLine(row.clientId)"
type="danger"
size="small"
>
{{ buttons.del.name }}
{{ buttons.offLine.name }}
</el-button>
<el-button
v-permission="['sendMessage']"
@ -93,7 +93,7 @@ export default {
search: { name: "查询" },
add: { name: "添加" },
edit: { name: "编辑" },
off_line: { name: "下线" },
offLine: { name: "下线" },
sendMessage: { name: "发送消息" },
export: { name: "导出用户" },
},