From 0a6f980474f22ccf6ec50a35c8dbc612fd34416b Mon Sep 17 00:00:00 2001 From: wujiawei <12345678> Date: Mon, 8 Jan 2024 18:28:23 +0800 Subject: [PATCH] fix init --- ...ClientInternalNetworkPenetration.README.md | 92 +++ CloudClientInternalNetworkPenetration1.0-.png | Bin 0 -> 44110 bytes CloudClientInternalNetworkPenetration1.0.puml | 77 +++ k8s-on.yaml | 152 +++++ k8s-under.yaml | 154 +++++ lazy-cloud-heartbeat-client/Native-Dockerfile | 16 + lazy-cloud-heartbeat-client/README.md | 14 + lazy-cloud-heartbeat-client/pom.xml | 56 ++ ...MiddlegroundUnderCloudHeartbeatClient.java | 15 + .../ClientNettyConfigApplication.java | 32 + .../ClientNettyConfigApplicationImpl.java | 82 +++ .../ClientChannelHeartbeatTypeAdvanced.java | 31 + ...ClientRealAutoReadConnectTypeAdvanced.java | 31 + ...gleClientRealCloseVisitorTypeAdvanced.java | 28 + ...teSingleClientRealConnectTypeAdvanced.java | 56 ++ ...ientReportChannelTransferTypeAdvanced.java | 59 ++ ...onnectSuccessNotificationTypeAdvanced.java | 55 ++ .../DistributeDisconnectTypeAdvanced.java | 44 ++ .../DistributeStagingClosedTypeAdvanced.java | 34 ++ .../DistributeStagingOpenedTypeAdvanced.java | 37 ++ .../netty/config/AutoConfiguration.java | 82 +++ .../netty/config/NettyServerProperties.java | 31 + .../netty/filter/NettyClientFilter.java | 45 ++ .../netty/filter/NettyClientRealFilter.java | 30 + .../filter/NettyClientVisitorRealFilter.java | 43 ++ .../netty/handler/HeartBeatClientHandler.java | 25 + .../netty/handler/NettyClientHandler.java | 120 ++++ .../netty/handler/NettyClientRealHandler.java | 81 +++ .../NettyClientVisitorRealHandler.java | 63 ++ ...entStagingOpenedOrClosedRedisListener.java | 54 ++ .../netty/socket/NettyClientRealSocket.java | 176 ++++++ .../netty/socket/NettyClientSocket.java | 114 ++++ .../client/rpc/StagingNoticeApiRpc.java | 67 +++ .../src/main/resources/application-dev.yml | 17 + .../src/main/resources/application-prod.yml | 0 .../src/main/resources/application.yml | 7 + .../src/main/resources/bootstrap.yml | 12 + lazy-cloud-heartbeat-common/pom.xml | 30 + .../heartbeat/common/ChannelContext.java | 193 ++++++ .../InternalNetworkPenetrationRealClient.java | 41 ++ .../cloud/heartbeat/common/MessageType.java | 136 +++++ .../common/NettyCommunicationIdContext.java | 71 +++ .../cloud/heartbeat/common/NettyMsg.java | 39 ++ .../cloud/heartbeat/common/NettyProxyMsg.java | 111 ++++ .../heartbeat/common/NettyRealIdContext.java | 71 +++ .../heartbeat/common/NettyVisitorContext.java | 35 ++ .../common/NettyVisitorIdContext.java | 72 +++ .../common/adapter/ChannelTypeAdapter.java | 36 ++ .../AbstractChannelHeartbeatTypeAdvanced.java | 25 + .../advanced/AbstractChannelTypeAdvanced.java | 68 +++ .../common/advanced/ChannelTypeAdvanced.java | 33 ++ ...DistributeChannelTransferTypeAdvanced.java | 27 + ...onnectSuccessNotificationTypeAdvanced.java | 23 + ...tractDistributeDisconnectTypeAdvanced.java | 26 + ...ClientRealAutoReadConnectTypeAdvanced.java | 27 + ...gleClientRealCloseVisitorTypeAdvanced.java | 25 + ...teSingleClientRealConnectTypeAdvanced.java | 25 + ...ctDistributeStagingClosedTypeAdvanced.java | 25 + ...ctDistributeStagingOpenedTypeAdvanced.java | 25 + ...ractReportChannelTransferTypeAdvanced.java | 27 + ...tractReportConnectSuccessTypeAdvanced.java | 23 + .../AbstractReportDisconnectTypeAdvanced.java | 27 + ...tSingleClientCloseVisitorTypeAdvanced.java | 27 + ...rtSingleClientRealConnectTypeAdvanced.java | 27 + ...stractReportStagingClosedTypeAdvanced.java | 29 + ...stractReportStagingOpenedTypeAdvanced.java | 25 + .../common/constant/ClientConfigKeyUtils.java | 46 ++ .../constant/NettyChannelAttributeKey.java | 10 + .../common/constant/ProxyConfigConstant.java | 5 + .../common/constant/RedisChannelConstant.java | 14 + .../common/decoder/NettyMsgDecoder.java | 53 ++ .../common/decoder/NettyProxyMsgDecoder.java | 152 +++++ .../common/encoder/NettMsgEncoder.java | 48 ++ .../common/encoder/NettyProxyMsgEncoder.java | 106 ++++ .../common/enums/MessageTypeEnums.java | 91 +++ .../common/enums/NettyClientStatus.java | 17 + .../common/state/ClientOnLineState.java | 18 + .../utils/ChannelAttributeKeyUtils.java | 70 +++ lazy-cloud-heartbeat-server/pom.xml | 68 +++ .../MiddlegroundOnCloudHeartbeatServer.java | 14 + ...lNetworkPenetrationMappingApplication.java | 111 ++++ .../NettyClientBlacklistApplication.java | 116 ++++ .../NettyClientStateApplication.java | 107 ++++ .../ServerNettyConfigApplication.java | 34 ++ ...NetworkPenetrationMappingDTOAssembler.java | 89 +++ .../NettyClientBlacklistDTOAssembler.java | 89 +++ .../NettyClientStateDTOAssembler.java | 89 +++ ...orkPenetrationMappingQueryListCommand.java | 82 +++ ...workPenetrationMappingQueryOneCommand.java | 82 +++ ...etworkPenetrationMappingRemoveCommand.java | 82 +++ ...NetworkPenetrationMappingStoryCommand.java | 82 +++ ...etworkPenetrationMappingUpdateCommand.java | 82 +++ .../NettyClientBlacklistQueryListCommand.java | 56 ++ .../NettyClientBlacklistQueryOneCommand.java | 56 ++ .../NettyClientBlacklistRemoveCommand.java | 56 ++ .../NettyClientBlacklistStoryCommand.java | 60 ++ .../NettyClientBlacklistUpdateCommand.java | 56 ++ .../NettyClientStateQueryListCommand.java | 71 +++ .../NettyClientStateQueryOneCommand.java | 71 +++ .../state/NettyClientStateRemoveCommand.java | 71 +++ .../state/NettyClientStateStoryCommand.java | 71 +++ .../state/NettyClientStateUpdateCommand.java | 71 +++ .../application/dto/ClientChannelDTO.java | 26 + .../InternalNetworkPenetrationMappingDTO.java | 82 +++ .../dto/NettyClientBlacklistDTO.java | 56 ++ .../application/dto/NettyClientStateDTO.java | 71 +++ ...workPenetrationMappingApplicationImpl.java | 202 +++++++ .../NettyClientBlacklistApplicationImpl.java | 170 ++++++ .../impl/NettyClientStateApplicationImpl.java | 141 +++++ .../ServerNettyConfigApplicationImpl.java | 97 +++ .../domain/controller/ChannelController.java | 111 ++++ ...rnalNetworkPenetrationMappingProvider.java | 138 +++++ .../NettyClientBlacklistProvider.java | 140 +++++ .../controller/NettyClientStateProvider.java | 139 +++++ ...nalNetworkPenetrationMappingConverter.java | 48 ++ .../NettyClientBlacklistConverter.java | 50 ++ .../converter/NettyClientStateConverter.java | 48 ++ .../InternalNetworkPenetrationMappingDO.java | 94 +++ .../entity/NettyClientBlacklistDO.java | 59 ++ .../entity/NettyClientStateDO.java | 74 +++ ...ternalNetworkPenetrationMappingMapper.java | 15 + .../mapper/NettyClientBlacklistMapper.java | 15 + .../mapper/NettyClientStateMapper.java | 15 + ...tworkPenetrationMappingRepositoryImpl.java | 152 +++++ .../NettyClientBlacklistRepositoryImpl.java | 146 +++++ .../NettyClientStateRepositoryImpl.java | 178 ++++++ .../InternalNetworkPenetrationMapping.java | 85 +++ ...alNetworkPenetrationMappingRepository.java | 104 ++++ .../blacklist/NettyClientBlacklist.java | 56 ++ .../NettyClientBlacklistRepository.java | 104 ++++ .../netty/client/state/NettyClientState.java | 71 +++ .../state/NettyClientStateRepository.java | 118 ++++ .../ServerChannelHeartbeatTypeAdvanced.java | 32 + ...rverReportChannelTransferTypeAdvanced.java | 41 ++ ...erverReportConnectSuccessTypeAdvanced.java | 91 +++ .../ServerReportDisconnectTypeAdvanced.java | 73 +++ ...tSingleClientCloseVisitorTypeAdvanced.java | 32 + ...rtSingleClientRealConnectTypeAdvanced.java | 46 ++ ...ServerReportStagingClosedTypeAdvanced.java | 61 ++ ...ServerReportStagingOpenedTypeAdvanced.java | 61 ++ .../netty/config/AutoConfiguration.java | 64 ++ .../netty/filter/NettyServerFilter.java | 51 ++ .../domain/netty/filter/VisitorFilter.java | 31 + .../netty/handler/HeartBeatServerHandler.java | 45 ++ .../handler/LazyServerIdleStateHandler.java | 553 ++++++++++++++++++ .../netty/handler/NettyServerHandler.java | 114 ++++ .../domain/netty/handler/VisitorHandler.java | 161 +++++ .../socket/NettyOnCloudNettyServerSocket.java | 62 ++ .../netty/socket/NettyVisitorSocket.java | 55 ++ .../src/main/resources/application-dev.yml | 14 + .../src/main/resources/application-prod.yml | 10 + .../src/main/resources/application.yml | 9 + .../src/main/resources/bootstrap.yml | 15 + netty-proxy-client/pom.xml | 40 -- .../java/com/luck/client/ClientStart.java | 21 - .../main/java/com/luck/client/Constant.java | 87 --- .../java/com/luck/client/ProxyHandler.java | 98 ---- .../java/com/luck/client/ProxySocket.java | 101 ---- .../java/com/luck/client/RealHandler.java | 74 --- .../main/java/com/luck/client/RealSocket.java | 59 -- .../client/controller/ClientController.java | 17 - .../src/main/resources/application.yml | 2 - netty-proxy-common/pom.xml | 26 - .../src/main/java/com/luck/msg/MyMsg.java | 58 -- .../main/java/com/luck/msg/MyMsgDecoder.java | 41 -- .../main/java/com/luck/msg/MyMsgEncoder.java | 28 - netty-proxy-server/pom.xml | 40 -- .../java/com/luck/server/ClientHandler.java | 113 ---- .../main/java/com/luck/server/Constant.java | 82 --- .../java/com/luck/server/ServerSocket.java | 61 -- .../java/com/luck/server/ServerStart.java | 21 - .../java/com/luck/server/VisitorHandler.java | 97 --- .../java/com/luck/server/VisitorSocket.java | 37 -- .../server/controller/ServerController.java | 17 - .../src/main/resources/application.yml | 2 - pom.xml | 105 ++-- 176 files changed, 10256 insertions(+), 1174 deletions(-) create mode 100644 CloudClientInternalNetworkPenetration.README.md create mode 100644 CloudClientInternalNetworkPenetration1.0-.png create mode 100644 CloudClientInternalNetworkPenetration1.0.puml create mode 100644 k8s-on.yaml create mode 100644 k8s-under.yaml create mode 100644 lazy-cloud-heartbeat-client/Native-Dockerfile create mode 100644 lazy-cloud-heartbeat-client/README.md create mode 100644 lazy-cloud-heartbeat-client/pom.xml create mode 100644 lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/MiddlegroundUnderCloudHeartbeatClient.java create mode 100644 lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/application/ClientNettyConfigApplication.java create mode 100644 lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/application/impl/ClientNettyConfigApplicationImpl.java create mode 100644 lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/advanced/ClientChannelHeartbeatTypeAdvanced.java create mode 100644 lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/advanced/ClientDistributeSingleClientRealAutoReadConnectTypeAdvanced.java create mode 100644 lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/advanced/ClientDistributeSingleClientRealCloseVisitorTypeAdvanced.java create mode 100644 lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/advanced/ClientDistributeSingleClientRealConnectTypeAdvanced.java create mode 100644 lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/advanced/ClientReportChannelTransferTypeAdvanced.java create mode 100644 lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/advanced/DistributeConnectSuccessNotificationTypeAdvanced.java create mode 100644 lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/advanced/DistributeDisconnectTypeAdvanced.java create mode 100644 lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/advanced/DistributeStagingClosedTypeAdvanced.java create mode 100644 lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/advanced/DistributeStagingOpenedTypeAdvanced.java create mode 100644 lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/config/AutoConfiguration.java create mode 100644 lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/config/NettyServerProperties.java create mode 100644 lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/filter/NettyClientFilter.java create mode 100644 lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/filter/NettyClientRealFilter.java create mode 100644 lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/filter/NettyClientVisitorRealFilter.java create mode 100644 lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/handler/HeartBeatClientHandler.java create mode 100644 lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/handler/NettyClientHandler.java create mode 100644 lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/handler/NettyClientRealHandler.java create mode 100644 lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/handler/NettyClientVisitorRealHandler.java create mode 100644 lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/listener/ClientStagingOpenedOrClosedRedisListener.java create mode 100644 lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/socket/NettyClientRealSocket.java create mode 100644 lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/socket/NettyClientSocket.java create mode 100644 lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/rpc/StagingNoticeApiRpc.java create mode 100644 lazy-cloud-heartbeat-client/src/main/resources/application-dev.yml create mode 100644 lazy-cloud-heartbeat-client/src/main/resources/application-prod.yml create mode 100644 lazy-cloud-heartbeat-client/src/main/resources/application.yml create mode 100644 lazy-cloud-heartbeat-client/src/main/resources/bootstrap.yml create mode 100644 lazy-cloud-heartbeat-common/pom.xml create mode 100644 lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/ChannelContext.java create mode 100644 lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/InternalNetworkPenetrationRealClient.java create mode 100644 lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/MessageType.java create mode 100644 lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/NettyCommunicationIdContext.java create mode 100644 lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/NettyMsg.java create mode 100644 lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/NettyProxyMsg.java create mode 100644 lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/NettyRealIdContext.java create mode 100644 lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/NettyVisitorContext.java create mode 100644 lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/NettyVisitorIdContext.java create mode 100644 lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/adapter/ChannelTypeAdapter.java create mode 100644 lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/AbstractChannelHeartbeatTypeAdvanced.java create mode 100644 lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/AbstractChannelTypeAdvanced.java create mode 100644 lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/ChannelTypeAdvanced.java create mode 100644 lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/client/AbstractDistributeChannelTransferTypeAdvanced.java create mode 100644 lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/client/AbstractDistributeConnectSuccessNotificationTypeAdvanced.java create mode 100644 lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/client/AbstractDistributeDisconnectTypeAdvanced.java create mode 100644 lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/client/AbstractDistributeSingleClientRealAutoReadConnectTypeAdvanced.java create mode 100644 lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/client/AbstractDistributeSingleClientRealCloseVisitorTypeAdvanced.java create mode 100644 lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/client/AbstractDistributeSingleClientRealConnectTypeAdvanced.java create mode 100644 lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/client/AbstractDistributeStagingClosedTypeAdvanced.java create mode 100644 lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/client/AbstractDistributeStagingOpenedTypeAdvanced.java create mode 100644 lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/server/AbstractReportChannelTransferTypeAdvanced.java create mode 100644 lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/server/AbstractReportConnectSuccessTypeAdvanced.java create mode 100644 lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/server/AbstractReportDisconnectTypeAdvanced.java create mode 100644 lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/server/AbstractReportSingleClientCloseVisitorTypeAdvanced.java create mode 100644 lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/server/AbstractReportSingleClientRealConnectTypeAdvanced.java create mode 100644 lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/server/AbstractReportStagingClosedTypeAdvanced.java create mode 100644 lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/server/AbstractReportStagingOpenedTypeAdvanced.java create mode 100644 lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/constant/ClientConfigKeyUtils.java create mode 100644 lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/constant/NettyChannelAttributeKey.java create mode 100644 lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/constant/ProxyConfigConstant.java create mode 100644 lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/constant/RedisChannelConstant.java create mode 100644 lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/decoder/NettyMsgDecoder.java create mode 100644 lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/decoder/NettyProxyMsgDecoder.java create mode 100644 lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/encoder/NettMsgEncoder.java create mode 100644 lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/encoder/NettyProxyMsgEncoder.java create mode 100644 lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/enums/MessageTypeEnums.java create mode 100644 lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/enums/NettyClientStatus.java create mode 100644 lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/state/ClientOnLineState.java create mode 100644 lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/utils/ChannelAttributeKeyUtils.java create mode 100644 lazy-cloud-heartbeat-server/pom.xml create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/MiddlegroundOnCloudHeartbeatServer.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/InternalNetworkPenetrationMappingApplication.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/NettyClientBlacklistApplication.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/NettyClientStateApplication.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/ServerNettyConfigApplication.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/assembler/InternalNetworkPenetrationMappingDTOAssembler.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/assembler/NettyClientBlacklistDTOAssembler.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/assembler/NettyClientStateDTOAssembler.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/internal/network/penetration/mapping/InternalNetworkPenetrationMappingQueryListCommand.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/internal/network/penetration/mapping/InternalNetworkPenetrationMappingQueryOneCommand.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/internal/network/penetration/mapping/InternalNetworkPenetrationMappingRemoveCommand.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/internal/network/penetration/mapping/InternalNetworkPenetrationMappingStoryCommand.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/internal/network/penetration/mapping/InternalNetworkPenetrationMappingUpdateCommand.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/netty/client/blacklist/NettyClientBlacklistQueryListCommand.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/netty/client/blacklist/NettyClientBlacklistQueryOneCommand.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/netty/client/blacklist/NettyClientBlacklistRemoveCommand.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/netty/client/blacklist/NettyClientBlacklistStoryCommand.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/netty/client/blacklist/NettyClientBlacklistUpdateCommand.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/netty/client/state/NettyClientStateQueryListCommand.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/netty/client/state/NettyClientStateQueryOneCommand.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/netty/client/state/NettyClientStateRemoveCommand.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/netty/client/state/NettyClientStateStoryCommand.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/netty/client/state/NettyClientStateUpdateCommand.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/dto/ClientChannelDTO.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/dto/InternalNetworkPenetrationMappingDTO.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/dto/NettyClientBlacklistDTO.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/dto/NettyClientStateDTO.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/impl/InternalNetworkPenetrationMappingApplicationImpl.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/impl/NettyClientBlacklistApplicationImpl.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/impl/NettyClientStateApplicationImpl.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/impl/ServerNettyConfigApplicationImpl.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/controller/ChannelController.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/controller/InternalNetworkPenetrationMappingProvider.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/controller/NettyClientBlacklistProvider.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/controller/NettyClientStateProvider.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/infrastructure/converter/InternalNetworkPenetrationMappingConverter.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/infrastructure/converter/NettyClientBlacklistConverter.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/infrastructure/converter/NettyClientStateConverter.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/infrastructure/entity/InternalNetworkPenetrationMappingDO.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/infrastructure/entity/NettyClientBlacklistDO.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/infrastructure/entity/NettyClientStateDO.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/infrastructure/mapper/InternalNetworkPenetrationMappingMapper.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/infrastructure/mapper/NettyClientBlacklistMapper.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/infrastructure/mapper/NettyClientStateMapper.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/infrastructure/persistence/InternalNetworkPenetrationMappingRepositoryImpl.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/infrastructure/persistence/NettyClientBlacklistRepositoryImpl.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/infrastructure/persistence/NettyClientStateRepositoryImpl.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/model/internal/network/penetration/mapping/InternalNetworkPenetrationMapping.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/model/internal/network/penetration/mapping/InternalNetworkPenetrationMappingRepository.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/model/netty/client/blacklist/NettyClientBlacklist.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/model/netty/client/blacklist/NettyClientBlacklistRepository.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/model/netty/client/state/NettyClientState.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/model/netty/client/state/NettyClientStateRepository.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/advanced/ServerChannelHeartbeatTypeAdvanced.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/advanced/ServerReportChannelTransferTypeAdvanced.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/advanced/ServerReportConnectSuccessTypeAdvanced.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/advanced/ServerReportDisconnectTypeAdvanced.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/advanced/ServerReportSingleClientCloseVisitorTypeAdvanced.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/advanced/ServerReportSingleClientRealConnectTypeAdvanced.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/advanced/ServerReportStagingClosedTypeAdvanced.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/advanced/ServerReportStagingOpenedTypeAdvanced.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/config/AutoConfiguration.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/filter/NettyServerFilter.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/filter/VisitorFilter.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/handler/HeartBeatServerHandler.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/handler/LazyServerIdleStateHandler.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/handler/NettyServerHandler.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/handler/VisitorHandler.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/socket/NettyOnCloudNettyServerSocket.java create mode 100644 lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/socket/NettyVisitorSocket.java create mode 100644 lazy-cloud-heartbeat-server/src/main/resources/application-dev.yml create mode 100644 lazy-cloud-heartbeat-server/src/main/resources/application-prod.yml create mode 100644 lazy-cloud-heartbeat-server/src/main/resources/application.yml create mode 100644 lazy-cloud-heartbeat-server/src/main/resources/bootstrap.yml delete mode 100644 netty-proxy-client/pom.xml delete mode 100644 netty-proxy-client/src/main/java/com/luck/client/ClientStart.java delete mode 100644 netty-proxy-client/src/main/java/com/luck/client/Constant.java delete mode 100644 netty-proxy-client/src/main/java/com/luck/client/ProxyHandler.java delete mode 100644 netty-proxy-client/src/main/java/com/luck/client/ProxySocket.java delete mode 100644 netty-proxy-client/src/main/java/com/luck/client/RealHandler.java delete mode 100644 netty-proxy-client/src/main/java/com/luck/client/RealSocket.java delete mode 100644 netty-proxy-client/src/main/java/com/luck/client/controller/ClientController.java delete mode 100644 netty-proxy-client/src/main/resources/application.yml delete mode 100644 netty-proxy-common/pom.xml delete mode 100644 netty-proxy-common/src/main/java/com/luck/msg/MyMsg.java delete mode 100644 netty-proxy-common/src/main/java/com/luck/msg/MyMsgDecoder.java delete mode 100644 netty-proxy-common/src/main/java/com/luck/msg/MyMsgEncoder.java delete mode 100644 netty-proxy-server/pom.xml delete mode 100644 netty-proxy-server/src/main/java/com/luck/server/ClientHandler.java delete mode 100644 netty-proxy-server/src/main/java/com/luck/server/Constant.java delete mode 100644 netty-proxy-server/src/main/java/com/luck/server/ServerSocket.java delete mode 100644 netty-proxy-server/src/main/java/com/luck/server/ServerStart.java delete mode 100644 netty-proxy-server/src/main/java/com/luck/server/VisitorHandler.java delete mode 100644 netty-proxy-server/src/main/java/com/luck/server/VisitorSocket.java delete mode 100644 netty-proxy-server/src/main/java/com/luck/server/controller/ServerController.java delete mode 100644 netty-proxy-server/src/main/resources/application.yml diff --git a/CloudClientInternalNetworkPenetration.README.md b/CloudClientInternalNetworkPenetration.README.md new file mode 100644 index 0000000..2b17bb5 --- /dev/null +++ b/CloudClientInternalNetworkPenetration.README.md @@ -0,0 +1,92 @@ +### 内网穿透使用 + +#### 模块说明 + +| 模块 | 所属层级 | 描述 | 端口 | +|----------------------------------------------------------------------------------------|------|------------------------|----------------------------------------------------------------| +| [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 | + +#### 功能 + + 1.将局域网IP映射到公网IP + 2. 支持tcp、http映射 + +#### 使用 + +```text +客户端配置信息 +``` + +```yaml +spring: + middleground: + netty: + inet-host: 127.0.0.1 # 服务端地址 + inet-port: 7001 #服务端端口 + client-id: local # 客户端ID +``` + +```text +服务端配置客户端映射地址 +数据库表【internal_network_penetration_mapping】 添加数据 +``` + +| 客户端ID | 客户端真实地址 | 客户端真实端口 | 创建时间 | id | 是否删除 | 更新时间 | 访客端口 | 描述 | +|--------------|----------------|---------|------|----|------|------|-------|------------------------------------------------------------| +| local | 127.0.0.1 | 18080 | null | 1 | 0 | null | 19080 | 访客通过 --> 19080 --> 访问 --> 客户端 local本地的 18080 | +| local | 127.0.0.1 | 28080 | null | 2 | 0 | null | 29080 | 访客通过 --> 29080 --> 访问 --> 客户端 local本地的 28080 | +| local | 127.0.0.1 | 3306 | null | 3 | 0 | null | 4306 | 访客通过 --> 4306 --> 访问 --> 客户端 local本地的 3306 | +| local | 192.168.17.185 | 80 | null | 4 | 0 | null | 30080 | 访客通过 --> 30080 --> 访问 --> 客户端 local局域网内192.168.17.185的 80 | +| middleground | web-nginx | 80 | null | 5 | 0 | null | 31570 | 访客通过 --> 31570 --> 访问 --> 客户端 local局域网内web-nginx的 80 | + + + +#### 部署 + +##### 云端部署 + +```text +云端部署:内网穿透服务端 +如果云端需要部署云上暂存+内网穿透功能:需要部署 内网穿透服务端、暂存服务、内网穿透客户端、云上离线网关 +``` + +| 模块 | 说明 | 部署内网穿透必须 | 部署内网穿透+云上暂存必须 | +|----------------------------------------------------------------------------------------|------------|----------|---------------| +| [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) | 云下暂存网关 | ✖️ | ✖️ | + +##### 云网关部署 + +```text +云网关部署内网穿透客户端 +``` + +| 模块 | 说明 | 部署内网穿透必须 | 部署内网穿透+云上暂存必须 | +|----------------------------------------------------------------------------------------|------------|----------|---------------| +| [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) | 云下暂存网关 | ✖️ | ✖️ | + +##### 独立租户部署 + +```text +拥有内网穿透能力:需要部署内网穿透客户端 +内网穿透+离线暂存能力: 需要部署内网穿透客户端、离线网关、离线暂存服务 +``` + +| 模块 | 说明 | 部署内网穿透必须 | 部署内网穿透+云上暂存必须 | +|----------------------------------------------------------------------------------------|------------|----------|---------------| +| [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) | 云下暂存网关 | ✖️ | ☑️ | + + diff --git a/CloudClientInternalNetworkPenetration1.0-.png b/CloudClientInternalNetworkPenetration1.0-.png new file mode 100644 index 0000000000000000000000000000000000000000..dd2d74dd28046dc50222da38c93c2fa9e666d4af GIT binary patch literal 44110 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 [客户端真实代理通道]: 转发二进制请求到真实服务通道 + } + node “客户端真实服务”{ + component [客户端需要代理的真实服务A]{ + [客户端真实通道读数据] + [客户端真实通道返回数据] + } + } + +' [客户端真实代理通道] ...right...> [客户端真实服务]: 发送真实二进制请求到真实服务 + +} +package "服务端"{ + node "Netty服务端" { + + component [Netty服务端通道] { + component [服务端心跳通道]{ + + } + component [服务端代理通信通道]{ + [服务端通信通道读数据] + [服务端通信通道返回数据] + } + } + + component [Netty服务端绑定访客端口] { + component [服务端访客真实通道]{ + [服务端访客真实通道读数据] + [服务端访客真实通道返回数据] + } + } + + } + +} + + + + [服务端心跳通道] <----> [客户端心跳通道]:长连接channel + + + [访客] ..> [服务端访客真实通道读数据]: 访客访问数据 + [服务端访客真实通道读数据] ...> [服务端通信通道读数据]: 服务端访客数据转发到通信通道 + [服务端通信通道读数据] ..down..> [客户端通信通道读数据]: 服务端通信将数据转发到客户端通信通道 + [客户端通信通道读数据] ..down..> [客户端真实通道读数据]: 客户端通信通道将数据转发道客户端端真实代理通道 + [客户端真实通道读数据] ..left..> [客户端真实通道返回数据]: 处理数据。。。 + [客户端真实通道返回数据] ..up..> [客户端通信通道返回数据]: 客户端真实服务返回数据 + [客户端通信通道返回数据] ..up..> [服务端通信通道返回数据]: 将客户端返回的数据发送给访客真实通道 + [服务端通信通道返回数据] ..up..> [服务端访客真实通道返回数据]: 返回数据 + + + + +@enduml \ No newline at end of file diff --git a/k8s-on.yaml b/k8s-on.yaml new file mode 100644 index 0000000..cd5305c --- /dev/null +++ b/k8s-on.yaml @@ -0,0 +1,152 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + 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 + namespace: middleground-management +spec: + progressDeadlineSeconds: 600 + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + k8s.kuboard.cn/layer: monitor + k8s.kuboard.cn/name: middleground-on-cloud-heartbeat-server + strategy: + rollingUpdate: + maxSurge: 25% + maxUnavailable: 25% + type: RollingUpdate + template: + metadata: + labels: + k8s.kuboard.cn/layer: monitor + k8s.kuboard.cn/name: middleground-on-cloud-heartbeat-server + spec: + containers: + - envFrom: + - configMapRef: + name: common-cnf + image: >- + docker-registry.laihui.com/middleground/middleground-on-cloud-heartbeat-server:master_latest + imagePullPolicy: Always + name: middleground-on-cloud-heartbeat-server + resources: + limits: + memory: 512Mi + requests: + memory: 512Mi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + 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 + namespace: middleground-management +spec: + progressDeadlineSeconds: 600 + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + k8s.kuboard.cn/layer: gateway + k8s.kuboard.cn/name: middleground-on-cloud-central-gateway + strategy: + rollingUpdate: + maxSurge: 25% + maxUnavailable: 25% + type: RollingUpdate + template: + metadata: + labels: + k8s.kuboard.cn/layer: gateway + k8s.kuboard.cn/name: middleground-on-cloud-central-gateway + spec: + containers: + - envFrom: + - configMapRef: + name: common-cnf + image: >- + docker-registry.laihui.com/middleground/middleground-on-cloud-central-gateway:master_latest + imagePullPolicy: Always + name: middleground-on-cloud-central-gateway + resources: + limits: + memory: 384Mi + requests: + memory: 384Mi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + k8s.kuboard.cn/displayName: 【云上云下】暂存服务(新) + labels: + k8s.kuboard.cn/layer: svc + k8s.kuboard.cn/name: middleground-cloud-staging-provider + name: middleground-cloud-staging-provider + namespace: middleground-management +spec: + progressDeadlineSeconds: 600 + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + k8s.kuboard.cn/layer: svc + k8s.kuboard.cn/name: middleground-cloud-staging-provider + strategy: + rollingUpdate: + maxSurge: 25% + maxUnavailable: 25% + type: RollingUpdate + template: + metadata: + labels: + k8s.kuboard.cn/layer: svc + k8s.kuboard.cn/name: middleground-cloud-staging-provider + spec: + containers: + - envFrom: + - configMapRef: + name: common-cnf + image: >- + docker-registry.laihui.com/middleground/middleground-cloud-staging-provider:master_latest + imagePullPolicy: Always + name: middleground-cloud-staging-provider + resources: + limits: + memory: 384Mi + requests: + memory: 384Mi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 diff --git a/k8s-under.yaml b/k8s-under.yaml new file mode 100644 index 0000000..432e4dc --- /dev/null +++ b/k8s-under.yaml @@ -0,0 +1,154 @@ + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + 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 + namespace: middleground-tenant-share +spec: + progressDeadlineSeconds: 600 + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + k8s.kuboard.cn/layer: monitor + k8s.kuboard.cn/name: middleground-under-cloud-heartbeat-client + strategy: + rollingUpdate: + maxSurge: 25% + maxUnavailable: 25% + type: RollingUpdate + template: + metadata: + labels: + k8s.kuboard.cn/layer: monitor + k8s.kuboard.cn/name: middleground-under-cloud-heartbeat-client + spec: + containers: + - envFrom: + - configMapRef: + name: common-cnf + image: >- + docker-registry.laihui.com/middleground/middleground-under-cloud-heartbeat-client:master_latest + imagePullPolicy: Always + name: middleground-under-cloud-heartbeat-client + resources: + limits: + memory: 384Mi + requests: + memory: 384Mi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + 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 + namespace: middleground-tenant-share +spec: + progressDeadlineSeconds: 600 + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + k8s.kuboard.cn/layer: gateway + k8s.kuboard.cn/name: middleground-under-cloud-central-gateway + strategy: + rollingUpdate: + maxSurge: 25% + maxUnavailable: 25% + type: RollingUpdate + template: + metadata: + labels: + k8s.kuboard.cn/layer: gateway + k8s.kuboard.cn/name: middleground-under-cloud-central-gateway + spec: + containers: + - envFrom: + - configMapRef: + name: common-cnf + image: >- + docker-registry.laihui.com/middleground/middleground-under-cloud-central-gateway:master_latest + imagePullPolicy: Always + name: middleground-under-cloud-central-gateway + resources: + limits: + memory: 384Mi + requests: + memory: 384Mi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + k8s.kuboard.cn/displayName: 【云上云下】云下暂存服务(新) + labels: + k8s.kuboard.cn/layer: svc + k8s.kuboard.cn/name: middleground-cloud-staging-provider + name: middleground-cloud-staging-provider + namespace: middleground-tenant-share +spec: + progressDeadlineSeconds: 600 + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + k8s.kuboard.cn/layer: svc + k8s.kuboard.cn/name: middleground-cloud-staging-provider + strategy: + rollingUpdate: + maxSurge: 25% + maxUnavailable: 25% + type: RollingUpdate + template: + metadata: + labels: + k8s.kuboard.cn/layer: svc + k8s.kuboard.cn/name: middleground-cloud-staging-provider + spec: + containers: + - envFrom: + - configMapRef: + name: common-cnf + image: >- + docker-registry.laihui.com/middleground/middleground-cloud-staging-provider:master_latest + imagePullPolicy: Always + name: middleground-cloud-staging-provider + resources: + limits: + memory: 384Mi + requests: + memory: 384Mi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 + diff --git a/lazy-cloud-heartbeat-client/Native-Dockerfile b/lazy-cloud-heartbeat-client/Native-Dockerfile new file mode 100644 index 0000000..9264610 --- /dev/null +++ b/lazy-cloud-heartbeat-client/Native-Dockerfile @@ -0,0 +1,16 @@ +FROM alpine + +MAINTAINER wujiawei <1207537021@qq.com> + +RUN echo "Asia/Shanghai" > /etc/timezone + + +COPY target/middleground-under-cloud-heartbeat-client /native-app + +ENTRYPOINT ["/bin/sh" ,"-c", "exec ./native-app"] + + + + + + diff --git a/lazy-cloud-heartbeat-client/README.md b/lazy-cloud-heartbeat-client/README.md new file mode 100644 index 0000000..2521065 --- /dev/null +++ b/lazy-cloud-heartbeat-client/README.md @@ -0,0 +1,14 @@ + + +#### 构建native 镜像 +```shell +mvn clean compile +mvn spring-boot:process-aot -Pnative + +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 +``` \ No newline at end of file diff --git a/lazy-cloud-heartbeat-client/pom.xml b/lazy-cloud-heartbeat-client/pom.xml new file mode 100644 index 0000000..00a9fb6 --- /dev/null +++ b/lazy-cloud-heartbeat-client/pom.xml @@ -0,0 +1,56 @@ + + + + top.wu2020 + lazy-cloud-network + 1.2.1-JDK17-SNAPSHOT + + 4.0.0 + + lazy-cloud-heartbeat-client + 云下心跳客户端 + + + 17 + 17 + + + + + + top.wu2020 + lazy-cloud-heartbeat-common + 1.2.1-JDK17-SNAPSHOT + + + com.alibaba + fastjson + 2.0.33 + compile + + + top.wu2020 + wu-database-lazy-plus-starter + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + org.apache.maven.plugins + maven-deploy-plugin + + true + + + + + + \ No newline at end of file diff --git a/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/MiddlegroundUnderCloudHeartbeatClient.java b/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/MiddlegroundUnderCloudHeartbeatClient.java new file mode 100644 index 0000000..ee095a0 --- /dev/null +++ b/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/MiddlegroundUnderCloudHeartbeatClient.java @@ -0,0 +1,15 @@ +package wu.framework.middleground.under.cloud.heartbeat.client; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * 云上云下-云下心跳服务器 + */ + +@SpringBootApplication +public class MiddlegroundUnderCloudHeartbeatClient { + public static void main(String[] args) { + SpringApplication.run(MiddlegroundUnderCloudHeartbeatClient.class,args); + } +} diff --git a/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/application/ClientNettyConfigApplication.java b/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/application/ClientNettyConfigApplication.java new file mode 100644 index 0000000..66f0fc5 --- /dev/null +++ b/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/application/ClientNettyConfigApplication.java @@ -0,0 +1,32 @@ +package wu.framework.middleground.under.cloud.heartbeat.client.application; + +/** + * 云下心跳客户端操作nacos 配置 + */ +public interface ClientNettyConfigApplication { + + + + /** + * 推送客户端在线 + */ + void clientOnLine(String clientId); + + /** + * 推送客户端离线 + */ + void clientOffLine(String clientId); + + /** + * 暂存开启 + * @param clientId 租户ID + */ + void stagingOpen(String clientId); + + + /** + * 暂存关闭 + * @param clientId 客户端ID 对应的租户 + */ + void stagingClose(String clientId); +} diff --git a/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/application/impl/ClientNettyConfigApplicationImpl.java b/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/application/impl/ClientNettyConfigApplicationImpl.java new file mode 100644 index 0000000..c97100a --- /dev/null +++ b/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/application/impl/ClientNettyConfigApplicationImpl.java @@ -0,0 +1,82 @@ +package wu.framework.middleground.under.cloud.heartbeat.client.application.impl; + + +import wu.framework.middleground.under.cloud.heartbeat.client.application.ClientNettyConfigApplication; +import com.wu.framework.database.lazy.web.plus.stereotype.LazyApplication; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@LazyApplication +public class ClientNettyConfigApplicationImpl implements ClientNettyConfigApplication { +// private final StringRedisTemplate stringRedisTemplate; +// private final RedisProviderTemplate redisProviderTemplate; +// +// public ClientNettyConfigApplicationImpl(StringRedisTemplate stringRedisTemplate, RedisProviderTemplate redisProviderTemplate) { +// this.stringRedisTemplate = stringRedisTemplate; +// this.redisProviderTemplate = redisProviderTemplate; +// } + + + /** + * 推送客户端在线 + */ + @Override + public void clientOnLine(String clientId) { +// // 获取当前客户端ID +// if (ObjectUtils.isEmpty(clientId)) { +// clientId = stringRedisTemplate.opsForValue().get(ClientConfigKeyUtils.CLIENT_ID_KEY); +// } +// String clientStatusKey = ClientConfigKeyUtils.getClientStatusKey(clientId); +// // 如果可以已经在线状态不推送 +// stringRedisTemplate.opsForValue().set(clientStatusKey, NettyClientStatus.ON_LINE.name()); +// ClientOnLineState clientOnLineState = new ClientOnLineState(); +// clientOnLineState.setClientId(clientId); +// clientOnLineState.setOnLineState(NettyClientStatus.ON_LINE.name()); +// // 暂存扫描触发 +// redisProviderTemplate.send(RedisChannelConstant.REDIS_CLIENT_ONLINE_OR_OFFLINE_CHANNEL,clientOnLineState); + + } + + /** + * 推送客户端离线 + */ + @Override + public void clientOffLine(String clientId) { +// if (ObjectUtils.isEmpty(clientId)) { +// clientId = stringRedisTemplate.opsForValue().get(ClientConfigKeyUtils.CLIENT_ID_KEY); +// } +// String clientStatusKey = ClientConfigKeyUtils.getClientStatusKey(clientId); +// // 离线状态 +// stringRedisTemplate.opsForValue().set(clientStatusKey, NettyClientStatus.OFF_LINE.name()); +// // 暂存状态 +// stagingOpen(clientId); +// // 暂存扫描触发 +// ClientOnLineState clientOnLineState = new ClientOnLineState(); +// clientOnLineState.setClientId(clientId); +// clientOnLineState.setOnLineState(NettyClientStatus.OFF_LINE.name()); +// redisProviderTemplate.send(RedisChannelConstant.REDIS_CLIENT_ONLINE_OR_OFFLINE_CHANNEL,clientOnLineState); + } + + @Override + public void stagingOpen(String clientId) { +// String stagingStatusKey = StagingConfigKeyConstant.getStagingStatusKey(clientId); +// stringRedisTemplate.opsForValue().set(stagingStatusKey, StagingStatus.OPENED.name()); + + } + + /** + * 暂存关闭 + * + * @param clientId 租户ID + */ + @Override + public void stagingClose(String clientId) { +// if (clientId == null) { +// clientId = stringRedisTemplate.opsForValue().get(ClientConfigKeyUtils.CLIENT_ID_KEY); +// } +// String stagingStatusKey = StagingConfigKeyConstant.getStagingStatusKey(clientId); +// stringRedisTemplate.opsForValue().set(stagingStatusKey, StagingStatus.CLOSED.name()); + + } + +} diff --git a/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/advanced/ClientChannelHeartbeatTypeAdvanced.java b/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/advanced/ClientChannelHeartbeatTypeAdvanced.java new file mode 100644 index 0000000..2e9dc84 --- /dev/null +++ b/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/advanced/ClientChannelHeartbeatTypeAdvanced.java @@ -0,0 +1,31 @@ +package wu.framework.middleground.under.cloud.heartbeat.client.netty.advanced; + + +import wu.framework.middleground.cloud.heartbeat.common.MessageType; +import wu.framework.middleground.cloud.heartbeat.common.NettyProxyMsg; +import wu.framework.middleground.cloud.heartbeat.common.advanced.AbstractChannelHeartbeatTypeAdvanced; +import io.netty.channel.Channel; +import org.springframework.stereotype.Component; + + +/** + * 服务端 处理客户端心跳 + * TYPE_HEARTBEAT + */ +@Component +public class ClientChannelHeartbeatTypeAdvanced extends AbstractChannelHeartbeatTypeAdvanced { + + /** + * 处理当前数据 + * + * @param channel 当前通道 + * @param msg 通道数据 + */ + @Override + public void doHandler(Channel channel, NettyProxyMsg msg) { + NettyProxyMsg hb = new NettyProxyMsg(); + hb.setType(MessageType.TYPE_HEARTBEAT); +// channel.writeAndFlush(hb); + } + +} diff --git a/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/advanced/ClientDistributeSingleClientRealAutoReadConnectTypeAdvanced.java b/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/advanced/ClientDistributeSingleClientRealAutoReadConnectTypeAdvanced.java new file mode 100644 index 0000000..46ffbe2 --- /dev/null +++ b/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/advanced/ClientDistributeSingleClientRealAutoReadConnectTypeAdvanced.java @@ -0,0 +1,31 @@ +package wu.framework.middleground.under.cloud.heartbeat.client.netty.advanced; + +import wu.framework.middleground.cloud.heartbeat.common.NettyProxyMsg; +import wu.framework.middleground.cloud.heartbeat.common.NettyRealIdContext; +import wu.framework.middleground.cloud.heartbeat.common.advanced.client.AbstractDistributeSingleClientRealAutoReadConnectTypeAdvanced; +import io.netty.channel.Channel; +import io.netty.channel.ChannelOption; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +public class ClientDistributeSingleClientRealAutoReadConnectTypeAdvanced extends AbstractDistributeSingleClientRealAutoReadConnectTypeAdvanced { + /** + * 处理当前数据 + * + * @param channel 当前通道 + * @param nettyProxyMsg 通道数据 + */ + @Override + protected void doHandler(Channel channel, NettyProxyMsg nettyProxyMsg) { + // 获取访客ID + byte[] visitorId = nettyProxyMsg.getVisitorId(); + // 获取访客对应的真实代理通道 + Channel realChannel = NettyRealIdContext.getVisitor(visitorId); + if (realChannel != null) { + realChannel.config().setOption(ChannelOption.AUTO_READ, true); + } + + } +} diff --git a/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/advanced/ClientDistributeSingleClientRealCloseVisitorTypeAdvanced.java b/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/advanced/ClientDistributeSingleClientRealCloseVisitorTypeAdvanced.java new file mode 100644 index 0000000..c7182d6 --- /dev/null +++ b/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/advanced/ClientDistributeSingleClientRealCloseVisitorTypeAdvanced.java @@ -0,0 +1,28 @@ +package wu.framework.middleground.under.cloud.heartbeat.client.netty.advanced; + +import wu.framework.middleground.cloud.heartbeat.common.NettyCommunicationIdContext; +import wu.framework.middleground.cloud.heartbeat.common.NettyProxyMsg; +import wu.framework.middleground.cloud.heartbeat.common.NettyRealIdContext; +import wu.framework.middleground.cloud.heartbeat.common.advanced.client.AbstractDistributeSingleClientRealCloseVisitorTypeAdvanced; +import io.netty.channel.Channel; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +public class ClientDistributeSingleClientRealCloseVisitorTypeAdvanced extends AbstractDistributeSingleClientRealCloseVisitorTypeAdvanced { + /** + * 处理当前数据 + * + * @param channel 当前通道 + * @param nettyProxyMsg 通道数据 + */ + @Override + protected void doHandler(Channel channel, NettyProxyMsg nettyProxyMsg) { + // 关闭代理的真实通道 + byte[] visitorId = nettyProxyMsg.getVisitorId(); + NettyRealIdContext.clear(visitorId); + NettyCommunicationIdContext.clear(visitorId); + + } +} diff --git a/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/advanced/ClientDistributeSingleClientRealConnectTypeAdvanced.java b/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/advanced/ClientDistributeSingleClientRealConnectTypeAdvanced.java new file mode 100644 index 0000000..24f43c2 --- /dev/null +++ b/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/advanced/ClientDistributeSingleClientRealConnectTypeAdvanced.java @@ -0,0 +1,56 @@ +package wu.framework.middleground.under.cloud.heartbeat.client.netty.advanced; + +import wu.framework.middleground.cloud.heartbeat.common.InternalNetworkPenetrationRealClient; +import wu.framework.middleground.cloud.heartbeat.common.NettyProxyMsg; +import wu.framework.middleground.cloud.heartbeat.common.advanced.ChannelTypeAdvanced; +import wu.framework.middleground.cloud.heartbeat.common.advanced.client.AbstractDistributeSingleClientRealConnectTypeAdvanced; +import wu.framework.middleground.under.cloud.heartbeat.client.netty.config.NettyServerProperties; +import wu.framework.middleground.under.cloud.heartbeat.client.netty.socket.NettyClientRealSocket; +import io.netty.channel.Channel; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * 客户端创建真实代理同奥 + */ +@Slf4j +@Component +public class ClientDistributeSingleClientRealConnectTypeAdvanced extends AbstractDistributeSingleClientRealConnectTypeAdvanced { + + private final NettyServerProperties nettyServerProperties;// 服务端地址信息 + private final List channelTypeAdvancedList; + + public ClientDistributeSingleClientRealConnectTypeAdvanced(NettyServerProperties nettyServerProperties, List channelTypeAdvancedList) { + this.nettyServerProperties = nettyServerProperties; + this.channelTypeAdvancedList = channelTypeAdvancedList; + } + + /** + * 处理当前数据 + * + * @param channel 当前通道 + * @param msg 通道数据 + */ + @Override + protected void doHandler(Channel channel, NettyProxyMsg msg) { + // 创建真实端口监听 + byte[] clientIdBytes = msg.getClientId(); + byte[] visitorPort = msg.getVisitorPort(); + byte[] clientTargetIp = msg.getClientTargetIp(); + byte[] clientTargetPort = msg.getClientTargetPort(); + byte[] visitorIdBytes = msg.getVisitorId(); + InternalNetworkPenetrationRealClient internalNetworkPenetrationRealClient = new InternalNetworkPenetrationRealClient(); + internalNetworkPenetrationRealClient.setClientId(new String(clientIdBytes)); + internalNetworkPenetrationRealClient.setVisitorPort(Integer.valueOf(new String(visitorPort))); + internalNetworkPenetrationRealClient.setClientTargetIp(new String( clientTargetIp)); + internalNetworkPenetrationRealClient.setClientTargetPort(Integer.valueOf(new String( clientTargetPort))); + String visitorId=new String(visitorIdBytes);// 访客ID + internalNetworkPenetrationRealClient.setVisitorId(visitorId); + + // 绑定真实服务端口 + NettyClientRealSocket.buildRealServer(internalNetworkPenetrationRealClient,nettyServerProperties,channelTypeAdvancedList ); + + } +} diff --git a/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/advanced/ClientReportChannelTransferTypeAdvanced.java b/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/advanced/ClientReportChannelTransferTypeAdvanced.java new file mode 100644 index 0000000..ae51dac --- /dev/null +++ b/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/advanced/ClientReportChannelTransferTypeAdvanced.java @@ -0,0 +1,59 @@ +package wu.framework.middleground.under.cloud.heartbeat.client.netty.advanced; + + +import wu.framework.middleground.cloud.heartbeat.common.NettyProxyMsg; +import wu.framework.middleground.cloud.heartbeat.common.NettyRealIdContext; +import wu.framework.middleground.cloud.heartbeat.common.advanced.client.AbstractDistributeChannelTransferTypeAdvanced; +import wu.framework.middleground.cloud.heartbeat.common.enums.MessageTypeEnums; +import wu.framework.middleground.under.cloud.heartbeat.client.netty.config.NettyServerProperties; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + + +/** + * 服务端处理客户端数据传输 + * @see MessageTypeEnums#DISTRIBUTE_CLIENT_TRANSFER + */ +@Slf4j +@Component +public class ClientReportChannelTransferTypeAdvanced extends AbstractDistributeChannelTransferTypeAdvanced { + + private final NettyServerProperties nettyServerProperties; + + public ClientReportChannelTransferTypeAdvanced(NettyServerProperties nettyServerProperties) { + this.nettyServerProperties = nettyServerProperties; + } + + /** + * 处理当前数据 + * + * @param channel 当前通道 + * @param nettyProxyMsg 通道数据 + */ + @Override + public void doHandler(Channel channel, NettyProxyMsg nettyProxyMsg) { + log.debug("接收到服务端需要内网穿透的数据" + nettyProxyMsg); + String clientId = nettyServerProperties.getClientId(); + byte[] visitorPort = nettyProxyMsg.getVisitorPort(); + byte[] clientTargetIp = nettyProxyMsg.getClientTargetIp(); + byte[] clientTargetPort = nettyProxyMsg.getClientTargetPort(); + byte[] visitorId = nettyProxyMsg.getVisitorId(); + // 真实服务通道 + Channel realChannel = NettyRealIdContext.getVisitor(new String(visitorId)); + if (realChannel == null) { + log.error("无法获取访客:{} 真实服务", new String(visitorId)); + return; + } + + + // 把数据转到真实服务 + ByteBuf buf = channel.config().getAllocator().buffer(nettyProxyMsg.getData().length); + buf.writeBytes(nettyProxyMsg.getData()); + + realChannel.writeAndFlush(buf); + + } + +} diff --git a/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/advanced/DistributeConnectSuccessNotificationTypeAdvanced.java b/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/advanced/DistributeConnectSuccessNotificationTypeAdvanced.java new file mode 100644 index 0000000..e8cd4db --- /dev/null +++ b/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/advanced/DistributeConnectSuccessNotificationTypeAdvanced.java @@ -0,0 +1,55 @@ +package wu.framework.middleground.under.cloud.heartbeat.client.netty.advanced; + +import com.alibaba.fastjson.JSONObject; +import wu.framework.middleground.cloud.heartbeat.common.ChannelContext; +import wu.framework.middleground.cloud.heartbeat.common.NettyProxyMsg; +import wu.framework.middleground.cloud.heartbeat.common.advanced.client.AbstractDistributeConnectSuccessNotificationTypeAdvanced; +import wu.framework.middleground.cloud.heartbeat.common.utils.ChannelAttributeKeyUtils; +import wu.framework.middleground.under.cloud.heartbeat.client.application.ClientNettyConfigApplication; +import wu.framework.middleground.under.cloud.heartbeat.client.netty.config.NettyServerProperties; +import io.netty.channel.Channel; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.nio.charset.StandardCharsets; +import java.util.List; + +/** + * 客户端连接成功通知 + */ +@Slf4j +@Component +public class DistributeConnectSuccessNotificationTypeAdvanced extends AbstractDistributeConnectSuccessNotificationTypeAdvanced { + + private final ClientNettyConfigApplication clientNettyConfigApplication; + private final NettyServerProperties nettyServerProperties; + + public DistributeConnectSuccessNotificationTypeAdvanced(ClientNettyConfigApplication clientNettyConfigApplication, NettyServerProperties nettyServerProperties) { + this.clientNettyConfigApplication = clientNettyConfigApplication; + this.nettyServerProperties = nettyServerProperties; + } + + /** + * 处理当前数据 + * + * @param channel 当前通道 + * @param msg 通道数据 + */ + @Override + protected void doHandler(Channel channel, NettyProxyMsg msg) { + log.warn("客户端ID:{},客户端:{}连接成功", new String(msg.getClientId()), new String(msg.getData())); + + // 缓存当前通道 + String clientId = nettyServerProperties.getClientId(); + NettyProxyMsg nettyMsg = new NettyProxyMsg(); + nettyMsg.setClientId(clientId.getBytes(StandardCharsets.UTF_8)); + ChannelContext.push(channel, nettyMsg); + ChannelAttributeKeyUtils.buildClientId(channel,clientId); + // 存储其他客户端状态 + List clientIdList = JSONObject.parseArray(new String(msg.getData()), String.class); + for (String tenantId : clientIdList) { + clientNettyConfigApplication.clientOnLine(tenantId); + } + + } +} diff --git a/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/advanced/DistributeDisconnectTypeAdvanced.java b/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/advanced/DistributeDisconnectTypeAdvanced.java new file mode 100644 index 0000000..8be2ca9 --- /dev/null +++ b/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/advanced/DistributeDisconnectTypeAdvanced.java @@ -0,0 +1,44 @@ +package wu.framework.middleground.under.cloud.heartbeat.client.netty.advanced; + + +import wu.framework.middleground.cloud.heartbeat.common.NettyProxyMsg; +import wu.framework.middleground.cloud.heartbeat.common.advanced.client.AbstractDistributeDisconnectTypeAdvanced; +import wu.framework.middleground.under.cloud.heartbeat.client.application.ClientNettyConfigApplication; +import io.netty.channel.Channel; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + + +/** + * 服务端处理客户端断开连接处理 + * TYPE_DISCONNECT + */ +@Slf4j +@Component +public class DistributeDisconnectTypeAdvanced extends AbstractDistributeDisconnectTypeAdvanced { + + + private final ClientNettyConfigApplication clientNettyConfigApplication; + + public DistributeDisconnectTypeAdvanced(ClientNettyConfigApplication clientNettyConfigApplication) { + this.clientNettyConfigApplication = clientNettyConfigApplication; + } + + /** + * 处理当前数据 + * + * @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("客户端:{}下线",tenantId); + clientNettyConfigApplication.clientOffLine(tenantId); + + } + +} diff --git a/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/advanced/DistributeStagingClosedTypeAdvanced.java b/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/advanced/DistributeStagingClosedTypeAdvanced.java new file mode 100644 index 0000000..f57ea0f --- /dev/null +++ b/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/advanced/DistributeStagingClosedTypeAdvanced.java @@ -0,0 +1,34 @@ +package wu.framework.middleground.under.cloud.heartbeat.client.netty.advanced; + +import wu.framework.middleground.cloud.heartbeat.common.NettyProxyMsg; +import wu.framework.middleground.cloud.heartbeat.common.advanced.client.AbstractDistributeStagingClosedTypeAdvanced; +import io.netty.channel.Channel; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * 服务端下发暂存关闭消息处理 + */ +@Slf4j +@Component +public class DistributeStagingClosedTypeAdvanced extends AbstractDistributeStagingClosedTypeAdvanced { + + + + + /** + * 处理当前数据 + * + * @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()); + + } +} diff --git a/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/advanced/DistributeStagingOpenedTypeAdvanced.java b/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/advanced/DistributeStagingOpenedTypeAdvanced.java new file mode 100644 index 0000000..25fe781 --- /dev/null +++ b/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/advanced/DistributeStagingOpenedTypeAdvanced.java @@ -0,0 +1,37 @@ +package wu.framework.middleground.under.cloud.heartbeat.client.netty.advanced; + +import wu.framework.middleground.cloud.heartbeat.common.NettyProxyMsg; +import wu.framework.middleground.cloud.heartbeat.common.advanced.client.AbstractDistributeStagingOpenedTypeAdvanced; + +import io.netty.channel.Channel; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * 服务端下发暂存开启消息处理 + */ +@Slf4j +@Component +public class DistributeStagingOpenedTypeAdvanced extends AbstractDistributeStagingOpenedTypeAdvanced{ + + + + public DistributeStagingOpenedTypeAdvanced() { + + } + + /** + * 处理当前数据 + * + * @param channel 当前通道 + * @param msg 通道数据 + */ + @Override + protected void doHandler(Channel channel, NettyProxyMsg msg) { + String clientId = new String(msg.getClientId()); + log.info("客户端:{}离线暂存开启", new String(msg.getClientId())); + // 修改redis 客户端暂存状态 +// String stagingStatusKey = StagingConfigKeyConstant.getStagingStatusKey(clientId); +// stringRedisTemplate.opsForValue().set(stagingStatusKey, StagingStatus.OPENED.name()); + } +} diff --git a/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/config/AutoConfiguration.java b/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/config/AutoConfiguration.java new file mode 100644 index 0000000..9433166 --- /dev/null +++ b/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/config/AutoConfiguration.java @@ -0,0 +1,82 @@ +package wu.framework.middleground.under.cloud.heartbeat.client.netty.config; + + +import wu.framework.middleground.cloud.heartbeat.common.advanced.ChannelTypeAdvanced; +import wu.framework.middleground.under.cloud.heartbeat.client.application.ClientNettyConfigApplication; +import wu.framework.middleground.under.cloud.heartbeat.client.netty.socket.NettyClientSocket; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.autoconfigure.web.ServerProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.List; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +/** + * description 自动配置 + * + * @author 吴佳伟 + * @date 2023/09/12 18:22 + */ +@Slf4j +@Configuration +public class AutoConfiguration implements CommandLineRunner { + + private final ServerProperties serverProperties; + private final NettyServerProperties nettyServerProperties; + private final ClientNettyConfigApplication clientNettyConfigApplication; + + private final List channelTypeAdvancedList; // 处理服务端发送过来的数据类型 + + + ThreadPoolExecutor NETTY_CLIENT_EXECUTOR = new ThreadPoolExecutor(1, 1, 200, TimeUnit.MILLISECONDS, + new ArrayBlockingQueue<>(1)); + + public AutoConfiguration(ServerProperties serverProperties, + NettyServerProperties nettyServerProperties, + ClientNettyConfigApplication clientNettyConfigApplication, + List channelTypeAdvancedList) { + this.serverProperties = serverProperties; + this.nettyServerProperties = nettyServerProperties; + this.clientNettyConfigApplication = clientNettyConfigApplication; + this.channelTypeAdvancedList = channelTypeAdvancedList; + } + + + @Bean(destroyMethod = "shutdown") + public NettyClientSocket nettyServerSocket() { + String inetHost = nettyServerProperties.getInetHost(); + int inetPort = nettyServerProperties.getInetPort(); + String clientId = nettyServerProperties.getClientId(); + return new NettyClientSocket(inetHost, inetPort, clientId, clientNettyConfigApplication, channelTypeAdvancedList); + } + + /** + * @param args + * @throws Exception + */ + @Override + public void run(String... args) throws Exception { + + + String inetHost = nettyServerProperties.getInetHost(); + int inetPort = nettyServerProperties.getInetPort(); + String clientId = nettyServerProperties.getClientId(); + NettyClientSocket nettyClientSocket = new NettyClientSocket(inetHost, inetPort, clientId, clientNettyConfigApplication, channelTypeAdvancedList); + Thread thread = new Thread(() -> { + try { + nettyClientSocket.newConnect2Server(); + } catch (Exception e) { + throw new RuntimeException(e); + } + + }); + log.info("当前服务连接Netty客户端:{},Netty端口:{}", inetHost, inetPort); + NETTY_CLIENT_EXECUTOR.execute(thread); + + + } +} diff --git a/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/config/NettyServerProperties.java b/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/config/NettyServerProperties.java new file mode 100644 index 0000000..d62c95e --- /dev/null +++ b/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/config/NettyServerProperties.java @@ -0,0 +1,31 @@ +package wu.framework.middleground.under.cloud.heartbeat.client.netty.config; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +/** + * netty 客户服务端地址配置属性 + */ +@ConfigurationProperties(prefix = NettyServerProperties.PREFIX, ignoreUnknownFields = true) +@Configuration +@Data +public class NettyServerProperties { + public static final String PREFIX = "spring.middleground.netty"; + /** + * 服务端地址 + */ + private String inetHost = "127.0.0.1"; + /** + * 服务端端口 + */ + private int inetPort = 7001; + /** + * 服务端path + */ + private String inetPath = "middleground-on-cloud-heartbeat-server"; + /** + * 客户端ID + */ + private String clientId = "1024"; +} diff --git a/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/filter/NettyClientFilter.java b/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/filter/NettyClientFilter.java new file mode 100644 index 0000000..d6065d7 --- /dev/null +++ b/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/filter/NettyClientFilter.java @@ -0,0 +1,45 @@ +package wu.framework.middleground.under.cloud.heartbeat.client.netty.filter; + +import wu.framework.middleground.cloud.heartbeat.common.adapter.ChannelTypeAdapter; +import wu.framework.middleground.cloud.heartbeat.common.decoder.NettyProxyMsgDecoder; +import wu.framework.middleground.cloud.heartbeat.common.encoder.NettyProxyMsgEncoder; +import wu.framework.middleground.under.cloud.heartbeat.client.netty.handler.NettyClientHandler; +import wu.framework.middleground.under.cloud.heartbeat.client.netty.socket.NettyClientSocket; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelPipeline; +import io.netty.channel.socket.SocketChannel; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; +import io.netty.handler.timeout.IdleStateHandler; + +public class NettyClientFilter extends ChannelInitializer { + + + private final ChannelTypeAdapter channelTypeAdapter; + private final NettyClientSocket nettyClientSocket; + + public NettyClientFilter(ChannelTypeAdapter channelTypeAdapter, NettyClientSocket nettyClientSocket) { + this.channelTypeAdapter = channelTypeAdapter; + this.nettyClientSocket = nettyClientSocket; + } + + @Override + protected void initChannel(SocketChannel ch) throws Exception { + ChannelPipeline pipeline = ch.pipeline(); + + /* * 解码和编码,应和服务端一致 * */ +// pipeline.addLast(new NettyMsgDecoder(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("framer", new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter())); + //入参说明: 读超时时间、写超时时间、所有类型的超时时间、时间格式 + //因为服务端设置的超时时间是5秒,所以设置4秒 + + pipeline.addLast(new IdleStateHandler(0, 4, 0)); + pipeline.addLast("decoder", new StringDecoder()); + pipeline.addLast("encoder", new StringEncoder()); + pipeline.addLast("doHandler", new NettyClientHandler(channelTypeAdapter,nettyClientSocket)); //客户端的逻辑 + } +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/filter/NettyClientRealFilter.java b/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/filter/NettyClientRealFilter.java new file mode 100644 index 0000000..e154eee --- /dev/null +++ b/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/filter/NettyClientRealFilter.java @@ -0,0 +1,30 @@ +package wu.framework.middleground.under.cloud.heartbeat.client.netty.filter; + +import wu.framework.middleground.under.cloud.heartbeat.client.netty.handler.NettyClientRealHandler; +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; + +public class NettyClientRealFilter extends ChannelInitializer { + /** + * This method will be called once the {@link Channel} was registered. After the method returns this instance + * will be removed from the {@link ChannelPipeline} of the {@link Channel}. + * + * @param ch the {@link Channel} which was registered. + * @throws Exception is thrown if an error occurs. In that case it will be handled by + * {@link #exceptionCaught(ChannelHandlerContext, Throwable)} which will by default close + * the {@link Channel}. + */ + @Override + protected void initChannel(SocketChannel ch) throws Exception { + ChannelPipeline pipeline = ch.pipeline(); + pipeline.addLast(new NettyClientRealHandler()); +// // 解码、编码 +// 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()); + } +} diff --git a/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/filter/NettyClientVisitorRealFilter.java b/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/filter/NettyClientVisitorRealFilter.java new file mode 100644 index 0000000..7432aa3 --- /dev/null +++ b/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/filter/NettyClientVisitorRealFilter.java @@ -0,0 +1,43 @@ +package wu.framework.middleground.under.cloud.heartbeat.client.netty.filter; + +import wu.framework.middleground.cloud.heartbeat.common.adapter.ChannelTypeAdapter; +import wu.framework.middleground.cloud.heartbeat.common.decoder.NettyProxyMsgDecoder; +import wu.framework.middleground.cloud.heartbeat.common.encoder.NettMsgEncoder; +import wu.framework.middleground.cloud.heartbeat.common.encoder.NettyProxyMsgEncoder; +import wu.framework.middleground.under.cloud.heartbeat.client.netty.handler.NettyClientVisitorRealHandler; +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; + +/** + * netty 客户端连接真实服服务端访客拦截器 + */ +public class NettyClientVisitorRealFilter extends ChannelInitializer { + private final ChannelTypeAdapter channelTypeAdapter; + + public NettyClientVisitorRealFilter(ChannelTypeAdapter channelTypeAdapter) { + this.channelTypeAdapter = channelTypeAdapter; + } + + /** + * This method will be called once the {@link Channel} was registered. After the method returns this instance + * will be removed from the {@link ChannelPipeline} of the {@link Channel}. + * + * @param ch the {@link Channel} which was registered. + * @throws Exception is thrown if an error occurs. In that case it will be handled by + * {@link #exceptionCaught(ChannelHandlerContext, Throwable)} which will by default close + * the {@link Channel}. + */ + @Override + 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 NettyProxyMsgEncoder()); + pipeline.addLast(new NettyClientVisitorRealHandler(channelTypeAdapter)); + } +} diff --git a/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/handler/HeartBeatClientHandler.java b/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/handler/HeartBeatClientHandler.java new file mode 100644 index 0000000..76e76b7 --- /dev/null +++ b/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/handler/HeartBeatClientHandler.java @@ -0,0 +1,25 @@ +package wu.framework.middleground.under.cloud.heartbeat.client.netty.handler; + +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import io.netty.handler.timeout.IdleState; +import io.netty.handler.timeout.IdleStateEvent; + +import java.util.Date; + +public class HeartBeatClientHandler extends ChannelInboundHandlerAdapter { + private int lossConnectCount = 0; + + @Override + public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { + System.out.println("客户端循环心跳监测发送: " + new Date()); + if (evt instanceof IdleStateEvent) { + IdleStateEvent event = (IdleStateEvent) evt; + if (event.state() == IdleState.WRITER_IDLE) { + ctx.writeAndFlush("biubiu"); + } + + } + } + +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/handler/NettyClientHandler.java b/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/handler/NettyClientHandler.java new file mode 100644 index 0000000..f1f2915 --- /dev/null +++ b/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/handler/NettyClientHandler.java @@ -0,0 +1,120 @@ +package wu.framework.middleground.under.cloud.heartbeat.client.netty.handler; + +import wu.framework.middleground.cloud.heartbeat.common.MessageType; +import wu.framework.middleground.cloud.heartbeat.common.NettyProxyMsg; +import wu.framework.middleground.cloud.heartbeat.common.adapter.ChannelTypeAdapter; +import wu.framework.middleground.under.cloud.heartbeat.client.netty.socket.NettyClientSocket; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.EventLoop; +import io.netty.channel.SimpleChannelInboundHandler; +import io.netty.handler.timeout.IdleState; +import io.netty.handler.timeout.IdleStateEvent; +import lombok.extern.slf4j.Slf4j; + +import java.nio.charset.StandardCharsets; +import java.util.Date; +import java.util.concurrent.TimeUnit; + +/** + * description + * + * @author 吴佳伟 + * @date 2023/09/13 10:29 + */ +@Slf4j +public class NettyClientHandler extends SimpleChannelInboundHandler { + + private final ChannelTypeAdapter channelTypeAdapter; + private final NettyClientSocket nettyClientSocket; + + + public NettyClientHandler(ChannelTypeAdapter channelTypeAdapter, NettyClientSocket nettyClientSocket) { + this.channelTypeAdapter = channelTypeAdapter; + this.nettyClientSocket = nettyClientSocket; + } + + /** + * @param ctx the {@link ChannelHandlerContext} which this {@link SimpleChannelInboundHandler} + * belongs to + * @param msg the message to handle + */ + @Override + protected void channelRead0(ChannelHandlerContext ctx, NettyProxyMsg msg) { +// log.info("第" + count + "次" + ",客户端接受的消息:" + msg); +// log.info("第" + count + "次" + ",客户端接受的消息内容:" + new String(msg.getData())); +// count++; + // 接收服务端、或者是代理端的信息 + Channel channel = ctx.channel(); +// log.info("type:{},clientId:{},data:{}",msg.getType(),new String(msg.getClientId()),new String(msg.getData())); + channelTypeAdapter.handler(channel, msg); + } + + /** + * 建立连接时 + */ + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + log.info("建立连接时:" + new Date()); + ctx.fireChannelActive(); + String clientId = nettyClientSocket.getClientId(); + // 处理客户端连接成功 + Channel channel = ctx.channel(); + NettyProxyMsg nettyMsg = new NettyProxyMsg(); + nettyMsg.setType(MessageType.REPORT_CLIENT_CONNECT_SUCCESS); + nettyMsg.setClientId(clientId); + channelTypeAdapter.handler(channel, nettyMsg); + + + } + + /** + * 关闭连接时 + */ + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + log.info("关闭连接时:" + new Date()); + final EventLoop eventLoop = ctx.channel().eventLoop(); + eventLoop.schedule(() -> { + try { + nettyClientSocket.newConnect2Server(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + }, 1L, TimeUnit.SECONDS); + + super.channelInactive(ctx); + } + + /** + * 心跳请求处理 * 每4秒发送一次心跳请求; * + */ + @Override + public void userEventTriggered(ChannelHandlerContext ctx, Object obj) throws Exception { + if (obj instanceof IdleStateEvent) { + IdleStateEvent event = (IdleStateEvent) obj; + if (IdleState.WRITER_IDLE.equals(event.state())) { //如果写通道处于空闲状态,就发送心跳命令 + String clientId = nettyClientSocket.getClientId(); + NettyProxyMsg nettyMsg = new NettyProxyMsg(); + nettyMsg.setType(MessageType.TYPE_HEARTBEAT); + nettyMsg.setData(clientId.getBytes(StandardCharsets.UTF_8)); + nettyMsg.setClientId(clientId.getBytes(StandardCharsets.UTF_8)); + ctx.writeAndFlush(nettyMsg);// 发送心跳数据 + } else if (event.state() == IdleState.WRITER_IDLE) { // 如果检测到写空闲状态,关闭连接 + // 离线、暂存通知 + String clientId = nettyClientSocket.getClientId(); + Channel channel = ctx.channel(); + NettyProxyMsg nettyMsg = new NettyProxyMsg(); + nettyMsg.setType(MessageType.DISTRIBUTE_CLIENT_DISCONNECTION_NOTIFICATION); + nettyMsg.setClientId(clientId.getBytes(StandardCharsets.UTF_8)); + channelTypeAdapter.handler(channel, nettyMsg); + ctx.close(); + } + + } else { + super.userEventTriggered(ctx, obj); + } + } + + +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/handler/NettyClientRealHandler.java b/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/handler/NettyClientRealHandler.java new file mode 100644 index 0000000..f87e5e6 --- /dev/null +++ b/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/handler/NettyClientRealHandler.java @@ -0,0 +1,81 @@ +package wu.framework.middleground.under.cloud.heartbeat.client.netty.handler; + + +import wu.framework.middleground.cloud.heartbeat.common.MessageType; +import wu.framework.middleground.cloud.heartbeat.common.NettyCommunicationIdContext; +import wu.framework.middleground.cloud.heartbeat.common.NettyProxyMsg; +import wu.framework.middleground.cloud.heartbeat.common.utils.ChannelAttributeKeyUtils; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.SimpleChannelInboundHandler; +import lombok.extern.slf4j.Slf4j; + +/** + * 来自客户端 真实服务器返回的数据请求 + */ +@Slf4j +public class NettyClientRealHandler extends SimpleChannelInboundHandler { + + @Override + public void channelRead0(ChannelHandlerContext ctx, ByteBuf buf) throws Exception { + + // 客户端发送真实数据到代理了 + byte[] bytes = new byte[buf.readableBytes()]; + buf.readBytes(bytes); + log.debug("接收客户端真实服务数据:{}", new String(bytes)); + String visitorId = ChannelAttributeKeyUtils.getVisitorId(ctx.channel()); + // 访客通信通道 上报服务端代理完成 + Channel visitorChannel = NettyCommunicationIdContext.getVisitor(visitorId); + NettyProxyMsg returnMessage = new NettyProxyMsg(); + returnMessage.setType(MessageType.REPORT_CLIENT_TRANSFER); + returnMessage.setVisitorId(visitorId); + returnMessage.setData(bytes); + + visitorChannel.writeAndFlush(returnMessage); + + + } + + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + super.channelActive(ctx); + } + + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + String clientId = ChannelAttributeKeyUtils.getClientId(ctx.channel()); + String visitorId = ChannelAttributeKeyUtils.getVisitorId(ctx.channel()); + // 客户端真实通信通道 + Channel visitor = NettyCommunicationIdContext.getVisitor(visitorId); + if (visitor != null) { + // 上报关闭这个客户端的访客通道 + NettyProxyMsg closeVisitorMsg = new NettyProxyMsg(); + closeVisitorMsg.setType(MessageType.REPORT_SINGLE_CLIENT_CLOSE_VISITOR); + closeVisitorMsg.setVisitorId(visitorId); + visitor.writeAndFlush(closeVisitorMsg); + } + + super.channelInactive(ctx); + } + + @Override + public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception { +// String vid = ctx.channel().attr(Constant.VID).get(); +// if (StringUtil.isNullOrEmpty(vid)) { +// super.channelWritabilityChanged(ctx); +// return; +// } +// Channel proxyChannel = Constant.vpc.get(vid); +// if (proxyChannel != null) { +// proxyChannel.config().setOption(ChannelOption.AUTO_READ, ctx.channel().isWritable()); +// } + + super.channelWritabilityChanged(ctx); + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + super.exceptionCaught(ctx, cause); + } +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/handler/NettyClientVisitorRealHandler.java b/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/handler/NettyClientVisitorRealHandler.java new file mode 100644 index 0000000..8ac4358 --- /dev/null +++ b/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/handler/NettyClientVisitorRealHandler.java @@ -0,0 +1,63 @@ +package wu.framework.middleground.under.cloud.heartbeat.client.netty.handler; + + +import wu.framework.middleground.cloud.heartbeat.common.ChannelContext; +import wu.framework.middleground.cloud.heartbeat.common.MessageType; +import wu.framework.middleground.cloud.heartbeat.common.NettyProxyMsg; +import wu.framework.middleground.cloud.heartbeat.common.adapter.ChannelTypeAdapter; +import wu.framework.middleground.cloud.heartbeat.common.utils.ChannelAttributeKeyUtils; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.SimpleChannelInboundHandler; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class NettyClientVisitorRealHandler extends SimpleChannelInboundHandler { + private final ChannelTypeAdapter channelTypeAdapter; + + public NettyClientVisitorRealHandler(ChannelTypeAdapter channelTypeAdapter) { + this.channelTypeAdapter = channelTypeAdapter; + } + + @Override + public void channelRead0(ChannelHandlerContext ctx, NettyProxyMsg nettyProxyMsg) throws Exception { + Channel channel = ctx.channel(); + channelTypeAdapter.handler(channel, nettyProxyMsg); + + } + + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + super.channelActive(ctx); + } + + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + + String clientId = ChannelAttributeKeyUtils.getClientId(ctx.channel()); + String visitorId = ChannelAttributeKeyUtils.getVisitorId(ctx.channel()); + // 关闭访客 + ChannelContext.ClientChannel clientChannel = ChannelContext.get(clientId); + if (clientChannel != null) { + Channel channel = clientChannel.getChannel(); + // 上报关闭这个客户端的访客通道 + NettyProxyMsg closeVisitorMsg = new NettyProxyMsg(); + closeVisitorMsg.setType(MessageType.REPORT_SINGLE_CLIENT_CLOSE_VISITOR); + closeVisitorMsg.setVisitorId(visitorId); + channel.writeAndFlush(closeVisitorMsg); + } + + super.channelInactive(ctx); + } + + @Override + public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception { + + super.channelWritabilityChanged(ctx); + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + super.exceptionCaught(ctx, cause); + } +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/listener/ClientStagingOpenedOrClosedRedisListener.java b/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/listener/ClientStagingOpenedOrClosedRedisListener.java new file mode 100644 index 0000000..9338d14 --- /dev/null +++ b/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/listener/ClientStagingOpenedOrClosedRedisListener.java @@ -0,0 +1,54 @@ +package wu.framework.middleground.under.cloud.heartbeat.client.netty.listener; + + +import wu.framework.middleground.cloud.heartbeat.common.constant.RedisChannelConstant; + +import wu.framework.middleground.under.cloud.heartbeat.client.netty.config.NettyServerProperties; +import wu.framework.middleground.under.cloud.heartbeat.client.rpc.StagingNoticeApiRpc; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * 客户端暂存开启、关闭通知 + * + * @see RedisChannelConstant#REDIS_CLIENT_STAGING_OPENED_OR_CLOSED_CHANNEL + */ +@Slf4j +@Component +public class ClientStagingOpenedOrClosedRedisListener { + + private final StagingNoticeApiRpc stagingNoticeApiRpc; + private final NettyServerProperties nettyServerProperties; + + + public ClientStagingOpenedOrClosedRedisListener(StagingNoticeApiRpc stagingNoticeApiRpc, NettyServerProperties nettyServerProperties) { + this.stagingNoticeApiRpc = stagingNoticeApiRpc; + this.nettyServerProperties = nettyServerProperties; + + } + +// /** +// * 使用redis监听注解监听数据 +// * +// * @param consumerRecord 客户端暂存开启、关闭通知 +// */ +// @EasyRedisListener(topics = RedisChannelConstant.REDIS_CLIENT_STAGING_OPENED_OR_CLOSED_CHANNEL) +// public void subscription(ConsumerRecord consumerRecord, Acknowledgment acknowledgment) { +// ClientStagingRedisChannelBo payload = consumerRecord.payload(); +// String clientId = payload.getClientId(); +// // 如果客户端ID为空默认当前客户端 +// if (ObjectUtils.isEmpty(clientId)) { +// clientId = nettyServerProperties.getClientId(); +// } +// StagingStatus stagingStatus = payload.getStagingStatus(); +// log.info("客户端:【{}】暂存:【{}】通知", clientId, stagingStatus); +// +// +// if (StagingStatus.OPENED.equals(stagingStatus)) { +// stagingNoticeApiRpc.stagingOpened(clientId); +// } else if (StagingStatus.CLOSED.equals(stagingStatus)) { +// stagingNoticeApiRpc.stagingClosed(clientId); +// } +// acknowledgment.acknowledge(); +// } +} diff --git a/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/socket/NettyClientRealSocket.java b/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/socket/NettyClientRealSocket.java new file mode 100644 index 0000000..d7161e9 --- /dev/null +++ b/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/socket/NettyClientRealSocket.java @@ -0,0 +1,176 @@ +package wu.framework.middleground.under.cloud.heartbeat.client.netty.socket; + + +import wu.framework.middleground.cloud.heartbeat.common.*; +import wu.framework.middleground.cloud.heartbeat.common.adapter.ChannelTypeAdapter; +import wu.framework.middleground.cloud.heartbeat.common.advanced.ChannelTypeAdvanced; +import wu.framework.middleground.cloud.heartbeat.common.utils.ChannelAttributeKeyUtils; +import wu.framework.middleground.under.cloud.heartbeat.client.netty.config.NettyServerProperties; +import wu.framework.middleground.under.cloud.heartbeat.client.netty.filter.NettyClientRealFilter; +import wu.framework.middleground.under.cloud.heartbeat.client.netty.filter.NettyClientVisitorRealFilter; +import io.netty.bootstrap.Bootstrap; +import io.netty.channel.*; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.nio.NioSocketChannel; +import lombok.extern.slf4j.Slf4j; + +import java.util.List; +import java.util.concurrent.TimeUnit; + +/** + * 客户端连接真实服务 + */ +@Slf4j +public class NettyClientRealSocket { + static EventLoopGroup eventLoopGroup = new NioEventLoopGroup(); + + /** + * 连接真实服务 + * + * @param internalNetworkPenetrationRealClient 访客信息 + * @param nettyServerProperties 服务端地址信息 + */ + public static void buildRealServer(InternalNetworkPenetrationRealClient internalNetworkPenetrationRealClient, + NettyServerProperties nettyServerProperties, + List channelTypeAdvancedList) { + + buildNewRealServer(internalNetworkPenetrationRealClient, nettyServerProperties, channelTypeAdvancedList); + + } + + /** + * @param internalNetworkPenetrationRealClient 访客信息 + * @param nettyServerProperties 服务端地址信息 + */ + private static void buildNewRealServer(InternalNetworkPenetrationRealClient internalNetworkPenetrationRealClient, + NettyServerProperties nettyServerProperties, + List channelTypeAdvancedList) { + try { + String clientTargetIp = internalNetworkPenetrationRealClient.getClientTargetIp(); + Integer clientTargetPort = internalNetworkPenetrationRealClient.getClientTargetPort(); + Bootstrap bootstrap = new Bootstrap(); + bootstrap.group(eventLoopGroup).channel(NioSocketChannel.class) + .handler(new NettyClientRealFilter()); + bootstrap.connect(clientTargetIp, clientTargetPort).addListener((ChannelFutureListener) future -> { + if (future.isSuccess()) { + // 客户端链接真实服务成功 设置自动读写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); + // 客户端真实通道 + NettyRealIdContext.pushVisitor(realChannel, visitorId); + // 绑定访客ID到当前真实通道属性 + ChannelAttributeKeyUtils.buildVisitorId(realChannel, visitorId); + ChannelAttributeKeyUtils.buildClientId(realChannel, clientId); + // 通知服务端访客连接成功 + + + // 新建一个通道处理 + newVisitorConnect2Server(internalNetworkPenetrationRealClient, nettyServerProperties, channelTypeAdvancedList); + + // 是否等 服务端相应访客通道已经可以自动读写 +// realChannel.config().setOption(ChannelOption.AUTO_READ, true); + // 模拟发送 + String byteData = "GET /swagger-ui/index.html HTTP/1.1\n" + + "Host: 127.0.0.1:19080\n" + + "Connection: keep-alive\n" + + "Cache-Control: max-age=0\n" + + "sec-ch-ua: \"Not_A Brand\";v=\"8\", \"Chromium\";v=\"120\", \"Google Chrome\";v=\"120\"\n" + + "sec-ch-ua-mobile: ?0\n" + + "sec-ch-ua-platform: \"macOS\"\n" + + "Upgrade-Insecure-Requests: 1\n" + + "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36\n" + + "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7\n" + + "Sec-Fetch-Site: none\n" + + "Sec-Fetch-Mode: navigate\n" + + "Sec-Fetch-User: ?1\n" + + "Sec-Fetch-Dest: document\n" + + "Accept-Encoding: gzip, deflate, br\n" + + "Accept-Language: zh-CN,zh;q=0.9\n" + + "Cookie: XXL_JOB_LOGIN_IDENTITY=7b226964223a312c22757365726e616d65223a2261646d696e222c2270617373776f7264223a226531306164633339343962613539616262653536653035376632306638383365222c22726f6c65223a312c227065726d697373696f6e223a6e756c6c7d; Hm_lvt_173e771eef816c412396d2cb4fe2d632=1703040917\n"; +// ChannelContext.ClientChannel clientChannel = ChannelContext.get(String.valueOf(visitorPort).getBytes(StandardCharsets.UTF_8)); +// Channel channel = clientChannel.getChannel(); +// channel.writeAndFlush(byteData.getBytes(StandardCharsets.UTF_8)); +// future.channel().attr(Constant.VID).set(internalNetworkPenetrationRealClient); +// Constant.vrc.put(internalNetworkPenetrationRealClient, future.channel()); +// ProxySocket.connectProxyServer(internalNetworkPenetrationRealClient); + } + }); + } catch (Exception e) { + e.printStackTrace(); + } + } + + + /** + * 创建访客连接服务端 + * + * @param internalNetworkPenetrationRealClient 内网穿透信息 + * @param nettyServerProperties 服务端配置信息 + * @param channelTypeAdvancedList 处理器适配器 + * @throws InterruptedException 异常 + */ + protected static void newVisitorConnect2Server(InternalNetworkPenetrationRealClient internalNetworkPenetrationRealClient, + NettyServerProperties nettyServerProperties, + List channelTypeAdvancedList) throws InterruptedException { + Bootstrap bootstrap = new Bootstrap(); + bootstrap.group(eventLoopGroup) + .channel(NioSocketChannel.class) + .handler(new NettyClientVisitorRealFilter(new ChannelTypeAdapter(channelTypeAdvancedList))) + ; + + String inetHost = nettyServerProperties.getInetHost(); + int inetPort = nettyServerProperties.getInetPort(); + String clientId = nettyServerProperties.getClientId(); + + + String visitorId = internalNetworkPenetrationRealClient.getVisitorId(); + Integer visitorPort = internalNetworkPenetrationRealClient.getVisitorPort(); + String clientTargetIp = internalNetworkPenetrationRealClient.getClientTargetIp(); + Integer clientTargetPort = internalNetworkPenetrationRealClient.getClientTargetPort(); + + log.info("客户端新建访客通道 连接服务端IP:{},连接服务端端口:{}", inetHost, inetPort); + ChannelFuture future = bootstrap.connect(inetHost, inetPort); + + log.info("使用的租户ID:" + clientId); + future.addListener((ChannelFutureListener) futureListener -> { + Channel channel = futureListener.channel(); + if (futureListener.isSuccess()) { + + NettyProxyMsg myMsg = new NettyProxyMsg(); + myMsg.setType(MessageType.REPORT_SINGLE_CLIENT_REAL_CONNECT); + myMsg.setClientId(clientId); + myMsg.setVisitorPort(visitorPort); + myMsg.setClientTargetIp(clientTargetIp); + myMsg.setClientTargetPort(clientTargetPort); + + myMsg.setVisitorId(visitorId); + channel.writeAndFlush(myMsg); + // 绑定客户端真实通信通道 + NettyCommunicationIdContext.pushVisitor(channel,visitorId); + ChannelAttributeKeyUtils.buildVisitorId(channel, visitorId); + ChannelAttributeKeyUtils.buildClientId(channel, clientId); + // 客户端真实通道自动读写打开 + Channel visitor = NettyRealIdContext.getVisitor(visitorId); + visitor.config().setOption(ChannelOption.AUTO_READ, true); + + + } else { + log.info("每隔2s重连...."); + // 离线 + channel.eventLoop().schedule(() -> { + try { + newVisitorConnect2Server(internalNetworkPenetrationRealClient, nettyServerProperties, channelTypeAdvancedList); + } catch (InterruptedException e) { + e.printStackTrace(); + } + }, 2, TimeUnit.SECONDS); + } + }); + } +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/socket/NettyClientSocket.java b/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/socket/NettyClientSocket.java new file mode 100644 index 0000000..7b7f1a4 --- /dev/null +++ b/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/netty/socket/NettyClientSocket.java @@ -0,0 +1,114 @@ +package wu.framework.middleground.under.cloud.heartbeat.client.netty.socket; + + +import wu.framework.middleground.cloud.heartbeat.common.MessageType; +import wu.framework.middleground.cloud.heartbeat.common.NettyProxyMsg; +import wu.framework.middleground.cloud.heartbeat.common.adapter.ChannelTypeAdapter; +import wu.framework.middleground.cloud.heartbeat.common.advanced.ChannelTypeAdvanced; +import wu.framework.middleground.cloud.heartbeat.common.utils.ChannelAttributeKeyUtils; +import wu.framework.middleground.under.cloud.heartbeat.client.application.ClientNettyConfigApplication; +import wu.framework.middleground.under.cloud.heartbeat.client.netty.filter.NettyClientFilter; +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 java.util.List; +import java.util.concurrent.TimeUnit; + +/** + * 客户端连接服务端 + */ +@Slf4j +public class NettyClientSocket { + /** + * 服务端host + */ + private final String inetHost; + /** + * 服务端端口 + */ + private final int inetPort; + /** + * 当前客户端id + */ + @Getter + private final String clientId; + /** + * nacos配置信息处理应用 + */ + @Getter + private final ClientNettyConfigApplication clientNettyConfigApplication; + + private final List channelTypeAdvancedList; // 处理服务端发送过来的数据类型 + + private static final EventLoopGroup eventLoopGroup = new NioEventLoopGroup(); + + public NettyClientSocket(String inetHost, int inetPort, String clientId, ClientNettyConfigApplication clientNettyConfigApplication, List channelTypeAdvancedList) { + this.inetHost = inetHost; + this.inetPort = inetPort; + this.clientId = clientId; + this.clientNettyConfigApplication = clientNettyConfigApplication; + this.channelTypeAdvancedList = channelTypeAdvancedList; + } + + public void newConnect2Server() throws InterruptedException { + newConnect2Server(inetHost, inetPort, clientId, clientNettyConfigApplication); + } + + protected void newConnect2Server(String inetHost, int inetPort, String clientId, ClientNettyConfigApplication clientNettyConfigApplication) throws InterruptedException { + Bootstrap bootstrap = new Bootstrap(); + bootstrap.group(eventLoopGroup) + .channel(NioSocketChannel.class) + .handler(new NettyClientFilter(new ChannelTypeAdapter(channelTypeAdvancedList),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); + // 在线 + clientNettyConfigApplication.clientOnLine(clientId); + } else { + log.info("每隔2s重连...."); + // 离线 + clientNettyConfigApplication.clientOffLine(clientId); + futureListener.channel().eventLoop().schedule(() -> { + try { + newConnect2Server(inetHost, inetPort, clientId, clientNettyConfigApplication); + } catch (InterruptedException e) { + e.printStackTrace(); + } + }, 2, TimeUnit.SECONDS); + } + }); + } + + /** + * 关闭连接 + */ + + public void shutdown() { + if ((eventLoopGroup != null) && (!eventLoopGroup.isShutdown())) { + eventLoopGroup.shutdownGracefully(); + } + } + +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/rpc/StagingNoticeApiRpc.java b/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/rpc/StagingNoticeApiRpc.java new file mode 100644 index 0000000..8634391 --- /dev/null +++ b/lazy-cloud-heartbeat-client/src/main/java/wu/framework/middleground/under/cloud/heartbeat/client/rpc/StagingNoticeApiRpc.java @@ -0,0 +1,67 @@ +package wu.framework.middleground.under.cloud.heartbeat.client.rpc; + +import com.wu.framework.database.lazy.web.plus.stereotype.LazyApplication; +import com.wu.framework.database.lazy.web.plus.stereotype.LazyRpc; +import com.wu.framework.response.Result; +import com.wu.framework.response.ResultFactory; +import wu.framework.middleground.cloud.heartbeat.common.ChannelContext; +import wu.framework.middleground.cloud.heartbeat.common.MessageType; +import wu.framework.middleground.cloud.heartbeat.common.NettyProxyMsg; + +import io.netty.channel.Channel; + +import java.nio.charset.StandardCharsets; +import java.util.List; + +@LazyRpc +public class StagingNoticeApiRpc { + + + /** + * 前提当前客户端曾经有过离线、而后上线了,但是呢现在有暂存的数据,因此暂存是打开的,所以这个时候可以通知服务端让其告知其他客户户我暂存了 + * 通知自己暂存了 + * + * @param clientId 租户ID + * @return + */ + public Result stagingOpened(String clientId) { + List clientChannels = ChannelContext.get(); + for (ChannelContext.ClientChannel clientChannel : clientChannels) { + // 上报 当前通道暂存开启了 + Channel channel = clientChannel.getChannel(); + + NettyProxyMsg nettyMsg = new NettyProxyMsg(); + nettyMsg.setType(MessageType.REPORT_CLIENT_STAGING_OPENED); + nettyMsg.setData((clientId.toString() + .getBytes(StandardCharsets.UTF_8))); + nettyMsg.setClientId((clientId.toString() + .getBytes(StandardCharsets.UTF_8))); + channel.writeAndFlush(nettyMsg); + } + + return ResultFactory.successOf(); + } + + /** + * 暂存恢复 + * + * @param clientId 租户ID + * @return + */ + public Result stagingClosed(String clientId) { + List clientChannels = ChannelContext.get(); + for (ChannelContext.ClientChannel clientChannel : clientChannels) { + // 上报 当前通道暂存关闭了 + Channel channel = clientChannel.getChannel(); + NettyProxyMsg nettyMsg = new NettyProxyMsg(); + nettyMsg.setType(MessageType.REPORT_CLIENT_STAGING_CLOSED); + nettyMsg.setData((clientId.toString() + .getBytes(StandardCharsets.UTF_8))); + nettyMsg.setClientId((clientId.toString() + .getBytes(StandardCharsets.UTF_8))); + channel.writeAndFlush(nettyMsg); + } + + return ResultFactory.successOf(); + } +} diff --git a/lazy-cloud-heartbeat-client/src/main/resources/application-dev.yml b/lazy-cloud-heartbeat-client/src/main/resources/application-dev.yml new file mode 100644 index 0000000..ac1c63f --- /dev/null +++ b/lazy-cloud-heartbeat-client/src/main/resources/application-dev.yml @@ -0,0 +1,17 @@ +spring: + middleground: + netty: +# inet-host: 192.168.17.221 +# inet-port: 4923 +# inet-path: middleground-on-cloud-heartbeat-server + inet-host: 127.0.0.1 # 服务端地址 + inet-port: 7001 #服务端端口 + inet-path: middleground-on-cloud-heartbeat-server + client-id: local # 客户端ID + data: + redis: + host: 192.168.17.221 + port: 30553 + password: laihui + database: 2 + diff --git a/lazy-cloud-heartbeat-client/src/main/resources/application-prod.yml b/lazy-cloud-heartbeat-client/src/main/resources/application-prod.yml new file mode 100644 index 0000000..e69de29 diff --git a/lazy-cloud-heartbeat-client/src/main/resources/application.yml b/lazy-cloud-heartbeat-client/src/main/resources/application.yml new file mode 100644 index 0000000..7d31c33 --- /dev/null +++ b/lazy-cloud-heartbeat-client/src/main/resources/application.yml @@ -0,0 +1,7 @@ + +server: + port: 6004 + +spring: + profiles: + active: dev diff --git a/lazy-cloud-heartbeat-client/src/main/resources/bootstrap.yml b/lazy-cloud-heartbeat-client/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..706ffe0 --- /dev/null +++ b/lazy-cloud-heartbeat-client/src/main/resources/bootstrap.yml @@ -0,0 +1,12 @@ + + + +spring: + application: + name: middleground-under-cloud-heartbeat-client + cloud: + nacos: + discovery: + server-addr: 192.168.17.221:30569 + config: + server-addr: 192.168.17.221:30569 diff --git a/lazy-cloud-heartbeat-common/pom.xml b/lazy-cloud-heartbeat-common/pom.xml new file mode 100644 index 0000000..7e5f9bc --- /dev/null +++ b/lazy-cloud-heartbeat-common/pom.xml @@ -0,0 +1,30 @@ + + + 4.0.0 + + top.wu2020 + lazy-cloud-network + 1.2.1-JDK17-SNAPSHOT + + + lazy-cloud-heartbeat-common + + + 17 + 17 + UTF-8 + + + + io.netty + netty-all + + + top.wu2020 + wu-framework-web + + + + \ No newline at end of file diff --git a/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/ChannelContext.java b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/ChannelContext.java new file mode 100644 index 0000000..f29128c --- /dev/null +++ b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/ChannelContext.java @@ -0,0 +1,193 @@ +package wu.framework.middleground.cloud.heartbeat.common; + +import io.netty.channel.Channel; +import io.netty.channel.ChannelId; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + + +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; + +/** + * 通道上下文 + */ +@Slf4j +public class ChannelContext { + + private final static ConcurrentHashMap + channelIdClientChannelDTOConcurrentHashMap = new ConcurrentHashMap<>(); + + /** + * 新增通道 + * + * @param channel 通道 + * @param nettyMsg 通道中的信息 + */ + public static void push(Channel channel, NettyProxyMsg nettyMsg) { + + ChannelId channelId = channel.id(); + byte[] clientId = nettyMsg.getClientId(); + + ClientChannelImpl clientChannelImpl = new ClientChannelImpl(); + clientChannelImpl.setChannelId(channelId); + clientChannelImpl.setChannel(channel); + clientChannelImpl.setClientId(clientId); + channelIdClientChannelDTOConcurrentHashMap.put(channelId, clientChannelImpl); + + } + + /** + * 新增通道 + * + * @param channel 通道 + * @param clientId 客户端ID + */ + public static void push(Channel channel, byte[] clientId) { + + ChannelId channelId = channel.id(); + ClientChannelImpl clientChannelImpl = new ClientChannelImpl(); + clientChannelImpl.setChannelId(channelId); + clientChannelImpl.setChannel(channel); + clientChannelImpl.setClientId(clientId); + channelIdClientChannelDTOConcurrentHashMap.put(channelId, clientChannelImpl); + + } + + /** + * 获取所有通道 + * + * @return 返回所有通道信息 + */ + public static List get() { + return new ArrayList<>(channelIdClientChannelDTOConcurrentHashMap.values()); + } + + /** + * 根据通道ID获取通道信息 + * + * @param channelId 通道ID + * @return 通道信息 + */ + public static ClientChannel get(ChannelId channelId) { + if (channelIdClientChannelDTOConcurrentHashMap.containsKey(channelId)) { + return channelIdClientChannelDTOConcurrentHashMap.get(channelId); + } else { + log.error("无法通过通道ID[" + channelId + "]获取通道信息"); + return null; + } + } + + /** + * 根据通道ID获取通道信息 + * + * @param clientId 客户端ID + * @return 通道信息 + */ + public static ClientChannel get(byte[] clientId) { + if (channelIdClientChannelDTOConcurrentHashMap + .values().stream() + .anyMatch(clientChannelImpl -> new String(clientChannelImpl.getClientId()).equals(new String(clientId)))) { + return channelIdClientChannelDTOConcurrentHashMap + .values() + .stream() + .filter(clientChannelImpl -> new String(clientChannelImpl.getClientId()).equals(new String(clientId))) + .findFirst().get(); + } else { + log.error("无法通过客户端ID[" + new String(clientId) + "]获取通道信息"); + return null; + } + } + + /** + * 根据通道ID获取通道信息 + * + * @param clientId 客户端ID + * @return 通道信息 + */ + public static ChannelContext.ClientChannel get(String clientId) { + return get(clientId.getBytes(StandardCharsets.UTF_8)); + } + + /** + * 通过客户端通道ID移除客户端通道 + * + * @param channelId 客户端通道ID + */ + public static void remove(ChannelId channelId) { + if (channelIdClientChannelDTOConcurrentHashMap.containsKey(channelId)) { + channelIdClientChannelDTOConcurrentHashMap.remove(channelId); + } else { + // log warm + log.warn("无法通过客户端通道ID:[{}]移除客户端", channelId); + } + } + + /** + * 通过客户端ID移除客户端通道 + * + * @param clientId 客户端ID + */ + public static void remove(byte[] clientId) { + ClientChannel clientChannel = get(clientId); + if (clientChannel != null) { + channelIdClientChannelDTOConcurrentHashMap.remove(clientChannel.getChannelId()); + } else { + // log warm + log.warn("无法通过客户ID:[{}]移除客户端", new String(clientId)); + } + } + + + /** + * 客户端通道信息 + */ + public interface ClientChannel { + + /** + * 客户端ID + */ + byte[] getClientId(); + + /** + * 通道ID + */ + ChannelId getChannelId(); + + /** + * 通道 + */ + Channel getChannel(); + + } + +} + +/** + * 客户端通道信息 + */ +@Data +class ClientChannelImpl implements ChannelContext.ClientChannel { + /** + * 客户端ID + */ + private byte[] clientId; + /** + * 通道ID + */ + private ChannelId channelId; + /** + * 通道 + */ + private Channel channel; + + @Override + public String toString() { + return "ClientChannelImpl{" + + "clientId=" + new String(clientId) + + ", channelId=" + channelId.asLongText() + + '}'; + } +} diff --git a/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/InternalNetworkPenetrationRealClient.java b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/InternalNetworkPenetrationRealClient.java new file mode 100644 index 0000000..47b108b --- /dev/null +++ b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/InternalNetworkPenetrationRealClient.java @@ -0,0 +1,41 @@ +package wu.framework.middleground.cloud.heartbeat.common; + +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * describe 内网穿透映射 真实客户端 + * + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + **/ +@Data +@Accessors(chain = true) +public class InternalNetworkPenetrationRealClient { + + + /** + * 客户端ID + */ + private String clientId; + + /** + * 客户端目标地址 + */ + private String clientTargetIp; + + /** + * 客户端目标端口 + */ + private Integer clientTargetPort; + + + /** + * 访问端口 + */ + private Integer visitorPort; + /** + * 访客ID + */ + private String visitorId; +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/MessageType.java b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/MessageType.java new file mode 100644 index 0000000..50f6437 --- /dev/null +++ b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/MessageType.java @@ -0,0 +1,136 @@ +package wu.framework.middleground.cloud.heartbeat.common; + +import wu.framework.middleground.cloud.heartbeat.common.advanced.AbstractChannelHeartbeatTypeAdvanced; +import wu.framework.middleground.cloud.heartbeat.common.advanced.client.*; +import wu.framework.middleground.cloud.heartbeat.common.advanced.server.*; +import wu.framework.middleground.cloud.heartbeat.common.enums.MessageTypeEnums; + +/** + * @see MessageTypeEnums + * -128~ 127 + */ +public class MessageType { + /** + * 心跳 + * + * @see MessageTypeEnums#TYPE_HEARTBEAT + * @see AbstractChannelHeartbeatTypeAdvanced + */ + public static final byte TYPE_HEARTBEAT = 0X00; + + /** + * 客户端上报连接成功 + * + * @see MessageTypeEnums#REPORT_CLIENT_CONNECT_SUCCESS + * @see AbstractReportConnectSuccessTypeAdvanced + */ + public static final byte REPORT_CLIENT_CONNECT_SUCCESS = 0X01; + /** + * 上报 客户端断开连接 + * + * @see MessageTypeEnums#REPORT_CLIENT_DISCONNECTION + * @see AbstractReportDisconnectTypeAdvanced + */ + public static final byte REPORT_CLIENT_DISCONNECTION = 0X02; + /** + * 客户端上报暂存开启 + * + * @see MessageTypeEnums#REPORT_CLIENT_STAGING_OPENED + * @see AbstractReportStagingOpenedTypeAdvanced + */ + public static final byte REPORT_CLIENT_STAGING_OPENED = 0X03; + /** + * 客户端上报暂存关闭 + * + * @see MessageTypeEnums#REPORT_CLIENT_STAGING_CLOSED + * @see AbstractReportStagingClosedTypeAdvanced + */ + public static final byte REPORT_CLIENT_STAGING_CLOSED = 0X04; + + /** + * 上报 客户端数据传输(内网穿透数据回传) + * + * @see MessageTypeEnums#REPORT_CLIENT_TRANSFER + * @see AbstractReportChannelTransferTypeAdvanced + */ + public static final byte REPORT_CLIENT_TRANSFER = 0X05; + + + /** + * 上报 客户端创建需要代理的真实端口成功 + * + * @see MessageTypeEnums#REPORT_SINGLE_CLIENT_REAL_CONNECT + * @see AbstractReportSingleClientRealConnectTypeAdvanced + */ + public static final byte REPORT_SINGLE_CLIENT_REAL_CONNECT = 0X06; + /** + * 上报 客户端关闭一个访客通道 + * + * @see MessageTypeEnums#REPORT_SINGLE_CLIENT_CLOSE_VISITOR + * @see AbstractReportSingleClientCloseVisitorTypeAdvanced + */ + public static final byte REPORT_SINGLE_CLIENT_CLOSE_VISITOR = 0X08; + + + /** + * 下发 客户端接收连接成功通知 + * + * @see MessageTypeEnums#DISTRIBUTE_CLIENT_CONNECTION_SUCCESS_NOTIFICATION + * @see AbstractDistributeConnectSuccessNotificationTypeAdvanced + */ + public static final byte DISTRIBUTE_CLIENT_CONNECTION_SUCCESS_NOTIFICATION = -0X01; + /** + * 下发 客户端断开连接通知 + * + * @see MessageTypeEnums#DISTRIBUTE_CLIENT_DISCONNECTION_NOTIFICATION + * @see AbstractDistributeDisconnectTypeAdvanced + */ + public static final byte DISTRIBUTE_CLIENT_DISCONNECTION_NOTIFICATION = -0X02; + /** + * 下发 客户端暂存开启通知 + * + * @see MessageTypeEnums#DISTRIBUTE_CLIENT_STAGING_OPENED_NOTIFICATION + * @see AbstractDistributeStagingOpenedTypeAdvanced + */ + public static final byte DISTRIBUTE_CLIENT_STAGING_OPENED_NOTIFICATION = -0X03; + + /** + * 下发 客户端暂存关闭通知 + * + * @see MessageTypeEnums#DISTRIBUTE_CLIENT_STAGING_CLOSED_NOTIFICATION + * @see AbstractDistributeStagingClosedTypeAdvanced + */ + public static final byte DISTRIBUTE_CLIENT_STAGING_CLOSED_NOTIFICATION = -0X04; + /** + * 下发 客户端数据传输(内网穿透数据发送) + * + * @see MessageTypeEnums#DISTRIBUTE_CLIENT_TRANSFER + * @see AbstractDistributeChannelTransferTypeAdvanced + */ + public static final byte DISTRIBUTE_CLIENT_TRANSFER = -0X05; + /** + * 下发 客户端创建需要代理的真实端口 + * + * @see MessageTypeEnums#DISTRIBUTE_SINGLE_CLIENT_REAL_CONNECT + * @see AbstractDistributeSingleClientRealConnectTypeAdvanced + */ + public static final byte DISTRIBUTE_SINGLE_CLIENT_REAL_CONNECT = -0X06; + + /** + * 下发 客户端代理的真实端口自动读写 + * + * @see MessageTypeEnums#DISTRIBUTE_SINGLE_CLIENT_REAL_CONNECT_AUTO_READ + * @see AbstractDistributeSingleClientRealAutoReadConnectTypeAdvanced + */ + public static final byte DISTRIBUTE_SINGLE_CLIENT_REAL_CONNECT_AUTO_READ = -0X07; + + /** + * 下发 客户端关闭代理服务通道 + * + * @see MessageTypeEnums#DISTRIBUTE_SINGLE_CLIENT_REAL_CLOSE_VISITOR + * @see AbstractDistributeSingleClientRealCloseVisitorTypeAdvanced + */ + public static final byte DISTRIBUTE_SINGLE_CLIENT_REAL_CLOSE_VISITOR = -0X08; + + +} diff --git a/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/NettyCommunicationIdContext.java b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/NettyCommunicationIdContext.java new file mode 100644 index 0000000..bbad6c2 --- /dev/null +++ b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/NettyCommunicationIdContext.java @@ -0,0 +1,71 @@ +package wu.framework.middleground.cloud.heartbeat.common; + +import io.netty.channel.Channel; + +import java.util.concurrent.ConcurrentHashMap; + +/** + * 通信通道对应上下文 + */ +public class NettyCommunicationIdContext { + + protected static final ConcurrentHashMap COMMUNICATION = new ConcurrentHashMap<>(); + + + /** + * 添加访客 + * + * @param visitorId 访客id + * @param visitor 访客 + */ + public static void pushVisitor(T visitor, String visitorId) { + COMMUNICATION.put(visitorId, visitor); + + } + + /** + * 通过访客端口获取访客 + * + * @param visitorId 访客id + * @param 访客范型 + * @return 访客 + */ + public static T getVisitor(String visitorId) { + return (T) COMMUNICATION.get(visitorId); + } + + /** + * 通过访客端口获取访客 + * + * @param visitorId 访客id + * @param 访客范型 + * @return 访客 + */ + public static T getVisitor(byte[] visitorId) { + return getVisitor(new String(visitorId)); + + } + + /** + * 移除访客 + * + * @param visitorId 访客ID + */ + public static void clear(String visitorId) { + Channel visitor = getVisitor(visitorId); + if (visitor != null) { + COMMUNICATION.remove(visitorId); + visitor.close(); + } + + } + + /** + * 移除访客 + * + * @param visitorId 访客ID + */ + public static void clear(byte[] visitorId) { + clear(new String(visitorId)); + } +} diff --git a/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/NettyMsg.java b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/NettyMsg.java new file mode 100644 index 0000000..8e8b2e4 --- /dev/null +++ b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/NettyMsg.java @@ -0,0 +1,39 @@ +package wu.framework.middleground.cloud.heartbeat.common; + +import lombok.Getter; +import lombok.Setter; + +import java.util.Arrays; + +@Setter +@Getter +public class NettyMsg { + // body 长度 type 1 clientId 4 data 4 + public static final int bodyLength = 9; + + /** + * 数据类型 + * + * @see MessageType + * byte长度 1 + */ + private byte type; + /** + * 客户端ID + * byte[] 长度 4 + */ + private byte[] clientId; + + /** + * 消息传输数据 + * byte[] 长度 4 + */ + private byte[] data; + + + @Override + public String toString() { + return "NettyProxyMsg [type=" + type + ", data=" + Arrays.toString(data) + ",clientId=" + Arrays.toString(clientId) + "]"; + } + +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/NettyProxyMsg.java b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/NettyProxyMsg.java new file mode 100644 index 0000000..171fa83 --- /dev/null +++ b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/NettyProxyMsg.java @@ -0,0 +1,111 @@ +package wu.framework.middleground.cloud.heartbeat.common; + +import lombok.Getter; +import lombok.Setter; + +import java.nio.charset.StandardCharsets; + +/** + * netty 代理请求数据 + */ +@Setter +@Getter +public class NettyProxyMsg { + // body 长度 type 1 clientId 4 clientTargetIp 4 clientTargetPort 4 visitorPort 4 visitorId 4 data 4 + public static final int bodyLength = 1 + 4 + 4 + 4 + 4 + 4 + 4; + + + /** + * 数据类型 + * + * @see MessageType + * byte长度 1 + */ + private byte type; + + /** + * 客户端ID + * byte[] 长度 4 + */ + private byte[] clientId; + /** + * 客户端目标地址 + * byte[] 长度 4 + */ + private byte[] clientTargetIp; + + /** + * 客户端目标端口 + * byte[] 长度 4 + */ + private byte[] clientTargetPort; + /** + * 客户端目使用的代理端口 + * byte[] 长度 4 + */ + private byte[] visitorPort; + /** + * 访客ID + * byte[] 长度 4 + */ + private byte[] visitorId; + /** + * 消息传输数据 + * byte[] 长度 4 + */ + private byte[] data; + + + @Override + public String toString() { + return "NettyProxyMsg [type=" + type + + ",clientId=" + (clientId == null ? null : new String(clientId)) + + ",clientTargetIp=" + (clientTargetIp == null ? null : new String(clientTargetIp)) + + ",clientTargetPort=" + (clientTargetPort == null ? null : new String(clientTargetPort)) + + ",visitorPort=" + (visitorPort == null ? null : new String(visitorPort)) + + "]"; + } + + public void setClientId(byte[] clientId) { + this.clientId = clientId; + } + + public void setClientId(String clientId) { + this.clientId = clientId.getBytes(StandardCharsets.UTF_8); + } + + + public void setClientTargetIp(byte[] clientTargetIp) { + this.clientTargetIp = clientTargetIp; + } + + public void setClientTargetIp(String clientTargetIp) { + this.clientTargetIp = clientTargetIp.getBytes(StandardCharsets.UTF_8); + } + + public void setClientTargetPort(Integer clientTargetPort) { + this.clientTargetPort = String.valueOf(clientTargetPort).getBytes(StandardCharsets.UTF_8); + } + + public void setClientTargetPort(byte[] clientTargetPort) { + this.clientTargetPort = clientTargetPort; + } + + public void setVisitorPort(byte[] visitorPort) { + this.visitorPort = visitorPort; + } + + public void setVisitorPort(Integer visitorPort) { + this.visitorPort = String.valueOf(visitorPort).getBytes(StandardCharsets.UTF_8); + } + + public void setVisitorId(String visitorId) { + this.visitorId = visitorId.getBytes(StandardCharsets.UTF_8); + } + + public void setVisitorId(byte[] visitorId) { + this.visitorId = visitorId; + } + + +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/NettyRealIdContext.java b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/NettyRealIdContext.java new file mode 100644 index 0000000..e2cda89 --- /dev/null +++ b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/NettyRealIdContext.java @@ -0,0 +1,71 @@ +package wu.framework.middleground.cloud.heartbeat.common; + +import io.netty.channel.Channel; + +import java.util.concurrent.ConcurrentHashMap; + +/** + * 真实通道对应上下文 + */ +public class NettyRealIdContext { + + protected static final ConcurrentHashMap REAL = new ConcurrentHashMap<>(); + + + /** + * 添加访客 + * + * @param visitorId 访客id + * @param visitor 访客 + */ + public static void pushVisitor(T visitor, String visitorId) { + REAL.put(visitorId, visitor); + + } + + /** + * 通过访客端口获取访客 + * + * @param visitorId 访客id + * @param 访客范型 + * @return 访客 + */ + public static T getVisitor(String visitorId) { + return (T) REAL.get(visitorId); + } + + /** + * 通过访客端口获取访客 + * + * @param visitorId 访客id + * @param 访客范型 + * @return 访客 + */ + public static T getVisitor(byte[] visitorId) { + return getVisitor(new String(visitorId)); + + } + + /** + * 移除访客 + * + * @param visitorId 访客ID + */ + public static void clear(String visitorId) { + Channel visitor = getVisitor(visitorId); + if (visitor != null) { + REAL.remove(visitorId); + visitor.close(); + } + + } + + /** + * 移除访客 + * + * @param visitorId 访客ID + */ + public static void clear(byte[] visitorId) { + clear(new String(visitorId)); + } +} diff --git a/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/NettyVisitorContext.java b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/NettyVisitorContext.java new file mode 100644 index 0000000..0cd5ab1 --- /dev/null +++ b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/NettyVisitorContext.java @@ -0,0 +1,35 @@ +package wu.framework.middleground.cloud.heartbeat.common; + +import java.util.concurrent.ConcurrentHashMap; + +/** + * 访客端口对应上下文 + */ +public class NettyVisitorContext { + + protected static final ConcurrentHashMap VISITOR_PORT = new ConcurrentHashMap<>(); + + + /** + * 添加访客 + * + * @param visitorPort 访客端口 + * @param visitor 访客 + */ + public static void pushVisitor(Integer visitorPort, T visitor) { + VISITOR_PORT.put(visitorPort, visitor); + + } + + /** + * 通过访客端口获取访客 + * + * @param visitorPort 访客端口 + * @param 访客范型 + * @return 访客 + */ + public static T getVisitor(Integer visitorPort) { + return (T) VISITOR_PORT.get(visitorPort); + } + +} diff --git a/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/NettyVisitorIdContext.java b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/NettyVisitorIdContext.java new file mode 100644 index 0000000..a6ed070 --- /dev/null +++ b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/NettyVisitorIdContext.java @@ -0,0 +1,72 @@ +package wu.framework.middleground.cloud.heartbeat.common; + +import io.netty.channel.Channel; + +import java.util.concurrent.ConcurrentHashMap; + +/** + * 访客ID对应上下文 + */ +@Deprecated +public class NettyVisitorIdContext { + + protected static final ConcurrentHashMap VISITOR_ID = new ConcurrentHashMap<>(); + + + /** + * 添加访客 + * + * @param visitorId 访客id + * @param visitor 访客 + */ + public static void pushVisitor(T visitor, String visitorId) { + VISITOR_ID.put(visitorId, visitor); + + } + + /** + * 通过访客端口获取访客 + * + * @param visitorId 访客id + * @param 访客范型 + * @return 访客 + */ + public static T getVisitor(String visitorId) { + return (T) VISITOR_ID.get(visitorId); + } + + /** + * 通过访客端口获取访客 + * + * @param visitorId 访客id + * @param 访客范型 + * @return 访客 + */ + public static T getVisitor(byte[] visitorId) { + return getVisitor(new String(visitorId)); + + } + + /** + * 移除访客 + * + * @param visitorId 访客ID + */ + public static void clear(String visitorId) { + Channel visitor = getVisitor(visitorId); + if (visitor != null) { + VISITOR_ID.remove(visitorId); + visitor.close(); + } + + } + + /** + * 移除访客 + * + * @param visitorId 访客ID + */ + public static void clear(byte[] visitorId) { + clear(new String(visitorId)); + } +} diff --git a/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/adapter/ChannelTypeAdapter.java b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/adapter/ChannelTypeAdapter.java new file mode 100644 index 0000000..001c4b6 --- /dev/null +++ b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/adapter/ChannelTypeAdapter.java @@ -0,0 +1,36 @@ +package wu.framework.middleground.cloud.heartbeat.common.adapter; + +import wu.framework.middleground.cloud.heartbeat.common.advanced.ChannelTypeAdvanced; +import io.netty.channel.Channel; +import lombok.extern.slf4j.Slf4j; + +import java.util.List; + +/** + * 通道类型适配器 + */ +@Slf4j +public class ChannelTypeAdapter { + protected final List channelTypeAdvancedList; + + public ChannelTypeAdapter(List channelTypeAdvancedList) { + this.channelTypeAdvancedList = channelTypeAdvancedList; + } + + /** + * 处理当前数据 + * + * @param msg 通道数据 + */ + public void handler(Channel channel, Object msg) { + for (ChannelTypeAdvanced channelTypeAdvanced : channelTypeAdvancedList) { + if (channelTypeAdvanced.support(msg)) { +// log.info("处理器:{},客户端:{}, 处理类型:{}",channelTypeAdvanced.getClass(),new String(msg.getClientId()),msg.getType()); + channelTypeAdvanced.handler(channel, msg); + return; + } + } + } + + +} diff --git a/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/AbstractChannelHeartbeatTypeAdvanced.java b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/AbstractChannelHeartbeatTypeAdvanced.java new file mode 100644 index 0000000..c1aaad6 --- /dev/null +++ b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/AbstractChannelHeartbeatTypeAdvanced.java @@ -0,0 +1,25 @@ +package wu.framework.middleground.cloud.heartbeat.common.advanced; + + +import wu.framework.middleground.cloud.heartbeat.common.NettyProxyMsg; +import wu.framework.middleground.cloud.heartbeat.common.enums.MessageTypeEnums; + + +/** + * 服务端 处理客户端心跳 + * TYPE_HEARTBEAT + */ + +public abstract class AbstractChannelHeartbeatTypeAdvanced extends AbstractChannelTypeAdvanced implements ChannelTypeAdvanced { + + /** + * 是否支持当前类型 + * + * @param msg 通道数据 + * @return 布尔类型 是、否 + */ + @Override + public boolean doSupport(NettyProxyMsg msg) { + return MessageTypeEnums.TYPE_HEARTBEAT.getTypeByte() == msg.getType(); + } +} diff --git a/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/AbstractChannelTypeAdvanced.java b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/AbstractChannelTypeAdvanced.java new file mode 100644 index 0000000..bba6474 --- /dev/null +++ b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/AbstractChannelTypeAdvanced.java @@ -0,0 +1,68 @@ +package wu.framework.middleground.cloud.heartbeat.common.advanced; + + +import io.netty.channel.Channel; + +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.Objects; + +public abstract class AbstractChannelTypeAdvanced implements ChannelTypeAdvanced { + + /** + * 处理当前数据 + * + * @param channel 当前通道 + * @param msg 通道数据 + */ + protected abstract void doHandler(Channel channel, MSG msg); + + /** + * 处理当前数据 + * + * @param channel 当前通道 + * @param msg 通道数据 + */ + @Override + public void handler(Channel channel, Object msg) { + doHandler(channel, (MSG) msg); + } + + protected abstract boolean doSupport(MSG msg); + + /** + * 是否支持当前类型 + * + * @param msg 通道数据 + * @return 布尔类型 是、否 + */ + @Override + public boolean support(Object msg) { + if (msg == null) return false; + if (!msg.getClass().isAssignableFrom(Objects.requireNonNull(getMsgTypes()))) { + return false; + } + return doSupport((MSG) msg); + } + + /** + * 获取当前处理范型 + * + * @return 范型 + */ + private Class getMsgTypes() { + + Type superClassType = this.getClass().getGenericSuperclass(); + if (superClassType instanceof ParameterizedType parameterizedType) { + + Type[] actualTypes = parameterizedType.getActualTypeArguments(); +// for (Type type : actualTypes) { +// System.out.println("范型类型:" + ((Class) type).getName()); +// } + return (Class) actualTypes[0]; + } else { +// System.out.println("未能获取到范型类型"); + return null; + } + } +} diff --git a/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/ChannelTypeAdvanced.java b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/ChannelTypeAdvanced.java new file mode 100644 index 0000000..015558f --- /dev/null +++ b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/ChannelTypeAdvanced.java @@ -0,0 +1,33 @@ +package wu.framework.middleground.cloud.heartbeat.common.advanced; + + +import wu.framework.middleground.cloud.heartbeat.common.MessageType; +import wu.framework.middleground.cloud.heartbeat.common.enums.MessageTypeEnums; +import io.netty.channel.Channel; + +/** + * 通道不同数据类型处理器 + * + * @see MessageType + * @see MessageTypeEnums + */ +public interface ChannelTypeAdvanced { + + + /** + * 处理当前数据 + * + * @param channel 当前通道 + * @param msg 通道数据 + */ + void handler(Channel channel, Object msg); + + /** + * 是否支持当前类型 + * + * @param msg 通道数据 + * @return 布尔类型 是、否 + */ + boolean support(Object msg); + +} diff --git a/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/client/AbstractDistributeChannelTransferTypeAdvanced.java b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/client/AbstractDistributeChannelTransferTypeAdvanced.java new file mode 100644 index 0000000..2357724 --- /dev/null +++ b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/client/AbstractDistributeChannelTransferTypeAdvanced.java @@ -0,0 +1,27 @@ +package wu.framework.middleground.cloud.heartbeat.common.advanced.client; + + +import wu.framework.middleground.cloud.heartbeat.common.NettyProxyMsg; +import wu.framework.middleground.cloud.heartbeat.common.advanced.AbstractChannelTypeAdvanced; +import wu.framework.middleground.cloud.heartbeat.common.advanced.ChannelTypeAdvanced; +import wu.framework.middleground.cloud.heartbeat.common.enums.MessageTypeEnums; + + +/** + * 客户端处理服务端下发数据 + * DISTRIBUTE_CLIENT_TRANSFER + */ +public abstract class AbstractDistributeChannelTransferTypeAdvanced extends AbstractChannelTypeAdvanced implements ChannelTypeAdvanced { + + + /** + * 是否支持当前类型 + * + * @param msg 通道数据 + * @return 布尔类型 是、否 + */ + @Override + public boolean doSupport(NettyProxyMsg msg) { + return MessageTypeEnums.DISTRIBUTE_CLIENT_TRANSFER.getTypeByte() == msg.getType(); + } +} diff --git a/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/client/AbstractDistributeConnectSuccessNotificationTypeAdvanced.java b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/client/AbstractDistributeConnectSuccessNotificationTypeAdvanced.java new file mode 100644 index 0000000..63e1f9c --- /dev/null +++ b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/client/AbstractDistributeConnectSuccessNotificationTypeAdvanced.java @@ -0,0 +1,23 @@ +package wu.framework.middleground.cloud.heartbeat.common.advanced.client; + +import wu.framework.middleground.cloud.heartbeat.common.NettyProxyMsg; +import wu.framework.middleground.cloud.heartbeat.common.advanced.AbstractChannelTypeAdvanced; +import wu.framework.middleground.cloud.heartbeat.common.advanced.ChannelTypeAdvanced; +import wu.framework.middleground.cloud.heartbeat.common.enums.MessageTypeEnums; + +/** + * 下发 客户端连接成功通知 + */ +public abstract class AbstractDistributeConnectSuccessNotificationTypeAdvanced extends AbstractChannelTypeAdvanced implements ChannelTypeAdvanced { + + /** + * 是否支持当前类型 + * + * @param msg 通道数据 + * @return 布尔类型 是、否 + */ + @Override + public boolean doSupport(NettyProxyMsg msg) { + return MessageTypeEnums.DISTRIBUTE_CLIENT_CONNECTION_SUCCESS_NOTIFICATION.getTypeByte() == msg.getType(); + } +} diff --git a/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/client/AbstractDistributeDisconnectTypeAdvanced.java b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/client/AbstractDistributeDisconnectTypeAdvanced.java new file mode 100644 index 0000000..07547a5 --- /dev/null +++ b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/client/AbstractDistributeDisconnectTypeAdvanced.java @@ -0,0 +1,26 @@ +package wu.framework.middleground.cloud.heartbeat.common.advanced.client; + + +import wu.framework.middleground.cloud.heartbeat.common.NettyProxyMsg; +import wu.framework.middleground.cloud.heartbeat.common.advanced.AbstractChannelTypeAdvanced; +import wu.framework.middleground.cloud.heartbeat.common.advanced.ChannelTypeAdvanced; +import wu.framework.middleground.cloud.heartbeat.common.enums.MessageTypeEnums; + +/** + * 下发客户端断开连接通知 + * DISTRIBUTE_CLIENT_DISCONNECTION_NOTIFICATION + */ +public abstract class AbstractDistributeDisconnectTypeAdvanced extends AbstractChannelTypeAdvanced implements ChannelTypeAdvanced { + + /** + * 是否支持当前类型 + * + * @param msg 通道数据 + * @return 布尔类型 是、否 + */ + @Override + public boolean doSupport(NettyProxyMsg msg) { + // 下发 客户端断开连接通知 + return MessageTypeEnums.DISTRIBUTE_CLIENT_DISCONNECTION_NOTIFICATION.getTypeByte() == msg.getType(); + } +} diff --git a/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/client/AbstractDistributeSingleClientRealAutoReadConnectTypeAdvanced.java b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/client/AbstractDistributeSingleClientRealAutoReadConnectTypeAdvanced.java new file mode 100644 index 0000000..1367d51 --- /dev/null +++ b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/client/AbstractDistributeSingleClientRealAutoReadConnectTypeAdvanced.java @@ -0,0 +1,27 @@ +package wu.framework.middleground.cloud.heartbeat.common.advanced.client; + + +import wu.framework.middleground.cloud.heartbeat.common.NettyProxyMsg; +import wu.framework.middleground.cloud.heartbeat.common.advanced.AbstractChannelTypeAdvanced; +import wu.framework.middleground.cloud.heartbeat.common.advanced.ChannelTypeAdvanced; +import wu.framework.middleground.cloud.heartbeat.common.enums.MessageTypeEnums; + +/** + * 下发 客户端代理的真实端口自动读写 + * + * @see MessageTypeEnums#DISTRIBUTE_SINGLE_CLIENT_REAL_CONNECT_AUTO_READ + */ + +public abstract class AbstractDistributeSingleClientRealAutoReadConnectTypeAdvanced extends AbstractChannelTypeAdvanced implements ChannelTypeAdvanced { + + /** + * 是否支持当前类型 + * + * @param msg 通道数据 + * @return 布尔类型 是、否 + */ + @Override + public boolean doSupport(NettyProxyMsg msg) { + return MessageTypeEnums.DISTRIBUTE_SINGLE_CLIENT_REAL_CONNECT_AUTO_READ.getTypeByte() == msg.getType(); + } +} diff --git a/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/client/AbstractDistributeSingleClientRealCloseVisitorTypeAdvanced.java b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/client/AbstractDistributeSingleClientRealCloseVisitorTypeAdvanced.java new file mode 100644 index 0000000..578bd3b --- /dev/null +++ b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/client/AbstractDistributeSingleClientRealCloseVisitorTypeAdvanced.java @@ -0,0 +1,25 @@ +package wu.framework.middleground.cloud.heartbeat.common.advanced.client; + + +import wu.framework.middleground.cloud.heartbeat.common.NettyProxyMsg; +import wu.framework.middleground.cloud.heartbeat.common.advanced.AbstractChannelTypeAdvanced; +import wu.framework.middleground.cloud.heartbeat.common.advanced.ChannelTypeAdvanced; +import wu.framework.middleground.cloud.heartbeat.common.enums.MessageTypeEnums; + +/** + * 下发 客户端关闭代理服务通道 + */ + +public abstract class AbstractDistributeSingleClientRealCloseVisitorTypeAdvanced extends AbstractChannelTypeAdvanced implements ChannelTypeAdvanced { + + /** + * 是否支持当前类型 + * + * @param msg 通道数据 + * @return 布尔类型 是、否 + */ + @Override + public boolean doSupport(NettyProxyMsg msg) { + return MessageTypeEnums.DISTRIBUTE_SINGLE_CLIENT_REAL_CLOSE_VISITOR.getTypeByte() == msg.getType(); + } +} diff --git a/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/client/AbstractDistributeSingleClientRealConnectTypeAdvanced.java b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/client/AbstractDistributeSingleClientRealConnectTypeAdvanced.java new file mode 100644 index 0000000..974c428 --- /dev/null +++ b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/client/AbstractDistributeSingleClientRealConnectTypeAdvanced.java @@ -0,0 +1,25 @@ +package wu.framework.middleground.cloud.heartbeat.common.advanced.client; + + +import wu.framework.middleground.cloud.heartbeat.common.NettyProxyMsg; +import wu.framework.middleground.cloud.heartbeat.common.advanced.AbstractChannelTypeAdvanced; +import wu.framework.middleground.cloud.heartbeat.common.advanced.ChannelTypeAdvanced; +import wu.framework.middleground.cloud.heartbeat.common.enums.MessageTypeEnums; + +/** + * 下发 客户端 创建真实连接 + */ + +public abstract class AbstractDistributeSingleClientRealConnectTypeAdvanced extends AbstractChannelTypeAdvanced implements ChannelTypeAdvanced { + + /** + * 是否支持当前类型 + * + * @param msg 通道数据 + * @return 布尔类型 是、否 + */ + @Override + public boolean doSupport(NettyProxyMsg msg) { + return MessageTypeEnums.DISTRIBUTE_SINGLE_CLIENT_REAL_CONNECT.getTypeByte() == msg.getType(); + } +} diff --git a/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/client/AbstractDistributeStagingClosedTypeAdvanced.java b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/client/AbstractDistributeStagingClosedTypeAdvanced.java new file mode 100644 index 0000000..1302eed --- /dev/null +++ b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/client/AbstractDistributeStagingClosedTypeAdvanced.java @@ -0,0 +1,25 @@ +package wu.framework.middleground.cloud.heartbeat.common.advanced.client; + + +import wu.framework.middleground.cloud.heartbeat.common.NettyProxyMsg; +import wu.framework.middleground.cloud.heartbeat.common.advanced.AbstractChannelTypeAdvanced; +import wu.framework.middleground.cloud.heartbeat.common.advanced.ChannelTypeAdvanced; +import wu.framework.middleground.cloud.heartbeat.common.enums.MessageTypeEnums; + +/** + * 下发 客户端暂存关闭 + */ + +public abstract class AbstractDistributeStagingClosedTypeAdvanced extends AbstractChannelTypeAdvanced implements ChannelTypeAdvanced { + + /** + * 是否支持当前类型 + * + * @param msg 通道数据 + * @return 布尔类型 是、否 + */ + @Override + public boolean doSupport(NettyProxyMsg msg) { + return MessageTypeEnums.DISTRIBUTE_CLIENT_STAGING_CLOSED_NOTIFICATION.getTypeByte() == msg.getType(); + } +} diff --git a/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/client/AbstractDistributeStagingOpenedTypeAdvanced.java b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/client/AbstractDistributeStagingOpenedTypeAdvanced.java new file mode 100644 index 0000000..077cdf3 --- /dev/null +++ b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/client/AbstractDistributeStagingOpenedTypeAdvanced.java @@ -0,0 +1,25 @@ +package wu.framework.middleground.cloud.heartbeat.common.advanced.client; + + +import wu.framework.middleground.cloud.heartbeat.common.NettyProxyMsg; +import wu.framework.middleground.cloud.heartbeat.common.advanced.AbstractChannelTypeAdvanced; +import wu.framework.middleground.cloud.heartbeat.common.advanced.ChannelTypeAdvanced; +import wu.framework.middleground.cloud.heartbeat.common.enums.MessageTypeEnums; + +/** + * 下发 客户端暂存开启 + */ + +public abstract class AbstractDistributeStagingOpenedTypeAdvanced extends AbstractChannelTypeAdvanced implements ChannelTypeAdvanced { + + /** + * 是否支持当前类型 + * + * @param msg 通道数据 + * @return 布尔类型 是、否 + */ + @Override + public boolean doSupport(NettyProxyMsg msg) { + return MessageTypeEnums.DISTRIBUTE_CLIENT_STAGING_OPENED_NOTIFICATION.getTypeByte() == msg.getType(); + } +} diff --git a/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/server/AbstractReportChannelTransferTypeAdvanced.java b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/server/AbstractReportChannelTransferTypeAdvanced.java new file mode 100644 index 0000000..cd1b6df --- /dev/null +++ b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/server/AbstractReportChannelTransferTypeAdvanced.java @@ -0,0 +1,27 @@ +package wu.framework.middleground.cloud.heartbeat.common.advanced.server; + + +import wu.framework.middleground.cloud.heartbeat.common.NettyProxyMsg; +import wu.framework.middleground.cloud.heartbeat.common.advanced.AbstractChannelTypeAdvanced; +import wu.framework.middleground.cloud.heartbeat.common.advanced.ChannelTypeAdvanced; +import wu.framework.middleground.cloud.heartbeat.common.enums.MessageTypeEnums; + + +/** + * 服务端处理客户端上报数据 + * REPORT_CLIENT_STAGING_CLOSED + */ +public abstract class AbstractReportChannelTransferTypeAdvanced extends AbstractChannelTypeAdvanced implements ChannelTypeAdvanced { + + + /** + * 是否支持当前类型 + * + * @param msg 通道数据 + * @return 布尔类型 是、否 + */ + @Override + public boolean doSupport(NettyProxyMsg msg) { + return MessageTypeEnums.REPORT_CLIENT_TRANSFER.getTypeByte() == msg.getType(); + } +} diff --git a/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/server/AbstractReportConnectSuccessTypeAdvanced.java b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/server/AbstractReportConnectSuccessTypeAdvanced.java new file mode 100644 index 0000000..1da051d --- /dev/null +++ b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/server/AbstractReportConnectSuccessTypeAdvanced.java @@ -0,0 +1,23 @@ +package wu.framework.middleground.cloud.heartbeat.common.advanced.server; + +import wu.framework.middleground.cloud.heartbeat.common.NettyProxyMsg; +import wu.framework.middleground.cloud.heartbeat.common.advanced.AbstractChannelTypeAdvanced; +import wu.framework.middleground.cloud.heartbeat.common.advanced.ChannelTypeAdvanced; +import wu.framework.middleground.cloud.heartbeat.common.enums.MessageTypeEnums; + +/** + * 客户端连接成功上报处理器 + */ +public abstract class AbstractReportConnectSuccessTypeAdvanced extends AbstractChannelTypeAdvanced implements ChannelTypeAdvanced { + + /** + * 是否支持当前类型 + * + * @param msg 通道数据 + * @return 布尔类型 是、否 + */ + @Override + public boolean doSupport(NettyProxyMsg msg) { + return MessageTypeEnums.REPORT_CLIENT_CONNECT_SUCCESS.getTypeByte() == msg.getType(); + } +} diff --git a/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/server/AbstractReportDisconnectTypeAdvanced.java b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/server/AbstractReportDisconnectTypeAdvanced.java new file mode 100644 index 0000000..a8289ab --- /dev/null +++ b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/server/AbstractReportDisconnectTypeAdvanced.java @@ -0,0 +1,27 @@ +package wu.framework.middleground.cloud.heartbeat.common.advanced.server; + + +import wu.framework.middleground.cloud.heartbeat.common.NettyProxyMsg; +import wu.framework.middleground.cloud.heartbeat.common.advanced.AbstractChannelTypeAdvanced; +import wu.framework.middleground.cloud.heartbeat.common.advanced.ChannelTypeAdvanced; +import wu.framework.middleground.cloud.heartbeat.common.enums.MessageTypeEnums; + +/** + * 客户端上报断开连接通知 + * DISTRIBUTE_CLIENT_DISCONNECTION_NOTIFICATION + */ + +public abstract class AbstractReportDisconnectTypeAdvanced extends AbstractChannelTypeAdvanced implements ChannelTypeAdvanced { + + /** + * 是否支持当前类型 + * + * @param msg 通道数据 + * @return 布尔类型 是、否 + */ + @Override + public boolean doSupport(NettyProxyMsg msg) { + // 下发 客户端断开连接通知 + return MessageTypeEnums.REPORT_CLIENT_DISCONNECTION.getTypeByte() == msg.getType(); + } +} diff --git a/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/server/AbstractReportSingleClientCloseVisitorTypeAdvanced.java b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/server/AbstractReportSingleClientCloseVisitorTypeAdvanced.java new file mode 100644 index 0000000..2f27a0a --- /dev/null +++ b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/server/AbstractReportSingleClientCloseVisitorTypeAdvanced.java @@ -0,0 +1,27 @@ +package wu.framework.middleground.cloud.heartbeat.common.advanced.server; + + +import wu.framework.middleground.cloud.heartbeat.common.NettyProxyMsg; +import wu.framework.middleground.cloud.heartbeat.common.advanced.AbstractChannelTypeAdvanced; +import wu.framework.middleground.cloud.heartbeat.common.advanced.ChannelTypeAdvanced; +import wu.framework.middleground.cloud.heartbeat.common.enums.MessageTypeEnums; + + +/** + * 服务端处理客户端 关闭一个访客 + * REPORT_SINGLE_CLIENT_CLOSE_VISITOR + */ +public abstract class AbstractReportSingleClientCloseVisitorTypeAdvanced extends AbstractChannelTypeAdvanced implements ChannelTypeAdvanced { + + + /** + * 是否支持当前类型 + * + * @param msg 通道数据 + * @return 布尔类型 是、否 + */ + @Override + public boolean doSupport(NettyProxyMsg msg) { + return MessageTypeEnums.REPORT_SINGLE_CLIENT_CLOSE_VISITOR.getTypeByte() == msg.getType(); + } +} diff --git a/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/server/AbstractReportSingleClientRealConnectTypeAdvanced.java b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/server/AbstractReportSingleClientRealConnectTypeAdvanced.java new file mode 100644 index 0000000..ac810e3 --- /dev/null +++ b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/server/AbstractReportSingleClientRealConnectTypeAdvanced.java @@ -0,0 +1,27 @@ +package wu.framework.middleground.cloud.heartbeat.common.advanced.server; + + +import wu.framework.middleground.cloud.heartbeat.common.NettyProxyMsg; +import wu.framework.middleground.cloud.heartbeat.common.advanced.AbstractChannelTypeAdvanced; +import wu.framework.middleground.cloud.heartbeat.common.advanced.ChannelTypeAdvanced; +import wu.framework.middleground.cloud.heartbeat.common.enums.MessageTypeEnums; + + +/** + * 服务端处理客户端绑定真实服务成功 + * REPORT_SINGLE_CLIENT_REAL_CONNECT + */ +public abstract class AbstractReportSingleClientRealConnectTypeAdvanced extends AbstractChannelTypeAdvanced implements ChannelTypeAdvanced { + + + /** + * 是否支持当前类型 + * + * @param msg 通道数据 + * @return 布尔类型 是、否 + */ + @Override + public boolean doSupport(NettyProxyMsg msg) { + return MessageTypeEnums.REPORT_SINGLE_CLIENT_REAL_CONNECT.getTypeByte() == msg.getType(); + } +} diff --git a/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/server/AbstractReportStagingClosedTypeAdvanced.java b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/server/AbstractReportStagingClosedTypeAdvanced.java new file mode 100644 index 0000000..20bf273 --- /dev/null +++ b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/server/AbstractReportStagingClosedTypeAdvanced.java @@ -0,0 +1,29 @@ +package wu.framework.middleground.cloud.heartbeat.common.advanced.server; + + +import wu.framework.middleground.cloud.heartbeat.common.NettyProxyMsg; +import wu.framework.middleground.cloud.heartbeat.common.advanced.AbstractChannelTypeAdvanced; +import wu.framework.middleground.cloud.heartbeat.common.advanced.ChannelTypeAdvanced; +import wu.framework.middleground.cloud.heartbeat.common.enums.MessageTypeEnums; + +/** + * 客户端暂存通知 + * 客户端离线后陷入暂存服务业务上使用 + * 云端发送的消息,此模式云端后者说服务端不需要处理 + * CLIENT_STAGING + * 客户端上报暂存 + */ + +public abstract class AbstractReportStagingClosedTypeAdvanced extends AbstractChannelTypeAdvanced implements ChannelTypeAdvanced{ + + /** + * 是否支持当前类型 + * + * @param msg 通道数据 + * @return 布尔类型 是、否 + */ + @Override + public boolean doSupport(NettyProxyMsg msg) { + return MessageTypeEnums.REPORT_CLIENT_STAGING_CLOSED.getTypeByte() == msg.getType(); + } +} diff --git a/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/server/AbstractReportStagingOpenedTypeAdvanced.java b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/server/AbstractReportStagingOpenedTypeAdvanced.java new file mode 100644 index 0000000..699c742 --- /dev/null +++ b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/advanced/server/AbstractReportStagingOpenedTypeAdvanced.java @@ -0,0 +1,25 @@ +package wu.framework.middleground.cloud.heartbeat.common.advanced.server; + + +import wu.framework.middleground.cloud.heartbeat.common.NettyProxyMsg; +import wu.framework.middleground.cloud.heartbeat.common.advanced.AbstractChannelTypeAdvanced; +import wu.framework.middleground.cloud.heartbeat.common.advanced.ChannelTypeAdvanced; +import wu.framework.middleground.cloud.heartbeat.common.enums.MessageTypeEnums; + +/** + * 上报客户端暂存开启 + */ + +public abstract class AbstractReportStagingOpenedTypeAdvanced extends AbstractChannelTypeAdvanced implements ChannelTypeAdvanced { + + /** + * 是否支持当前类型 + * + * @param msg 通道数据 + * @return 布尔类型 是、否 + */ + @Override + public boolean doSupport(NettyProxyMsg msg) { + return MessageTypeEnums.REPORT_CLIENT_STAGING_OPENED.getTypeByte() == msg.getType(); + } +} diff --git a/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/constant/ClientConfigKeyUtils.java b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/constant/ClientConfigKeyUtils.java new file mode 100644 index 0000000..339e709 --- /dev/null +++ b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/constant/ClientConfigKeyUtils.java @@ -0,0 +1,46 @@ +package wu.framework.middleground.cloud.heartbeat.common.constant; + +import wu.framework.middleground.cloud.heartbeat.common.enums.NettyClientStatus; + +/** + * 客户端配置 key 常量 + */ +public class ClientConfigKeyUtils { + + // + /** + * 客户端状态对应的key + * + * @see NettyClientStatus#ON_LINE + * @see NettyClientStatus#OFF_LINE + */ + public static final String CLIENT_STATUS_KEY = "middleground:cloud:netty:client:status"; + + + /** + * 客户端ID存放的key + */ + public static final String CLIENT_ID_KEY = "middleground:cloud:netty:client:id"; + + + /** + * 获取客户端对应的状态key + * + * @param clientId 客户端ID + * @return 客户端对应的状态key + */ + public static String getClientStatusKey(String clientId) { + return CLIENT_STATUS_KEY + ":" + clientId; + } + + + /** + * 获取 客户端ID对应的key + * + * @param clientId 客户端ID + * @return 客户端ID对应的key + */ + public static String getClientIdKey(String clientId) { + return CLIENT_ID_KEY + ":" + clientId; + } +} diff --git a/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/constant/NettyChannelAttributeKey.java b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/constant/NettyChannelAttributeKey.java new file mode 100644 index 0000000..1a4f32a --- /dev/null +++ b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/constant/NettyChannelAttributeKey.java @@ -0,0 +1,10 @@ +package wu.framework.middleground.cloud.heartbeat.common.constant; + +import io.netty.util.AttributeKey; + +/** + * netty 通道属性 key常量 + */ +public class NettyChannelAttributeKey { + public static final AttributeKey CLIENT_ID_KEY = AttributeKey.newInstance("client_id"); +} diff --git a/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/constant/ProxyConfigConstant.java b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/constant/ProxyConfigConstant.java new file mode 100644 index 0000000..b4a83c1 --- /dev/null +++ b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/constant/ProxyConfigConstant.java @@ -0,0 +1,5 @@ +package wu.framework.middleground.cloud.heartbeat.common.constant; + +public class ProxyConfigConstant { + public static final String PREFIX ="spring.lazy.proxy"; +} diff --git a/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/constant/RedisChannelConstant.java b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/constant/RedisChannelConstant.java new file mode 100644 index 0000000..893312e --- /dev/null +++ b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/constant/RedisChannelConstant.java @@ -0,0 +1,14 @@ +package wu.framework.middleground.cloud.heartbeat.common.constant; + +/** + * redis 通道 + */ +public class RedisChannelConstant { + // 客户端离线或者在线通知通道 + public static final String REDIS_CLIENT_ONLINE_OR_OFFLINE_CHANNEL = "REDIS_CLIENT_ONLINE_OR_OFFLINE_CHANNEL"; + + /** + * 客户端监听 客户端暂存开启、关闭通道 + */ + public static final String REDIS_CLIENT_STAGING_OPENED_OR_CLOSED_CHANNEL = "REDIS_CLIENT_STAGING_OPENED_OR_CLOSED_CHANNEL"; +} diff --git a/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/decoder/NettyMsgDecoder.java b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/decoder/NettyMsgDecoder.java new file mode 100644 index 0000000..f1d7dfb --- /dev/null +++ b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/decoder/NettyMsgDecoder.java @@ -0,0 +1,53 @@ +package wu.framework.middleground.cloud.heartbeat.common.decoder; + +import wu.framework.middleground.cloud.heartbeat.common.NettyMsg; +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.LengthFieldBasedFrameDecoder; + +/** + * @see NettyMsg + * NettyMsg 对象解码 + */ +public class NettyMsgDecoder extends LengthFieldBasedFrameDecoder { + + public NettyMsgDecoder(int maxFrameLength, int lengthFieldOffset, int lengthFieldLength, int lengthAdjustment, + int initialBytesToStrip) { + super(maxFrameLength, lengthFieldOffset, lengthFieldLength, lengthAdjustment, initialBytesToStrip); + } + + public NettyMsgDecoder(int maxFrameLength, int lengthFieldOffset, int lengthFieldLength, int lengthAdjustment, + int initialBytesToStrip, boolean failFast) { + super(maxFrameLength, lengthFieldOffset, lengthFieldLength, lengthAdjustment, initialBytesToStrip, failFast); + } + + @Override + protected NettyMsg decode(ChannelHandlerContext ctx, ByteBuf in2) throws Exception { + ByteBuf in = (ByteBuf) super.decode(ctx, in2); + if (in == null) { + return null; + } + + if (in.readableBytes() < 4) { + return null; + } + + NettyMsg nettyMsg = new NettyMsg(); + int bodyLength = in.readInt(); + byte type = in.readByte(); + nettyMsg.setType(type); + + int clientIdLength = in.readInt(); + byte[] clientId = new byte[clientIdLength]; + in.readBytes(clientId); + nettyMsg.setClientId(clientId); + + + byte[] data = new byte[bodyLength - NettyMsg.bodyLength - clientIdLength]; + in.readBytes(data); + nettyMsg.setData(data); + in.release(); + + return nettyMsg; + } +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/decoder/NettyProxyMsgDecoder.java b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/decoder/NettyProxyMsgDecoder.java new file mode 100644 index 0000000..839c2cb --- /dev/null +++ b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/decoder/NettyProxyMsgDecoder.java @@ -0,0 +1,152 @@ +package wu.framework.middleground.cloud.heartbeat.common.decoder; + +import wu.framework.middleground.cloud.heartbeat.common.NettyProxyMsg; +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.ByteToMessageDecoder; +import io.netty.handler.codec.LengthFieldBasedFrameDecoder; +import io.netty.handler.codec.TooLongFrameException; + +import java.nio.ByteOrder; + +/** + * @see NettyProxyMsg + * NettyProxyMsg 解码 + */ +public class NettyProxyMsgDecoder extends LengthFieldBasedFrameDecoder { + /** + * Creates a new instance. + * + * @param maxFrameLength the maximum length of the frame. If the length of the frame is + * greater than this value, {@link TooLongFrameException} will be + * thrown. + * @param lengthFieldOffset the offset of the length field + * @param lengthFieldLength the length of the length field + */ + public NettyProxyMsgDecoder(int maxFrameLength, int lengthFieldOffset, int lengthFieldLength) { + super(maxFrameLength, lengthFieldOffset, lengthFieldLength); + } + + /** + * Creates a new instance. + * + * @param maxFrameLength the maximum length of the frame. If the length of the frame is + * greater than this value, {@link TooLongFrameException} will be + * thrown. + * @param lengthFieldOffset the offset of the length field + * @param lengthFieldLength the length of the length field + * @param lengthAdjustment the compensation value to add to the value of the length field + * @param initialBytesToStrip the number of first bytes to strip out from the decoded frame + */ + public NettyProxyMsgDecoder(int maxFrameLength, int lengthFieldOffset, int lengthFieldLength, int lengthAdjustment, int initialBytesToStrip) { + super(maxFrameLength, lengthFieldOffset, lengthFieldLength, lengthAdjustment, initialBytesToStrip); + } + + /** + * Creates a new instance. + * + * @param maxFrameLength the maximum length of the frame. If the length of the frame is + * greater than this value, {@link TooLongFrameException} will be + * thrown. + * @param lengthFieldOffset the offset of the length field + * @param lengthFieldLength the length of the length field + * @param lengthAdjustment the compensation value to add to the value of the length field + * @param initialBytesToStrip the number of first bytes to strip out from the decoded frame + * @param failFast If true, a {@link TooLongFrameException} is thrown as + * soon as the decoder notices the length of the frame will exceed + * maxFrameLength regardless of whether the entire frame + * has been read. If false, a {@link TooLongFrameException} + * is thrown after the entire frame that exceeds maxFrameLength + * has been read. + */ + public NettyProxyMsgDecoder(int maxFrameLength, int lengthFieldOffset, int lengthFieldLength, int lengthAdjustment, int initialBytesToStrip, boolean failFast) { + super(maxFrameLength, lengthFieldOffset, lengthFieldLength, lengthAdjustment, initialBytesToStrip, failFast); + } + + /** + * Creates a new instance. + * + * @param byteOrder the {@link ByteOrder} of the length field + * @param maxFrameLength the maximum length of the frame. If the length of the frame is + * greater than this value, {@link TooLongFrameException} will be + * thrown. + * @param lengthFieldOffset the offset of the length field + * @param lengthFieldLength the length of the length field + * @param lengthAdjustment the compensation value to add to the value of the length field + * @param initialBytesToStrip the number of first bytes to strip out from the decoded frame + * @param failFast If true, a {@link TooLongFrameException} is thrown as + * soon as the decoder notices the length of the frame will exceed + * maxFrameLength regardless of whether the entire frame + * has been read. If false, a {@link TooLongFrameException} + * is thrown after the entire frame that exceeds maxFrameLength + * has been read. + */ + public NettyProxyMsgDecoder(ByteOrder byteOrder, int maxFrameLength, int lengthFieldOffset, int lengthFieldLength, int lengthAdjustment, int initialBytesToStrip, boolean failFast) { + super(byteOrder, maxFrameLength, lengthFieldOffset, lengthFieldLength, lengthAdjustment, initialBytesToStrip, failFast); + } + + /** + * Create a frame out of the {@link ByteBuf} and return it. + * + * @param ctx the {@link ChannelHandlerContext} which this {@link ByteToMessageDecoder} belongs to + * @param in2 the {@link ByteBuf} from which to read data + * @return frame the {@link ByteBuf} which represent the frame or {@code null} if no frame could + * be created. + */ + @Override + protected NettyProxyMsg decode(ChannelHandlerContext ctx, ByteBuf in2) throws Exception { + // 解码顺序 body 长度 type 1 clientId 4 clientTargetIp 4 clientTargetPort 4 visitorPort 4 visitorId 4 data 4 + ByteBuf in = (ByteBuf) super.decode(ctx, in2); + if (in == null) { + return null; + } + + if (in.readableBytes() < 4) { + return null; + } + + NettyProxyMsg nettyProxyMsg = new NettyProxyMsg(); + int bodyLength = in.readInt(); + byte type = in.readByte(); + nettyProxyMsg.setType(type); + + int clientIdLength = in.readInt(); + byte[] clientIdBytes = new byte[clientIdLength]; + in.readBytes(clientIdBytes); + nettyProxyMsg.setClientId(clientIdBytes); + + int clientTargetIpLength = in.readInt(); + byte[] clientTargetIpBytes = new byte[clientTargetIpLength]; + in.readBytes(clientTargetIpBytes); + nettyProxyMsg.setClientTargetIp(clientTargetIpBytes); + + + int clientTargetPortLength = in.readInt(); + byte[] clientTargetPortBytes = new byte[clientTargetPortLength]; + in.readBytes(clientTargetPortBytes); + nettyProxyMsg.setClientTargetPort(clientTargetPortBytes); + + int visitorPortLength = in.readInt(); + byte[] visitorPortBytes = new byte[visitorPortLength]; + in.readBytes(visitorPortBytes); + nettyProxyMsg.setVisitorPort(visitorPortBytes); + + + int visitorIdLength = in.readInt(); + byte[] visitorIdBytes = new byte[visitorIdLength]; + in.readBytes(visitorIdBytes); + nettyProxyMsg.setVisitorId(visitorIdBytes); + + byte[] data = new byte[bodyLength - NettyProxyMsg.bodyLength - + clientIdLength - + clientTargetIpLength - + clientTargetPortLength - + visitorPortLength - + visitorIdLength]; + in.readBytes(data); + nettyProxyMsg.setData(data); + in.release(); + + return nettyProxyMsg; + } +} diff --git a/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/encoder/NettMsgEncoder.java b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/encoder/NettMsgEncoder.java new file mode 100644 index 0000000..b2227f1 --- /dev/null +++ b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/encoder/NettMsgEncoder.java @@ -0,0 +1,48 @@ +package wu.framework.middleground.cloud.heartbeat.common.encoder; + +import wu.framework.middleground.cloud.heartbeat.common.NettyMsg; +import wu.framework.middleground.cloud.heartbeat.common.NettyProxyMsg; +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.MessageToByteEncoder; + +/** + * @see NettyProxyMsg + * NettyProxyMsg 对象编码 + */ +public class NettMsgEncoder extends MessageToByteEncoder { + + public NettMsgEncoder() { + + } + + @Override + protected void encode(ChannelHandlerContext ctx, NettyMsg nettyMsg, ByteBuf out) throws Exception { + // type 1 data 4 clientId 4 + int bodyLength = NettyMsg.bodyLength; + byte[] clientIdBytes = nettyMsg.getClientId(); + + if (nettyMsg.getData() != null) { + bodyLength += nettyMsg.getData().length; + } + if (nettyMsg.getClientId() != null) { + bodyLength += nettyMsg.getClientId().length; + } + + out.writeInt(bodyLength); + + out.writeByte(nettyMsg.getType()); + // 客户端ID + // 防止数据读错位置 + if (clientIdBytes != null) { + out.writeInt(clientIdBytes.length); + out.writeBytes(clientIdBytes); + }else { + // 防止客户端ID未填写 + out.writeInt(0x00); + } + if (nettyMsg.getData() != null) { + out.writeBytes(nettyMsg.getData()); + } + } +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/encoder/NettyProxyMsgEncoder.java b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/encoder/NettyProxyMsgEncoder.java new file mode 100644 index 0000000..9982db8 --- /dev/null +++ b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/encoder/NettyProxyMsgEncoder.java @@ -0,0 +1,106 @@ +package wu.framework.middleground.cloud.heartbeat.common.encoder; + +import wu.framework.middleground.cloud.heartbeat.common.NettyProxyMsg; +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.MessageToByteEncoder; + +/** + * @see NettyProxyMsg + * NettyProxyMsg 编码 + */ +public class NettyProxyMsgEncoder extends MessageToByteEncoder { + /** + * Encode a message into a {@link ByteBuf}. This method will be called for each written message that can be handled + * by this encoder. + * + * @param ctx the {@link ChannelHandlerContext} which this {@link MessageToByteEncoder} belongs to + * @param msg the message to encode + * @param out the {@link ByteBuf} into which the encoded message will be written + */ + @Override + protected void encode(ChannelHandlerContext ctx, NettyProxyMsg msg, ByteBuf out) { + // body 长度 type 1 clientId 4 clientTargetIp 4 clientTargetPort 4 visitorPort 4 visitorId 4 data 4 + int bodyLength = NettyProxyMsg.bodyLength; + byte typeBytes = msg.getType(); + byte[] clientIdBytes = msg.getClientId(); + byte[] clientTargetIpBytes = msg.getClientTargetIp(); + byte[] clientTargetPortBytes = msg.getClientTargetPort(); + byte[] visitorPortBytes = msg.getVisitorPort(); + byte[] visitorIdBytes = msg.getVisitorId(); + byte[] msgDataBytes = msg.getData(); + + + if (clientIdBytes != null) { + bodyLength += clientIdBytes.length; + } + if (clientTargetIpBytes != null) { + bodyLength += clientTargetIpBytes.length; + } + if (clientTargetPortBytes != null) { + bodyLength += clientTargetPortBytes.length; + } + if (visitorPortBytes != null) { + bodyLength += visitorPortBytes.length; + } + if (visitorIdBytes != null) { + bodyLength += visitorIdBytes.length; + } + + if (msgDataBytes != null) { + bodyLength += msgDataBytes.length; + } + + out.writeInt(bodyLength); + + out.writeByte(typeBytes); + + // 防止数据读错位置 clientId + if (clientIdBytes != null) { + out.writeInt(clientIdBytes.length); + out.writeBytes(clientIdBytes); + } else { + // 防止客户端id 未填写 + out.writeInt(0x00); + } + + + // 防止数据读错位置 clientTargetIp + if (clientTargetIpBytes != null) { + out.writeInt(clientTargetIpBytes.length); + out.writeBytes(clientTargetIpBytes); + } else { + // 防止客户端 目标IP未填写 + out.writeInt(0x00); + } + + // clientTargetPort + if (clientTargetPortBytes != null) { + out.writeInt(clientTargetPortBytes.length); + out.writeBytes(clientTargetPortBytes); + } else { + // 防止客户端目标端口未填写 + out.writeInt(0x00); + } + + // visitorPort + if (visitorPortBytes != null) { + out.writeInt(visitorPortBytes.length); + out.writeBytes(visitorPortBytes); + } else { + // 防止客户端 访客端口未填写 + out.writeInt(0x00); + } + + if (visitorIdBytes != null) { + out.writeInt(visitorIdBytes.length); + out.writeBytes(visitorIdBytes); + } else { + // 防止客户端 访客ID未填写 + out.writeInt(0x00); + } + if (msgDataBytes != null) { + out.writeBytes(msgDataBytes); + } + } +} diff --git a/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/enums/MessageTypeEnums.java b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/enums/MessageTypeEnums.java new file mode 100644 index 0000000..a815289 --- /dev/null +++ b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/enums/MessageTypeEnums.java @@ -0,0 +1,91 @@ +package wu.framework.middleground.cloud.heartbeat.common.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import wu.framework.middleground.cloud.heartbeat.common.MessageType; +import wu.framework.middleground.cloud.heartbeat.common.advanced.AbstractChannelHeartbeatTypeAdvanced; +import wu.framework.middleground.cloud.heartbeat.common.advanced.client.*; +import wu.framework.middleground.cloud.heartbeat.common.advanced.server.*; + +/** + * @see MessageType + */ +@Getter +@AllArgsConstructor +public enum MessageTypeEnums { + /** + * @see AbstractChannelHeartbeatTypeAdvanced + */ + TYPE_HEARTBEAT(MessageType.TYPE_HEARTBEAT, "心跳"), + /** + * @see AbstractReportConnectSuccessTypeAdvanced + */ + REPORT_CLIENT_CONNECT_SUCCESS(MessageType.REPORT_CLIENT_CONNECT_SUCCESS, "上报 客户端连接成功"), + /** + * @see AbstractReportDisconnectTypeAdvanced + */ + REPORT_CLIENT_DISCONNECTION(MessageType.REPORT_CLIENT_DISCONNECTION, "上报 客户端断开连接"), + /** + * @see AbstractReportStagingOpenedTypeAdvanced + */ + REPORT_CLIENT_STAGING_OPENED(MessageType.REPORT_CLIENT_STAGING_OPENED, "上报 客户端暂存开启"), + /** + * @see AbstractReportStagingClosedTypeAdvanced + */ + REPORT_CLIENT_STAGING_CLOSED(MessageType.REPORT_CLIENT_STAGING_CLOSED, "上报 客户端暂存关闭"), + /** + * @see AbstractReportChannelTransferTypeAdvanced + */ + + REPORT_CLIENT_TRANSFER(MessageType.REPORT_CLIENT_TRANSFER, "上报 客户端数据传输(内网穿透数据回传)"), + /** + * @see AbstractReportSingleClientRealConnectTypeAdvanced + */ + REPORT_SINGLE_CLIENT_REAL_CONNECT(MessageType.REPORT_SINGLE_CLIENT_REAL_CONNECT, "上报 客户端创建需要代理的真实端口成功"), + /** + * @see AbstractReportSingleClientCloseVisitorTypeAdvanced + */ + REPORT_SINGLE_CLIENT_CLOSE_VISITOR(MessageType.REPORT_SINGLE_CLIENT_CLOSE_VISITOR, "上报 客户端关闭一个访客通道"), + /** + * @see AbstractDistributeConnectSuccessNotificationTypeAdvanced + */ + + DISTRIBUTE_CLIENT_CONNECTION_SUCCESS_NOTIFICATION(MessageType.DISTRIBUTE_CLIENT_CONNECTION_SUCCESS_NOTIFICATION, "下发 客户端接收连接成功通知"), + + + + + /** + * @see AbstractDistributeDisconnectTypeAdvanced + */ + DISTRIBUTE_CLIENT_DISCONNECTION_NOTIFICATION(MessageType.DISTRIBUTE_CLIENT_DISCONNECTION_NOTIFICATION, "下发 客户端断开连接通知"), + /** + * @see AbstractDistributeStagingOpenedTypeAdvanced + */ + DISTRIBUTE_CLIENT_STAGING_OPENED_NOTIFICATION(MessageType.DISTRIBUTE_CLIENT_STAGING_OPENED_NOTIFICATION, "下发 客户端暂存开启通知"), + /** + * @see AbstractDistributeStagingClosedTypeAdvanced + */ + DISTRIBUTE_CLIENT_STAGING_CLOSED_NOTIFICATION(MessageType.DISTRIBUTE_CLIENT_STAGING_CLOSED_NOTIFICATION, "下发 客户端暂存关闭通知"), + /** + * @see AbstractDistributeChannelTransferTypeAdvanced + */ + DISTRIBUTE_CLIENT_TRANSFER(MessageType.DISTRIBUTE_CLIENT_TRANSFER, "下发 客户端数据传输(内网穿透数据发送)"), + /** + * @see AbstractDistributeSingleClientRealConnectTypeAdvanced + */ + DISTRIBUTE_SINGLE_CLIENT_REAL_CONNECT(MessageType.DISTRIBUTE_SINGLE_CLIENT_REAL_CONNECT, "下发 客户端创建需要代理的真实端口"), + /** + * @see AbstractDistributeSingleClientRealAutoReadConnectTypeAdvanced + */ + DISTRIBUTE_SINGLE_CLIENT_REAL_CONNECT_AUTO_READ(MessageType.DISTRIBUTE_SINGLE_CLIENT_REAL_CONNECT_AUTO_READ, "下发 客户端代理的真实端口自动读写"), + /** + * @see AbstractDistributeSingleClientRealCloseVisitorTypeAdvanced + */ + DISTRIBUTE_SINGLE_CLIENT_REAL_CLOSE_VISITOR(MessageType.DISTRIBUTE_SINGLE_CLIENT_REAL_CLOSE_VISITOR, "下发 客户端关闭代理服务通道"), + + ; + + private final byte typeByte; + private final String desc; +} diff --git a/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/enums/NettyClientStatus.java b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/enums/NettyClientStatus.java new file mode 100644 index 0000000..d37e2aa --- /dev/null +++ b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/enums/NettyClientStatus.java @@ -0,0 +1,17 @@ +package wu.framework.middleground.cloud.heartbeat.common.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * netty客户端 状态 + */ +@AllArgsConstructor +@Getter +public enum NettyClientStatus { + + ON_LINE("在线"), + OFF_LINE("离线"); + + private final String desc; +} diff --git a/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/state/ClientOnLineState.java b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/state/ClientOnLineState.java new file mode 100644 index 0000000..e71c186 --- /dev/null +++ b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/state/ClientOnLineState.java @@ -0,0 +1,18 @@ +package wu.framework.middleground.cloud.heartbeat.common.state; + +import lombok.Data; + +/** + * 客户端在线状态 + */ +@Data +public class ClientOnLineState { + /** + * 客户端ID + */ + private String clientId; + /** + * 在线状态 + */ + private String onLineState; +} diff --git a/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/utils/ChannelAttributeKeyUtils.java b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/utils/ChannelAttributeKeyUtils.java new file mode 100644 index 0000000..40b9ba6 --- /dev/null +++ b/lazy-cloud-heartbeat-common/src/main/java/wu/framework/middleground/cloud/heartbeat/common/utils/ChannelAttributeKeyUtils.java @@ -0,0 +1,70 @@ +package wu.framework.middleground.cloud.heartbeat.common.utils; + +import io.netty.channel.Channel; +import io.netty.util.AttributeKey; + +/** + * 通道属性绑定工具 + */ +public class ChannelAttributeKeyUtils { + + private static final AttributeKey VISITOR_ID = AttributeKey.newInstance("visitorId"); + private static final AttributeKey CLIENT_ID = AttributeKey.newInstance("clientId"); + + + /** + * 为通道绑定 访客属性 + * + * @param channel 通道 + * @param visitorId 访客ID + */ + public static void buildVisitorId(Channel channel, byte[] visitorId) { + channel.attr(VISITOR_ID).set(new String(visitorId)); + } + + /** + * 为通道绑定 访客属性 + * + * @param channel 通道 + * @param visitorId 访客ID + */ + public static void buildVisitorId(Channel channel, String visitorId) { + channel.attr(VISITOR_ID).set(visitorId); + } + + /** + * 获取 通道中访客ID + * @param channel 通道 + */ + public static String getVisitorId(Channel channel) { + return channel.attr(VISITOR_ID).get(); + } + + + /** + * 为通道绑定 访客属性 + * + * @param channel 通道 + * @param clientId 客户端ID + */ + public static void buildClientId(Channel channel, byte[] clientId) { + channel.attr(CLIENT_ID).set(new String(clientId)); + } + /** + * 为通道绑定 访客属性 + * + * @param channel 通道 + * @param clientId 客户端ID + */ + public static void buildClientId(Channel channel, String clientId) { + channel.attr(CLIENT_ID).set(clientId); + } + + /** + * 获取 通道中访客ID + * @param channel 通道 + */ + public static String getClientId(Channel channel) { + return channel.attr(CLIENT_ID).get(); + } +} diff --git a/lazy-cloud-heartbeat-server/pom.xml b/lazy-cloud-heartbeat-server/pom.xml new file mode 100644 index 0000000..e81daeb --- /dev/null +++ b/lazy-cloud-heartbeat-server/pom.xml @@ -0,0 +1,68 @@ + + + + top.wu2020 + lazy-cloud-network + 1.2.1-JDK17-SNAPSHOT + + + 4.0.0 + + lazy-cloud-heartbeat-server + 云上心跳服务端 + + + 17 + 17 + + + + + top.wu2020 + wu-framework-web + + + + top.wu2020 + lazy-cloud-heartbeat-common + 1.2.1-JDK17-SNAPSHOT + + + + mysql + mysql-connector-java + 8.0.33 + + + top.wu2020 + wu-database-lazy-starter + + + top.wu2020 + wu-database-lazy-plus-starter + + + com.alibaba + fastjson + 2.0.33 + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + org.apache.maven.plugins + maven-deploy-plugin + + true + + + + + \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/MiddlegroundOnCloudHeartbeatServer.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/MiddlegroundOnCloudHeartbeatServer.java new file mode 100644 index 0000000..5af9755 --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/MiddlegroundOnCloudHeartbeatServer.java @@ -0,0 +1,14 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * 云上云下-云上心跳服务器 + */ +@SpringBootApplication +public class MiddlegroundOnCloudHeartbeatServer { + public static void main(String[] args) { + SpringApplication.run(MiddlegroundOnCloudHeartbeatServer.class,args); + } +} diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/InternalNetworkPenetrationMappingApplication.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/InternalNetworkPenetrationMappingApplication.java new file mode 100644 index 0000000..dbc3dcb --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/InternalNetworkPenetrationMappingApplication.java @@ -0,0 +1,111 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.application; + + +import wu.framework.middleground.on.cloud.heartbeat.server.domain.application.command.internal.network.penetration.mapping.*; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.application.dto.InternalNetworkPenetrationMappingDTO; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.model.internal.network.penetration.mapping.InternalNetworkPenetrationMapping; +import com.wu.framework.inner.lazy.database.expand.database.persistence.domain.LazyPage; +import com.wu.framework.response.Result; + +import java.util.List; +/** + * describe 内网穿透映射 + * + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + * @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyApplication + **/ + +public interface InternalNetworkPenetrationMappingApplication { + + + /** + * describe 新增内网穿透映射 + * + * @param internalNetworkPenetrationMappingStoryCommand 新增内网穿透映射 + * @return {@link Result} 内网穿透映射新增后领域对象 + + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + **/ + + Result story(InternalNetworkPenetrationMappingStoryCommand internalNetworkPenetrationMappingStoryCommand); + + /** + * describe 批量新增内网穿透映射 + * + * @param internalNetworkPenetrationMappingStoryCommandList 批量新增内网穿透映射 + * @return {@link Result>} 内网穿透映射新增后领域对象集合 + + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + **/ + + Result> batchStory(List internalNetworkPenetrationMappingStoryCommandList); + + /** + * describe 更新内网穿透映射 + * + * @param internalNetworkPenetrationMappingUpdateCommand 更新内网穿透映射 + * @return {@link Result} 内网穿透映射领域对象 + + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + **/ + + Result updateOne(InternalNetworkPenetrationMappingUpdateCommand internalNetworkPenetrationMappingUpdateCommand); + + /** + * describe 查询单个内网穿透映射 + * + * @param internalNetworkPenetrationMappingQueryOneCommand 查询单个内网穿透映射 + * @return {@link Result< InternalNetworkPenetrationMappingDTO >} 内网穿透映射DTO对象 + + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + **/ + + Result findOne(InternalNetworkPenetrationMappingQueryOneCommand internalNetworkPenetrationMappingQueryOneCommand); + + /** + * describe 查询多个内网穿透映射 + * + * @param internalNetworkPenetrationMappingQueryListCommand 查询多个内网穿透映射 + * @return {@link Result >} 内网穿透映射DTO对象 + + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + **/ + + Result > findList(InternalNetworkPenetrationMappingQueryListCommand internalNetworkPenetrationMappingQueryListCommand); + + /** + * describe 分页查询多个内网穿透映射 + * + * @param internalNetworkPenetrationMappingQueryListCommand 分页查询多个内网穿透映射 + * @return {@link Result >} 分页内网穿透映射DTO对象 + + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + **/ + + Result > findPage(int size,int current,InternalNetworkPenetrationMappingQueryListCommand internalNetworkPenetrationMappingQueryListCommand); + + /** + * describe 删除内网穿透映射 + * + * @param internalNetworkPenetrationMappingRemoveCommand 删除内网穿透映射 + * @return {@link Result} 内网穿透映射 + + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + **/ + + Result remove(InternalNetworkPenetrationMappingRemoveCommand internalNetworkPenetrationMappingRemoveCommand); + + /** + * 创建客户端的访问者 + * @param clientId 客户端ID + */ + Result createVisitor(String clientId); +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/NettyClientBlacklistApplication.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/NettyClientBlacklistApplication.java new file mode 100644 index 0000000..8bb9e69 --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/NettyClientBlacklistApplication.java @@ -0,0 +1,116 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.application; + +import wu.framework.middleground.on.cloud.heartbeat.server.domain.application.command.netty.client.blacklist.*; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.application.dto.NettyClientBlacklistDTO; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.model.netty.client.blacklist.NettyClientBlacklist; +import com.wu.framework.inner.lazy.database.expand.database.persistence.domain.LazyPage; +import com.wu.framework.response.Result; + +import java.util.List; +/** + * describe 客户端黑名单 + * + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + * @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyApplication + **/ + +public interface NettyClientBlacklistApplication { + + + /** + * describe 新增客户端黑名单 + * + * @param nettyClientBlacklistStoryCommand 新增客户端黑名单 + * @return {@link Result} 客户端黑名单新增后领域对象 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + Result story(NettyClientBlacklistStoryCommand nettyClientBlacklistStoryCommand); + + /** + * describe 批量新增客户端黑名单 + * + * @param nettyClientBlacklistStoryCommandList 批量新增客户端黑名单 + * @return {@link Result>} 客户端黑名单新增后领域对象集合 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + Result> batchStory(List nettyClientBlacklistStoryCommandList); + + /** + * describe 更新客户端黑名单 + * + * @param nettyClientBlacklistUpdateCommand 更新客户端黑名单 + * @return {@link Result} 客户端黑名单领域对象 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + Result updateOne(NettyClientBlacklistUpdateCommand nettyClientBlacklistUpdateCommand); + + /** + * describe 查询单个客户端黑名单 + * + * @param nettyClientBlacklistQueryOneCommand 查询单个客户端黑名单 + * @return {@link Result< NettyClientBlacklistDTO >} 客户端黑名单DTO对象 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + Result findOne(NettyClientBlacklistQueryOneCommand nettyClientBlacklistQueryOneCommand); + + /** + * describe 查询多个客户端黑名单 + * + * @param nettyClientBlacklistQueryListCommand 查询多个客户端黑名单 + * @return {@link Result >} 客户端黑名单DTO对象 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + Result > findList(NettyClientBlacklistQueryListCommand nettyClientBlacklistQueryListCommand); + + /** + * describe 分页查询多个客户端黑名单 + * + * @param nettyClientBlacklistQueryListCommand 分页查询多个客户端黑名单 + * @return {@link Result >} 分页客户端黑名单DTO对象 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + Result > findPage(int size,int current,NettyClientBlacklistQueryListCommand nettyClientBlacklistQueryListCommand); + + /** + * describe 删除客户端黑名单 + * + * @param nettyClientBlacklistRemoveCommand 删除客户端黑名单 + * @return {@link Result} 客户端黑名单 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + Result remove(NettyClientBlacklistRemoveCommand nettyClientBlacklistRemoveCommand); + + /** + * describe 是否存在客户端黑名单 + * + * @param nettyClientBlacklist 是否存在客户端黑名单 + * @return {@link Result} 客户端黑名单是否存在 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + Result exists(NettyClientBlacklist nettyClientBlacklist); +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/NettyClientStateApplication.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/NettyClientStateApplication.java new file mode 100644 index 0000000..0a250a3 --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/NettyClientStateApplication.java @@ -0,0 +1,107 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.application; + + +import com.wu.framework.inner.lazy.database.expand.database.persistence.domain.LazyPage; +import com.wu.framework.response.Result; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.application.command.netty.client.state.*; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.application.dto.NettyClientStateDTO; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.model.netty.client.state.NettyClientState; + +import java.util.List; + +/** + * describe 客户端状态 + * + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + * @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyApplication + **/ + +public interface NettyClientStateApplication { + + + /** + * describe 新增客户端状态 + * + * @param nettyClientStateStoryCommand 新增客户端状态 + * @return {@link Result< NettyClientState >} 客户端状态新增后领域对象 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + Result story(NettyClientStateStoryCommand nettyClientStateStoryCommand); + + /** + * describe 批量新增客户端状态 + * + * @param nettyClientStateStoryCommandList 批量新增客户端状态 + * @return {@link Result>} 客户端状态新增后领域对象集合 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + Result> batchStory(List nettyClientStateStoryCommandList); + + /** + * describe 更新客户端状态 + * + * @param nettyClientStateUpdateCommand 更新客户端状态 + * @return {@link Result} 客户端状态领域对象 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + Result updateOne(NettyClientStateUpdateCommand nettyClientStateUpdateCommand); + + /** + * describe 查询单个客户端状态 + * + * @param nettyClientStateQueryOneCommand 查询单个客户端状态 + * @return {@link Result< NettyClientStateDTO >} 客户端状态DTO对象 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + Result findOne(NettyClientStateQueryOneCommand nettyClientStateQueryOneCommand); + + /** + * describe 查询多个客户端状态 + * + * @param nettyClientStateQueryListCommand 查询多个客户端状态 + * @return {@link Result >} 客户端状态DTO对象 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + Result > findList(NettyClientStateQueryListCommand nettyClientStateQueryListCommand); + + /** + * describe 分页查询多个客户端状态 + * + * @param nettyClientStateQueryListCommand 分页查询多个客户端状态 + * @return {@link Result >} 分页客户端状态DTO对象 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + Result > findPage(int size, int current, NettyClientStateQueryListCommand nettyClientStateQueryListCommand); + + /** + * describe 删除客户端状态 + * + * @param nettyClientStateRemoveCommand 删除客户端状态 + * @return {@link Result} 客户端状态 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + Result remove(NettyClientStateRemoveCommand nettyClientStateRemoveCommand); + +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/ServerNettyConfigApplication.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/ServerNettyConfigApplication.java new file mode 100644 index 0000000..c9b3ead --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/ServerNettyConfigApplication.java @@ -0,0 +1,34 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.application; + +/** + * 云下心跳客户端操作nacos 配置 + */ +public interface ServerNettyConfigApplication { + + + /** + * 客户端在线 + * @param clientId 客户端ID + */ + void clientOnLine(String clientId); + + /** + * 客户端离线 + * @param clientId 客户端ID + */ + void clientOffLine(String clientId); + + /** + * 客户端暂存关闭 + * @param clientId 客户端ID + */ + void stagingClosed(String clientId); + + + /** + * 客户端暂存开启 + * @param clientId 客户端ID + */ + void stagingOpened(String clientId); + +} diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/assembler/InternalNetworkPenetrationMappingDTOAssembler.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/assembler/InternalNetworkPenetrationMappingDTOAssembler.java new file mode 100644 index 0000000..586a306 --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/assembler/InternalNetworkPenetrationMappingDTOAssembler.java @@ -0,0 +1,89 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.application.assembler; + +import wu.framework.middleground.on.cloud.heartbeat.server.domain.application.command.internal.network.penetration.mapping.*; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.application.dto.InternalNetworkPenetrationMappingDTO; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.model.internal.network.penetration.mapping.InternalNetworkPenetrationMapping; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; +/** + * describe 内网穿透映射 + * + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + * @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyAssembler + **/ +@Mapper +public interface InternalNetworkPenetrationMappingDTOAssembler { + + + /** + * describe MapStruct 创建的代理对象 + * + + + + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + **/ + InternalNetworkPenetrationMappingDTOAssembler INSTANCE = Mappers.getMapper(InternalNetworkPenetrationMappingDTOAssembler.class); + /** + * describe 应用层存储入参转换成 领域对象 + * + * @param internalNetworkPenetrationMappingStoryCommand 保存内网穿透映射对象 + * @return {@link InternalNetworkPenetrationMapping} 内网穿透映射领域对象 + + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + **/ + InternalNetworkPenetrationMapping toInternalNetworkPenetrationMapping(InternalNetworkPenetrationMappingStoryCommand internalNetworkPenetrationMappingStoryCommand); + /** + * describe 应用层更新入参转换成 领域对象 + * + * @param internalNetworkPenetrationMappingUpdateCommand 更新内网穿透映射对象 + * @return {@link InternalNetworkPenetrationMapping} 内网穿透映射领域对象 + + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + **/ + InternalNetworkPenetrationMapping toInternalNetworkPenetrationMapping(InternalNetworkPenetrationMappingUpdateCommand internalNetworkPenetrationMappingUpdateCommand); + /** + * describe 应用层查询入参转换成 领域对象 + * + * @param internalNetworkPenetrationMappingQueryOneCommand 查询单个内网穿透映射对象参数 + * @return {@link InternalNetworkPenetrationMapping} 内网穿透映射领域对象 + + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + **/ + InternalNetworkPenetrationMapping toInternalNetworkPenetrationMapping(InternalNetworkPenetrationMappingQueryOneCommand internalNetworkPenetrationMappingQueryOneCommand); + /** + * describe 应用层查询入参转换成 领域对象 + * + * @param internalNetworkPenetrationMappingQueryListCommand 查询集合内网穿透映射对象参数 + * @return {@link InternalNetworkPenetrationMapping} 内网穿透映射领域对象 + + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + **/ + InternalNetworkPenetrationMapping toInternalNetworkPenetrationMapping(InternalNetworkPenetrationMappingQueryListCommand internalNetworkPenetrationMappingQueryListCommand); + /** + * describe 应用层删除入参转换成 领域对象 + * + * @param internalNetworkPenetrationMappingRemoveCommand 删除内网穿透映射对象参数 + * @return {@link InternalNetworkPenetrationMapping} 内网穿透映射领域对象 + + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + **/ + InternalNetworkPenetrationMapping toInternalNetworkPenetrationMapping(InternalNetworkPenetrationMappingRemoveCommand internalNetworkPenetrationMappingRemoveCommand); + /** + * describe 持久层领域对象转换成DTO对象 + * + * @param internalNetworkPenetrationMapping 内网穿透映射领域对象 + * @return {@link InternalNetworkPenetrationMappingDTO} 内网穿透映射DTO对象 + + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + **/ + InternalNetworkPenetrationMappingDTO fromInternalNetworkPenetrationMapping(InternalNetworkPenetrationMapping internalNetworkPenetrationMapping); +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/assembler/NettyClientBlacklistDTOAssembler.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/assembler/NettyClientBlacklistDTOAssembler.java new file mode 100644 index 0000000..efad235 --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/assembler/NettyClientBlacklistDTOAssembler.java @@ -0,0 +1,89 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.application.assembler; + +import wu.framework.middleground.on.cloud.heartbeat.server.domain.application.command.netty.client.blacklist.*; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.application.dto.NettyClientBlacklistDTO; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.model.netty.client.blacklist.NettyClientBlacklist; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; +/** + * describe 客户端黑名单 + * + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + * @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyAssembler + **/ +@Mapper +public interface NettyClientBlacklistDTOAssembler { + + + /** + * describe MapStruct 创建的代理对象 + * + + + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + NettyClientBlacklistDTOAssembler INSTANCE = Mappers.getMapper(NettyClientBlacklistDTOAssembler.class); + /** + * describe 应用层存储入参转换成 领域对象 + * + * @param nettyClientBlacklistStoryCommand 保存客户端黑名单对象 + * @return {@link NettyClientBlacklist} 客户端黑名单领域对象 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + NettyClientBlacklist toNettyClientBlacklist(NettyClientBlacklistStoryCommand nettyClientBlacklistStoryCommand); + /** + * describe 应用层更新入参转换成 领域对象 + * + * @param nettyClientBlacklistUpdateCommand 更新客户端黑名单对象 + * @return {@link NettyClientBlacklist} 客户端黑名单领域对象 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + NettyClientBlacklist toNettyClientBlacklist(NettyClientBlacklistUpdateCommand nettyClientBlacklistUpdateCommand); + /** + * describe 应用层查询入参转换成 领域对象 + * + * @param nettyClientBlacklistQueryOneCommand 查询单个客户端黑名单对象参数 + * @return {@link NettyClientBlacklist} 客户端黑名单领域对象 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + NettyClientBlacklist toNettyClientBlacklist(NettyClientBlacklistQueryOneCommand nettyClientBlacklistQueryOneCommand); + /** + * describe 应用层查询入参转换成 领域对象 + * + * @param nettyClientBlacklistQueryListCommand 查询集合客户端黑名单对象参数 + * @return {@link NettyClientBlacklist} 客户端黑名单领域对象 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + NettyClientBlacklist toNettyClientBlacklist(NettyClientBlacklistQueryListCommand nettyClientBlacklistQueryListCommand); + /** + * describe 应用层删除入参转换成 领域对象 + * + * @param nettyClientBlacklistRemoveCommand 删除客户端黑名单对象参数 + * @return {@link NettyClientBlacklist} 客户端黑名单领域对象 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + NettyClientBlacklist toNettyClientBlacklist(NettyClientBlacklistRemoveCommand nettyClientBlacklistRemoveCommand); + /** + * describe 持久层领域对象转换成DTO对象 + * + * @param nettyClientBlacklist 客户端黑名单领域对象 + * @return {@link NettyClientBlacklistDTO} 客户端黑名单DTO对象 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + NettyClientBlacklistDTO fromNettyClientBlacklist(NettyClientBlacklist nettyClientBlacklist); +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/assembler/NettyClientStateDTOAssembler.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/assembler/NettyClientStateDTOAssembler.java new file mode 100644 index 0000000..6fb230a --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/assembler/NettyClientStateDTOAssembler.java @@ -0,0 +1,89 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.application.assembler; + +import wu.framework.middleground.on.cloud.heartbeat.server.domain.application.command.netty.client.state.*; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.application.dto.NettyClientStateDTO; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.model.netty.client.state.NettyClientState; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; +/** + * describe 客户端状态 + * + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + * @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyAssembler + **/ +@Mapper +public interface NettyClientStateDTOAssembler { + + + /** + * describe MapStruct 创建的代理对象 + * + + + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + NettyClientStateDTOAssembler INSTANCE = Mappers.getMapper(NettyClientStateDTOAssembler.class); + /** + * describe 应用层存储入参转换成 领域对象 + * + * @param nettyClientStateStoryCommand 保存客户端状态对象 + * @return {@link NettyClientState} 客户端状态领域对象 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + NettyClientState toNettyClientState(NettyClientStateStoryCommand nettyClientStateStoryCommand); + /** + * describe 应用层更新入参转换成 领域对象 + * + * @param nettyClientStateUpdateCommand 更新客户端状态对象 + * @return {@link NettyClientState} 客户端状态领域对象 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + NettyClientState toNettyClientState(NettyClientStateUpdateCommand nettyClientStateUpdateCommand); + /** + * describe 应用层查询入参转换成 领域对象 + * + * @param nettyClientStateQueryOneCommand 查询单个客户端状态对象参数 + * @return {@link NettyClientState} 客户端状态领域对象 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + NettyClientState toNettyClientState(NettyClientStateQueryOneCommand nettyClientStateQueryOneCommand); + /** + * describe 应用层查询入参转换成 领域对象 + * + * @param nettyClientStateQueryListCommand 查询集合客户端状态对象参数 + * @return {@link NettyClientState} 客户端状态领域对象 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + NettyClientState toNettyClientState(NettyClientStateQueryListCommand nettyClientStateQueryListCommand); + /** + * describe 应用层删除入参转换成 领域对象 + * + * @param nettyClientStateRemoveCommand 删除客户端状态对象参数 + * @return {@link NettyClientState} 客户端状态领域对象 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + NettyClientState toNettyClientState(NettyClientStateRemoveCommand nettyClientStateRemoveCommand); + /** + * describe 持久层领域对象转换成DTO对象 + * + * @param nettyClientState 客户端状态领域对象 + * @return {@link NettyClientStateDTO} 客户端状态DTO对象 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + NettyClientStateDTO fromNettyClientState(NettyClientState nettyClientState); +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/internal/network/penetration/mapping/InternalNetworkPenetrationMappingQueryListCommand.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/internal/network/penetration/mapping/InternalNetworkPenetrationMappingQueryListCommand.java new file mode 100644 index 0000000..257002a --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/internal/network/penetration/mapping/InternalNetworkPenetrationMappingQueryListCommand.java @@ -0,0 +1,82 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.application.command.internal.network.penetration.mapping; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.time.LocalDateTime; +/** + * describe 内网穿透映射 + * + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + * @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyQueryListCommand + **/ +@Data +@Accessors(chain = true) +@Schema(title = "internal_network_penetration_mapping_query_List_command",description = "内网穿透映射") +public class InternalNetworkPenetrationMappingQueryListCommand { + + + /** + * + * 客户端ID + */ + @Schema(description ="客户端ID",name ="clientId",example = "") + private String clientId; + + /** + * + * 客户端目标地址 + */ + @Schema(description ="客户端目标地址",name ="clientTargetIp",example = "") + private String clientTargetIp; + + /** + * + * 客户端目标端口 + */ + @Schema(description ="客户端目标端口",name ="clientTargetPort",example = "") + private Integer clientTargetPort; + + /** + * + * 创建时间 + */ + @Schema(description ="创建时间",name ="createTime",example = "") + private LocalDateTime createTime; + + /** + * + * 主键自增 + */ + @Schema(description ="主键自增",name ="id",example = "") + private Long id; + + /** + * + * 是否删除 默认否 + */ + @Schema(description ="是否删除 默认否",name ="isDeleted",example = "") + private Boolean isDeleted; + + /** + * + * 修改时间 + */ + @Schema(description ="修改时间",name ="updateTime",example = "") + private LocalDateTime updateTime; + + /** + * + * 访问端口 + */ + @Schema(description ="访问端口",name ="visitorPort",example = "") + private Integer visitorPort; + /** + * + * 描述 + */ + @Schema(description ="描述",name ="describe",example = "") + private String describe; +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/internal/network/penetration/mapping/InternalNetworkPenetrationMappingQueryOneCommand.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/internal/network/penetration/mapping/InternalNetworkPenetrationMappingQueryOneCommand.java new file mode 100644 index 0000000..7f05d08 --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/internal/network/penetration/mapping/InternalNetworkPenetrationMappingQueryOneCommand.java @@ -0,0 +1,82 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.application.command.internal.network.penetration.mapping; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.time.LocalDateTime; +/** + * describe 内网穿透映射 + * + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + * @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyQueryOneCommand + **/ +@Data +@Accessors(chain = true) +@Schema(title = "internal_network_penetration_mapping_query_one_command",description = "内网穿透映射") +public class InternalNetworkPenetrationMappingQueryOneCommand { + + + /** + * + * 客户端ID + */ + @Schema(description ="客户端ID",name ="clientId",example = "") + private String clientId; + + /** + * + * 客户端目标地址 + */ + @Schema(description ="客户端目标地址",name ="clientTargetIp",example = "") + private String clientTargetIp; + + /** + * + * 客户端目标端口 + */ + @Schema(description ="客户端目标端口",name ="clientTargetPort",example = "") + private Integer clientTargetPort; + + /** + * + * 创建时间 + */ + @Schema(description ="创建时间",name ="createTime",example = "") + private LocalDateTime createTime; + + /** + * + * 主键自增 + */ + @Schema(description ="主键自增",name ="id",example = "") + private Long id; + + /** + * + * 是否删除 默认否 + */ + @Schema(description ="是否删除 默认否",name ="isDeleted",example = "") + private Boolean isDeleted; + + /** + * + * 修改时间 + */ + @Schema(description ="修改时间",name ="updateTime",example = "") + private LocalDateTime updateTime; + + /** + * + * 访问端口 + */ + @Schema(description ="访问端口",name ="visitorPort",example = "") + private Integer visitorPort; + /** + * + * 描述 + */ + @Schema(description ="描述",name ="describe",example = "") + private String describe; +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/internal/network/penetration/mapping/InternalNetworkPenetrationMappingRemoveCommand.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/internal/network/penetration/mapping/InternalNetworkPenetrationMappingRemoveCommand.java new file mode 100644 index 0000000..d546a6f --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/internal/network/penetration/mapping/InternalNetworkPenetrationMappingRemoveCommand.java @@ -0,0 +1,82 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.application.command.internal.network.penetration.mapping; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.time.LocalDateTime; +/** + * describe 内网穿透映射 + * + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + * @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyRemoveCommand + **/ +@Data +@Accessors(chain = true) +@Schema(title = "internal_network_penetration_mapping_remove_command",description = "内网穿透映射") +public class InternalNetworkPenetrationMappingRemoveCommand { + + + /** + * + * 客户端ID + */ + @Schema(description ="客户端ID",name ="clientId",example = "") + private String clientId; + + /** + * + * 客户端目标地址 + */ + @Schema(description ="客户端目标地址",name ="clientTargetIp",example = "") + private String clientTargetIp; + + /** + * + * 客户端目标端口 + */ + @Schema(description ="客户端目标端口",name ="clientTargetPort",example = "") + private Integer clientTargetPort; + + /** + * + * 创建时间 + */ + @Schema(description ="创建时间",name ="createTime",example = "") + private LocalDateTime createTime; + + /** + * + * 主键自增 + */ + @Schema(description ="主键自增",name ="id",example = "") + private Long id; + + /** + * + * 是否删除 默认否 + */ + @Schema(description ="是否删除 默认否",name ="isDeleted",example = "") + private Boolean isDeleted; + + /** + * + * 修改时间 + */ + @Schema(description ="修改时间",name ="updateTime",example = "") + private LocalDateTime updateTime; + + /** + * + * 访问端口 + */ + @Schema(description ="访问端口",name ="visitorPort",example = "") + private Integer visitorPort; + /** + * + * 描述 + */ + @Schema(description ="描述",name ="describe",example = "") + private String describe; +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/internal/network/penetration/mapping/InternalNetworkPenetrationMappingStoryCommand.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/internal/network/penetration/mapping/InternalNetworkPenetrationMappingStoryCommand.java new file mode 100644 index 0000000..2524137 --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/internal/network/penetration/mapping/InternalNetworkPenetrationMappingStoryCommand.java @@ -0,0 +1,82 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.application.command.internal.network.penetration.mapping; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.time.LocalDateTime; +/** + * describe 内网穿透映射 + * + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + * @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyStoryCommand + **/ +@Data +@Accessors(chain = true) +@Schema(title = "internal_network_penetration_mapping_story_command",description = "内网穿透映射") +public class InternalNetworkPenetrationMappingStoryCommand { + + + /** + * + * 客户端ID + */ + @Schema(description ="客户端ID",name ="clientId",example = "") + private String clientId; + + /** + * + * 客户端目标地址 + */ + @Schema(description ="客户端目标地址",name ="clientTargetIp",example = "") + private String clientTargetIp; + + /** + * + * 客户端目标端口 + */ + @Schema(description ="客户端目标端口",name ="clientTargetPort",example = "") + private Integer clientTargetPort; + + /** + * + * 创建时间 + */ + @Schema(description ="创建时间",name ="createTime",example = "") + private LocalDateTime createTime; + + /** + * + * 主键自增 + */ + @Schema(description ="主键自增",name ="id",example = "") + private Long id; + + /** + * + * 是否删除 默认否 + */ + @Schema(description ="是否删除 默认否",name ="isDeleted",example = "") + private Boolean isDeleted; + + /** + * + * 修改时间 + */ + @Schema(description ="修改时间",name ="updateTime",example = "") + private LocalDateTime updateTime; + + /** + * + * 访问端口 + */ + @Schema(description ="访问端口",name ="visitorPort",example = "") + private Integer visitorPort; + /** + * + * 描述 + */ + @Schema(description ="描述",name ="describe",example = "") + private String describe; +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/internal/network/penetration/mapping/InternalNetworkPenetrationMappingUpdateCommand.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/internal/network/penetration/mapping/InternalNetworkPenetrationMappingUpdateCommand.java new file mode 100644 index 0000000..2443e84 --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/internal/network/penetration/mapping/InternalNetworkPenetrationMappingUpdateCommand.java @@ -0,0 +1,82 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.application.command.internal.network.penetration.mapping; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.time.LocalDateTime; +/** + * describe 内网穿透映射 + * + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + * @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyUpdateCommand + **/ +@Data +@Accessors(chain = true) +@Schema(title = "internal_network_penetration_mapping_update_command",description = "内网穿透映射") +public class InternalNetworkPenetrationMappingUpdateCommand { + + + /** + * + * 客户端ID + */ + @Schema(description ="客户端ID",name ="clientId",example = "") + private String clientId; + + /** + * + * 客户端目标地址 + */ + @Schema(description ="客户端目标地址",name ="clientTargetIp",example = "") + private String clientTargetIp; + + /** + * + * 客户端目标端口 + */ + @Schema(description ="客户端目标端口",name ="clientTargetPort",example = "") + private Integer clientTargetPort; + + /** + * + * 创建时间 + */ + @Schema(description ="创建时间",name ="createTime",example = "") + private LocalDateTime createTime; + + /** + * + * 主键自增 + */ + @Schema(description ="主键自增",name ="id",example = "") + private Long id; + + /** + * + * 是否删除 默认否 + */ + @Schema(description ="是否删除 默认否",name ="isDeleted",example = "") + private Boolean isDeleted; + + /** + * + * 修改时间 + */ + @Schema(description ="修改时间",name ="updateTime",example = "") + private LocalDateTime updateTime; + + /** + * + * 访问端口 + */ + @Schema(description ="访问端口",name ="visitorPort",example = "") + private Integer visitorPort; + /** + * + * 描述 + */ + @Schema(description ="描述",name ="describe",example = "") + private String describe; +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/netty/client/blacklist/NettyClientBlacklistQueryListCommand.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/netty/client/blacklist/NettyClientBlacklistQueryListCommand.java new file mode 100644 index 0000000..ff2862c --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/netty/client/blacklist/NettyClientBlacklistQueryListCommand.java @@ -0,0 +1,56 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.application.command.netty.client.blacklist; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.time.LocalDateTime; +/** + * describe 客户端黑名单 + * + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + * @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyQueryListCommand + **/ +@Data +@Accessors(chain = true) +@Schema(title = "netty_client_blacklist_query_List_command",description = "客户端黑名单") +public class NettyClientBlacklistQueryListCommand { + + + /** + * + * 客户端ID + */ + @Schema(description ="客户端ID",name ="clientId",example = "") + private String clientId; + + /** + * + * 创建时间 + */ + @Schema(description ="创建时间",name ="createTime",example = "") + private LocalDateTime createTime; + + /** + * + * 主键 + */ + @Schema(description ="主键",name ="id",example = "") + private Long id; + + /** + * + * 是否删除 + */ + @Schema(description ="是否删除",name ="isDeleted",example = "") + private Boolean isDeleted; + + /** + * + * 更新时间 + */ + @Schema(description ="更新时间",name ="updateTime",example = "") + private LocalDateTime updateTime; + +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/netty/client/blacklist/NettyClientBlacklistQueryOneCommand.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/netty/client/blacklist/NettyClientBlacklistQueryOneCommand.java new file mode 100644 index 0000000..39eded1 --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/netty/client/blacklist/NettyClientBlacklistQueryOneCommand.java @@ -0,0 +1,56 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.application.command.netty.client.blacklist; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.time.LocalDateTime; +/** + * describe 客户端黑名单 + * + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + * @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyQueryOneCommand + **/ +@Data +@Accessors(chain = true) +@Schema(title = "netty_client_blacklist_query_one_command",description = "客户端黑名单") +public class NettyClientBlacklistQueryOneCommand { + + + /** + * + * 客户端ID + */ + @Schema(description ="客户端ID",name ="clientId",example = "") + private String clientId; + + /** + * + * 创建时间 + */ + @Schema(description ="创建时间",name ="createTime",example = "") + private LocalDateTime createTime; + + /** + * + * 主键 + */ + @Schema(description ="主键",name ="id",example = "") + private Long id; + + /** + * + * 是否删除 + */ + @Schema(description ="是否删除",name ="isDeleted",example = "") + private Boolean isDeleted; + + /** + * + * 更新时间 + */ + @Schema(description ="更新时间",name ="updateTime",example = "") + private LocalDateTime updateTime; + +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/netty/client/blacklist/NettyClientBlacklistRemoveCommand.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/netty/client/blacklist/NettyClientBlacklistRemoveCommand.java new file mode 100644 index 0000000..633ce4e --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/netty/client/blacklist/NettyClientBlacklistRemoveCommand.java @@ -0,0 +1,56 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.application.command.netty.client.blacklist; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.time.LocalDateTime; +/** + * describe 客户端黑名单 + * + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + * @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyRemoveCommand + **/ +@Data +@Accessors(chain = true) +@Schema(title = "netty_client_blacklist_remove_command",description = "客户端黑名单") +public class NettyClientBlacklistRemoveCommand { + + + /** + * + * 客户端ID + */ + @Schema(description ="客户端ID",name ="clientId",example = "") + private String clientId; + + /** + * + * 创建时间 + */ + @Schema(description ="创建时间",name ="createTime",example = "") + private LocalDateTime createTime; + + /** + * + * 主键 + */ + @Schema(description ="主键",name ="id",example = "") + private Long id; + + /** + * + * 是否删除 + */ + @Schema(description ="是否删除",name ="isDeleted",example = "") + private Boolean isDeleted; + + /** + * + * 更新时间 + */ + @Schema(description ="更新时间",name ="updateTime",example = "") + private LocalDateTime updateTime; + +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/netty/client/blacklist/NettyClientBlacklistStoryCommand.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/netty/client/blacklist/NettyClientBlacklistStoryCommand.java new file mode 100644 index 0000000..6ac4bfb --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/netty/client/blacklist/NettyClientBlacklistStoryCommand.java @@ -0,0 +1,60 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.application.command.netty.client.blacklist; + + +import com.wu.framework.response.mark.ValidType; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.time.LocalDateTime; +/** + * describe 客户端黑名单 + * + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + * @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyStoryCommand + **/ +@Data +@Accessors(chain = true) +@Schema(title = "netty_client_blacklist_story_command",description = "客户端黑名单") +public class NettyClientBlacklistStoryCommand { + + + /** + * + * 客户端ID + */ + @NotNull(groups = ValidType.Create.class,message = "客户端ID不允许为空") + @Schema(description ="客户端ID",name ="clientId",example = "") + private String clientId; + + /** + * + * 创建时间 + */ + @Schema(description ="创建时间",name ="createTime",example = "") + private LocalDateTime createTime; + + /** + * + * 主键 + */ + @Schema(description ="主键",name ="id",example = "") + private Long id; + + /** + * + * 是否删除 + */ + @Schema(description ="是否删除",name ="isDeleted",example = "") + private Boolean isDeleted; + + /** + * + * 更新时间 + */ + @Schema(description ="更新时间",name ="updateTime",example = "") + private LocalDateTime updateTime; + +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/netty/client/blacklist/NettyClientBlacklistUpdateCommand.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/netty/client/blacklist/NettyClientBlacklistUpdateCommand.java new file mode 100644 index 0000000..83029cb --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/netty/client/blacklist/NettyClientBlacklistUpdateCommand.java @@ -0,0 +1,56 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.application.command.netty.client.blacklist; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.time.LocalDateTime; +/** + * describe 客户端黑名单 + * + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + * @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyUpdateCommand + **/ +@Data +@Accessors(chain = true) +@Schema(title = "netty_client_blacklist_update_command",description = "客户端黑名单") +public class NettyClientBlacklistUpdateCommand { + + + /** + * + * 客户端ID + */ + @Schema(description ="客户端ID",name ="clientId",example = "") + private String clientId; + + /** + * + * 创建时间 + */ + @Schema(description ="创建时间",name ="createTime",example = "") + private LocalDateTime createTime; + + /** + * + * 主键 + */ + @Schema(description ="主键",name ="id",example = "") + private Long id; + + /** + * + * 是否删除 + */ + @Schema(description ="是否删除",name ="isDeleted",example = "") + private Boolean isDeleted; + + /** + * + * 更新时间 + */ + @Schema(description ="更新时间",name ="updateTime",example = "") + private LocalDateTime updateTime; + +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/netty/client/state/NettyClientStateQueryListCommand.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/netty/client/state/NettyClientStateQueryListCommand.java new file mode 100644 index 0000000..c986d06 --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/netty/client/state/NettyClientStateQueryListCommand.java @@ -0,0 +1,71 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.application.command.netty.client.state; + +import wu.framework.middleground.cloud.heartbeat.common.enums.NettyClientStatus; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.time.LocalDateTime; +/** + * describe 客户端状态 + * + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + * @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyQueryListCommand + **/ +@Data +@Accessors(chain = true) +@Schema(title = "netty_client_state_query_List_command",description = "客户端状态") +public class NettyClientStateQueryListCommand { + + + /** + * + * 客户端ID + */ + @Schema(description ="客户端ID",name ="clientId",example = "") + private String clientId; + + /** + * + * 创建时间 + */ + @Schema(description ="创建时间",name ="createTime",example = "") + private LocalDateTime createTime; + + /** + * + * 主键 + */ + @Schema(description ="主键",name ="id",example = "") + private Long id; + + /** + * + * 是否删除 + */ + @Schema(description ="是否删除",name ="isDeleted",example = "") + private Boolean isDeleted; + + /** + * + * 在线状态(true在线,false离线) + */ + @Schema(description ="在线状态(true在线,false离线)",name ="onLineState",example = "") + private NettyClientStatus onLineState; + + /** + * + * 暂存状态(开启、关闭) + */ + @Schema(description ="暂存状态(开启、关闭)",name ="staging",example = "") + private String stagingState; + + /** + * + * 修改时间 + */ + @Schema(description ="修改时间",name ="updateTime",example = "") + private LocalDateTime updateTime; + +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/netty/client/state/NettyClientStateQueryOneCommand.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/netty/client/state/NettyClientStateQueryOneCommand.java new file mode 100644 index 0000000..10305ad --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/netty/client/state/NettyClientStateQueryOneCommand.java @@ -0,0 +1,71 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.application.command.netty.client.state; + +import wu.framework.middleground.cloud.heartbeat.common.enums.NettyClientStatus; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.time.LocalDateTime; +/** + * describe 客户端状态 + * + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + * @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyQueryOneCommand + **/ +@Data +@Accessors(chain = true) +@Schema(title = "netty_client_state_query_one_command",description = "客户端状态") +public class NettyClientStateQueryOneCommand { + + + /** + * + * 客户端ID + */ + @Schema(description ="客户端ID",name ="clientId",example = "") + private String clientId; + + /** + * + * 创建时间 + */ + @Schema(description ="创建时间",name ="createTime",example = "") + private LocalDateTime createTime; + + /** + * + * 主键 + */ + @Schema(description ="主键",name ="id",example = "") + private Long id; + + /** + * + * 是否删除 + */ + @Schema(description ="是否删除",name ="isDeleted",example = "") + private Boolean isDeleted; + + /** + * + * 在线状态(true在线,false离线) + */ + @Schema(description ="在线状态(true在线,false离线)",name ="onLineState",example = "") + private NettyClientStatus onLineState; + + /** + * + * 暂存状态(开启、关闭) + */ + @Schema(description ="暂存状态(开启、关闭)",name ="staging",example = "") + private String stagingState; + + /** + * + * 修改时间 + */ + @Schema(description ="修改时间",name ="updateTime",example = "") + private LocalDateTime updateTime; + +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/netty/client/state/NettyClientStateRemoveCommand.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/netty/client/state/NettyClientStateRemoveCommand.java new file mode 100644 index 0000000..9cb0e07 --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/netty/client/state/NettyClientStateRemoveCommand.java @@ -0,0 +1,71 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.application.command.netty.client.state; + +import wu.framework.middleground.cloud.heartbeat.common.enums.NettyClientStatus; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.time.LocalDateTime; +/** + * describe 客户端状态 + * + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + * @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyRemoveCommand + **/ +@Data +@Accessors(chain = true) +@Schema(title = "netty_client_state_remove_command",description = "客户端状态") +public class NettyClientStateRemoveCommand { + + + /** + * + * 客户端ID + */ + @Schema(description ="客户端ID",name ="clientId",example = "") + private String clientId; + + /** + * + * 创建时间 + */ + @Schema(description ="创建时间",name ="createTime",example = "") + private LocalDateTime createTime; + + /** + * + * 主键 + */ + @Schema(description ="主键",name ="id",example = "") + private Long id; + + /** + * + * 是否删除 + */ + @Schema(description ="是否删除",name ="isDeleted",example = "") + private Boolean isDeleted; + + /** + * + * 在线状态(true在线,false离线) + */ + @Schema(description ="在线状态(true在线,false离线)",name ="onLineState",example = "") + private NettyClientStatus onLineState; + + /** + * + * 暂存状态(开启、关闭) + */ + @Schema(description ="暂存状态(开启、关闭)",name ="staging",example = "") + private String stagingState; + + /** + * + * 修改时间 + */ + @Schema(description ="修改时间",name ="updateTime",example = "") + private LocalDateTime updateTime; + +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/netty/client/state/NettyClientStateStoryCommand.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/netty/client/state/NettyClientStateStoryCommand.java new file mode 100644 index 0000000..c21c692 --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/netty/client/state/NettyClientStateStoryCommand.java @@ -0,0 +1,71 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.application.command.netty.client.state; + +import wu.framework.middleground.cloud.heartbeat.common.enums.NettyClientStatus; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.time.LocalDateTime; +/** + * describe 客户端状态 + * + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + * @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyStoryCommand + **/ +@Data +@Accessors(chain = true) +@Schema(title = "netty_client_state_story_command",description = "客户端状态") +public class NettyClientStateStoryCommand { + + + /** + * + * 客户端ID + */ + @Schema(description ="客户端ID",name ="clientId",example = "") + private String clientId; + + /** + * + * 创建时间 + */ + @Schema(description ="创建时间",name ="createTime",example = "") + private LocalDateTime createTime; + + /** + * + * 主键 + */ + @Schema(description ="主键",name ="id",example = "") + private Long id; + + /** + * + * 是否删除 + */ + @Schema(description ="是否删除",name ="isDeleted",example = "") + private Boolean isDeleted; + + /** + * + * 在线状态(true在线,false离线) + */ + @Schema(description ="在线状态(true在线,false离线)",name ="onLineState",example = "") + private NettyClientStatus onLineState; + + /** + * + * 暂存状态(开启、关闭) + */ + @Schema(description ="暂存状态(开启、关闭)",name ="staging",example = "") + private String stagingState; + + /** + * + * 修改时间 + */ + @Schema(description ="修改时间",name ="updateTime",example = "") + private LocalDateTime updateTime; + +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/netty/client/state/NettyClientStateUpdateCommand.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/netty/client/state/NettyClientStateUpdateCommand.java new file mode 100644 index 0000000..4f280d8 --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/command/netty/client/state/NettyClientStateUpdateCommand.java @@ -0,0 +1,71 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.application.command.netty.client.state; + +import wu.framework.middleground.cloud.heartbeat.common.enums.NettyClientStatus; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.time.LocalDateTime; +/** + * describe 客户端状态 + * + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + * @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyUpdateCommand + **/ +@Data +@Accessors(chain = true) +@Schema(title = "netty_client_state_update_command",description = "客户端状态") +public class NettyClientStateUpdateCommand { + + + /** + * + * 客户端ID + */ + @Schema(description ="客户端ID",name ="clientId",example = "") + private String clientId; + + /** + * + * 创建时间 + */ + @Schema(description ="创建时间",name ="createTime",example = "") + private LocalDateTime createTime; + + /** + * + * 主键 + */ + @Schema(description ="主键",name ="id",example = "") + private Long id; + + /** + * + * 是否删除 + */ + @Schema(description ="是否删除",name ="isDeleted",example = "") + private Boolean isDeleted; + + /** + * + * 在线状态(true在线,false离线) + */ + @Schema(description ="在线状态(true在线,false离线)",name ="onLineState",example = "") + private NettyClientStatus onLineState; + + /** + * + * 暂存状态(开启、关闭) + */ + @Schema(description ="暂存状态(开启、关闭)",name ="staging",example = "") + private String stagingState; + + /** + * + * 修改时间 + */ + @Schema(description ="修改时间",name ="updateTime",example = "") + private LocalDateTime updateTime; + +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/dto/ClientChannelDTO.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/dto/ClientChannelDTO.java new file mode 100644 index 0000000..0b1e891 --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/dto/ClientChannelDTO.java @@ -0,0 +1,26 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.application.dto; + +import io.netty.channel.Channel; +import io.netty.channel.ChannelId; +import lombok.Data; + + + +/** + * 客户端通道 + */ +@Data +public class ClientChannelDTO { + /** + * 连接信息 + */ + private String clientId; + /** + * 通道ID + */ + private ChannelId channelId; + /** + * 通道 + */ + private Channel channel; +} diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/dto/InternalNetworkPenetrationMappingDTO.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/dto/InternalNetworkPenetrationMappingDTO.java new file mode 100644 index 0000000..ef91995 --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/dto/InternalNetworkPenetrationMappingDTO.java @@ -0,0 +1,82 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.application.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.time.LocalDateTime; +/** + * describe 内网穿透映射 + * + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + * @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyDTO + **/ +@Data +@Accessors(chain = true) +@Schema(title = "internal_network_penetration_mapping_command_dto",description = "内网穿透映射") +public class InternalNetworkPenetrationMappingDTO { + + + /** + * + * 客户端ID + */ + @Schema(description ="客户端ID",name ="clientId",example = "") + private String clientId; + + /** + * + * 客户端目标地址 + */ + @Schema(description ="客户端目标地址",name ="clientTargetIp",example = "") + private String clientTargetIp; + + /** + * + * 客户端目标端口 + */ + @Schema(description ="客户端目标端口",name ="clientTargetPort",example = "") + private Integer clientTargetPort; + + /** + * + * 创建时间 + */ + @Schema(description ="创建时间",name ="createTime",example = "") + private LocalDateTime createTime; + + /** + * + * 主键自增 + */ + @Schema(description ="主键自增",name ="id",example = "") + private Long id; + + /** + * + * 是否删除 默认否 + */ + @Schema(description ="是否删除 默认否",name ="isDeleted",example = "") + private Boolean isDeleted; + + /** + * + * 修改时间 + */ + @Schema(description ="修改时间",name ="updateTime",example = "") + private LocalDateTime updateTime; + + /** + * + * 访问端口 + */ + @Schema(description ="访问端口",name ="visitorPort",example = "") + private Integer visitorPort; + /** + * + * 描述 + */ + @Schema(description ="描述",name ="describe",example = "") + private String describe; +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/dto/NettyClientBlacklistDTO.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/dto/NettyClientBlacklistDTO.java new file mode 100644 index 0000000..e0b5575 --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/dto/NettyClientBlacklistDTO.java @@ -0,0 +1,56 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.application.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.time.LocalDateTime; +/** + * describe 客户端黑名单 + * + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + * @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyDTO + **/ +@Data +@Accessors(chain = true) +@Schema(title = "netty_client_blacklist_command_dto",description = "客户端黑名单") +public class NettyClientBlacklistDTO { + + + /** + * + * 客户端ID + */ + @Schema(description ="客户端ID",name ="clientId",example = "") + private String clientId; + + /** + * + * 创建时间 + */ + @Schema(description ="创建时间",name ="createTime",example = "") + private LocalDateTime createTime; + + /** + * + * 主键 + */ + @Schema(description ="主键",name ="id",example = "") + private Long id; + + /** + * + * 是否删除 + */ + @Schema(description ="是否删除",name ="isDeleted",example = "") + private Boolean isDeleted; + + /** + * + * 更新时间 + */ + @Schema(description ="更新时间",name ="updateTime",example = "") + private LocalDateTime updateTime; + +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/dto/NettyClientStateDTO.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/dto/NettyClientStateDTO.java new file mode 100644 index 0000000..86f79fc --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/dto/NettyClientStateDTO.java @@ -0,0 +1,71 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.application.dto; + +import wu.framework.middleground.cloud.heartbeat.common.enums.NettyClientStatus; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.time.LocalDateTime; +/** + * describe 客户端状态 + * + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + * @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyDTO + **/ +@Data +@Accessors(chain = true) +@Schema(title = "netty_client_state_command_dto",description = "客户端状态") +public class NettyClientStateDTO { + + + /** + * + * 客户端ID + */ + @Schema(description ="客户端ID",name ="clientId",example = "") + private String clientId; + + /** + * + * 创建时间 + */ + @Schema(description ="创建时间",name ="createTime",example = "") + private LocalDateTime createTime; + + /** + * + * 主键 + */ + @Schema(description ="主键",name ="id",example = "") + private Long id; + + /** + * + * 是否删除 + */ + @Schema(description ="是否删除",name ="isDeleted",example = "") + private Boolean isDeleted; + + /** + * + * 在线状态(true在线,false离线) + */ + @Schema(description ="在线状态(true在线,false离线)",name ="onLineState",example = "") + private NettyClientStatus onLineState; + + /** + * + * 暂存状态(开启、关闭) + */ + @Schema(description ="暂存状态(开启、关闭)",name ="staging",example = "") + private String stagingState; + + /** + * + * 修改时间 + */ + @Schema(description ="修改时间",name ="updateTime",example = "") + private LocalDateTime updateTime; + +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/impl/InternalNetworkPenetrationMappingApplicationImpl.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/impl/InternalNetworkPenetrationMappingApplicationImpl.java new file mode 100644 index 0000000..b131ef6 --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/impl/InternalNetworkPenetrationMappingApplicationImpl.java @@ -0,0 +1,202 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.application.impl; + +import wu.framework.middleground.cloud.heartbeat.common.InternalNetworkPenetrationRealClient; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.application.InternalNetworkPenetrationMappingApplication; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.application.assembler.InternalNetworkPenetrationMappingDTOAssembler; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.application.command.internal.network.penetration.mapping.*; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.application.dto.InternalNetworkPenetrationMappingDTO; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.model.internal.network.penetration.mapping.InternalNetworkPenetrationMapping; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.model.internal.network.penetration.mapping.InternalNetworkPenetrationMappingRepository; + +import com.wu.framework.database.lazy.web.plus.stereotype.LazyApplication; +import com.wu.framework.inner.lazy.database.expand.database.persistence.domain.LazyPage; +import com.wu.framework.response.Result; +import com.wu.framework.response.ResultFactory; +import jakarta.annotation.Resource; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.netty.filter.VisitorFilter; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.netty.socket.NettyVisitorSocket; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * describe 内网穿透映射 + * + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + * @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyApplicationImpl + **/ +@LazyApplication +public class InternalNetworkPenetrationMappingApplicationImpl implements InternalNetworkPenetrationMappingApplication { + + @Resource + InternalNetworkPenetrationMappingRepository internalNetworkPenetrationMappingRepository; + + + /** + * describe 新增内网穿透映射 + * + * @param internalNetworkPenetrationMappingStoryCommand 新增内网穿透映射 + * @return {@link Result} 内网穿透映射新增后领域对象 + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + **/ + + @Override + public Result story(InternalNetworkPenetrationMappingStoryCommand internalNetworkPenetrationMappingStoryCommand) { + InternalNetworkPenetrationMapping internalNetworkPenetrationMapping = InternalNetworkPenetrationMappingDTOAssembler.INSTANCE.toInternalNetworkPenetrationMapping(internalNetworkPenetrationMappingStoryCommand); + return internalNetworkPenetrationMappingRepository.story(internalNetworkPenetrationMapping); + } + + /** + * describe 批量新增内网穿透映射 + * + * @param internalNetworkPenetrationMappingStoryCommandList 批量新增内网穿透映射 + * @return {@link Result>} 内网穿透映射新增后领域对象集合 + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + **/ + + @Override + public Result> batchStory(List internalNetworkPenetrationMappingStoryCommandList) { + List internalNetworkPenetrationMappingList = internalNetworkPenetrationMappingStoryCommandList.stream().map(InternalNetworkPenetrationMappingDTOAssembler.INSTANCE::toInternalNetworkPenetrationMapping).collect(Collectors.toList()); + return internalNetworkPenetrationMappingRepository.batchStory(internalNetworkPenetrationMappingList); + } + + /** + * describe 更新内网穿透映射 + * + * @param internalNetworkPenetrationMappingUpdateCommand 更新内网穿透映射 + * @return {@link Result} 内网穿透映射领域对象 + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + **/ + + @Override + public Result updateOne(InternalNetworkPenetrationMappingUpdateCommand internalNetworkPenetrationMappingUpdateCommand) { + InternalNetworkPenetrationMapping internalNetworkPenetrationMapping = InternalNetworkPenetrationMappingDTOAssembler.INSTANCE.toInternalNetworkPenetrationMapping(internalNetworkPenetrationMappingUpdateCommand); + return internalNetworkPenetrationMappingRepository.story(internalNetworkPenetrationMapping); + } + + /** + * describe 查询单个内网穿透映射 + * + * @param internalNetworkPenetrationMappingQueryOneCommand 查询单个内网穿透映射 + * @return {@link Result< InternalNetworkPenetrationMappingDTO >} 内网穿透映射DTO对象 + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + **/ + + @Override + public Result findOne(InternalNetworkPenetrationMappingQueryOneCommand internalNetworkPenetrationMappingQueryOneCommand) { + InternalNetworkPenetrationMapping internalNetworkPenetrationMapping = InternalNetworkPenetrationMappingDTOAssembler.INSTANCE.toInternalNetworkPenetrationMapping(internalNetworkPenetrationMappingQueryOneCommand); + return internalNetworkPenetrationMappingRepository.findOne(internalNetworkPenetrationMapping).convert(InternalNetworkPenetrationMappingDTOAssembler.INSTANCE::fromInternalNetworkPenetrationMapping); + } + + /** + * describe 查询多个内网穿透映射 + * + * @param internalNetworkPenetrationMappingQueryListCommand 查询多个内网穿透映射 + * @return {@link Result>} 内网穿透映射DTO对象 + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + **/ + + @Override + public Result> findList(InternalNetworkPenetrationMappingQueryListCommand internalNetworkPenetrationMappingQueryListCommand) { + InternalNetworkPenetrationMapping internalNetworkPenetrationMapping = InternalNetworkPenetrationMappingDTOAssembler.INSTANCE.toInternalNetworkPenetrationMapping(internalNetworkPenetrationMappingQueryListCommand); + return internalNetworkPenetrationMappingRepository.findList(internalNetworkPenetrationMapping).convert(internalNetworkPenetrationMappings -> internalNetworkPenetrationMappings.stream().map(InternalNetworkPenetrationMappingDTOAssembler.INSTANCE::fromInternalNetworkPenetrationMapping).collect(Collectors.toList())); + } + + /** + * describe 分页查询多个内网穿透映射 + * + * @param internalNetworkPenetrationMappingQueryListCommand 分页查询多个内网穿透映射 + * @return {@link Result>} 分页内网穿透映射DTO对象 + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + **/ + + @Override + public Result> findPage(int size, int current, InternalNetworkPenetrationMappingQueryListCommand internalNetworkPenetrationMappingQueryListCommand) { + InternalNetworkPenetrationMapping internalNetworkPenetrationMapping = InternalNetworkPenetrationMappingDTOAssembler.INSTANCE.toInternalNetworkPenetrationMapping(internalNetworkPenetrationMappingQueryListCommand); + return internalNetworkPenetrationMappingRepository.findPage(size, current, internalNetworkPenetrationMapping).convert(page -> page.convert(InternalNetworkPenetrationMappingDTOAssembler.INSTANCE::fromInternalNetworkPenetrationMapping)); + } + + /** + * describe 删除内网穿透映射 + * + * @param internalNetworkPenetrationMappingRemoveCommand 删除内网穿透映射 + * @return {@link Result} 内网穿透映射 + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + **/ + + @Override + public Result remove(InternalNetworkPenetrationMappingRemoveCommand internalNetworkPenetrationMappingRemoveCommand) { + InternalNetworkPenetrationMapping internalNetworkPenetrationMapping = InternalNetworkPenetrationMappingDTOAssembler.INSTANCE.toInternalNetworkPenetrationMapping(internalNetworkPenetrationMappingRemoveCommand); + return internalNetworkPenetrationMappingRepository.remove(internalNetworkPenetrationMapping); + } + + /** + * 创建客户端的访问者 + * + * @param clientId 客户端ID + */ + @Override + public Result createVisitor(String clientId) { + // 查询代理信息 + InternalNetworkPenetrationMapping internalNetworkPenetrationMapping = new InternalNetworkPenetrationMapping(); + internalNetworkPenetrationMapping.setIsDeleted(false); + internalNetworkPenetrationMapping.setClientId(clientId); + return internalNetworkPenetrationMappingRepository + .findList(internalNetworkPenetrationMapping) + .applyOther(internalNetworkPenetrationMappings -> { + for (InternalNetworkPenetrationMapping networkPenetrationMapping : internalNetworkPenetrationMappings) { + Integer visitorPort = networkPenetrationMapping.getVisitorPort(); + String clientTargetIp = networkPenetrationMapping.getClientTargetIp(); + Integer clientTargetPort = networkPenetrationMapping.getClientTargetPort(); + + 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); + + Thread thread = new Thread(() -> { + try { + nettyVisitorSocket.startServer(visitorPort); + } catch (Exception e) { + throw new RuntimeException(e); + } + + }); + // 使用线程池 TODO + thread.run(); + + + + // 发送客户端代理连接请求 客户端创建代理连接 +// ChannelContext.ClientChannel clientChannel = ChannelContext.get(clientId.getBytes(StandardCharsets.UTF_8)); +// if (!ObjectUtils.isEmpty(clientChannel)) { +// Channel channel = clientChannel.getChannel(); +// NettyProxyMsg nettyMsg = new NettyProxyMsg(); +// nettyMsg.setType(MessageType.DISTRIBUTE_SINGLE_CLIENT_REAL_CONNECT); +// nettyMsg.setClientId(clientId.getBytes(StandardCharsets.UTF_8)); +// nettyMsg.setData(JSON.toJSONString(internalNetworkPenetrationRealClient).getBytes(StandardCharsets.UTF_8)); +// channel.writeAndFlush(nettyMsg); +// } + + + } + + + return ResultFactory.successOf(); + }); + + } +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/impl/NettyClientBlacklistApplicationImpl.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/impl/NettyClientBlacklistApplicationImpl.java new file mode 100644 index 0000000..8714df0 --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/impl/NettyClientBlacklistApplicationImpl.java @@ -0,0 +1,170 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.application.impl; + +import com.wu.framework.database.lazy.web.plus.stereotype.LazyApplication; +import wu.framework.middleground.cloud.heartbeat.common.ChannelContext; +import wu.framework.middleground.cloud.heartbeat.common.MessageType; +import wu.framework.middleground.cloud.heartbeat.common.NettyProxyMsg; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.application.NettyClientBlacklistApplication; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.application.assembler.NettyClientBlacklistDTOAssembler; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.application.command.netty.client.blacklist.*; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.application.dto.NettyClientBlacklistDTO; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.model.netty.client.blacklist.NettyClientBlacklist; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.model.netty.client.blacklist.NettyClientBlacklistRepository; +import com.wu.framework.inner.lazy.database.expand.database.persistence.domain.LazyPage; +import com.wu.framework.response.Result; +import io.netty.channel.Channel; +import jakarta.annotation.Resource; + +import java.nio.charset.StandardCharsets; +import java.util.List; +import java.util.stream.Collectors; +/** + * describe 客户端黑名单 + * + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + * @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyApplicationImpl + **/ +@LazyApplication +public class NettyClientBlacklistApplicationImpl implements NettyClientBlacklistApplication { + + @Resource + NettyClientBlacklistRepository nettyClientBlacklistRepository; + /** + * describe 新增客户端黑名单 + * + * @param nettyClientBlacklistStoryCommand 新增客户端黑名单 + * @return {@link Result} 客户端黑名单新增后领域对象 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + @Override + public Result story(NettyClientBlacklistStoryCommand nettyClientBlacklistStoryCommand) { + NettyClientBlacklist nettyClientBlacklist = NettyClientBlacklistDTOAssembler.INSTANCE.toNettyClientBlacklist(nettyClientBlacklistStoryCommand); + // 添加和名单,客户端下线 + Result story = nettyClientBlacklistRepository.story(nettyClientBlacklist); + // 获取客户端channel 发送下下通知 + String clientId = nettyClientBlacklist.getClientId(); + ChannelContext.ClientChannel clientChannel = ChannelContext.get(clientId.getBytes(StandardCharsets.UTF_8)); + if(null!=clientChannel){ + // 模拟客户端发送下线通知 + Channel channel = clientChannel.getChannel(); + NettyProxyMsg nettyMsg = new NettyProxyMsg(); + nettyMsg.setClientId(clientId); + nettyMsg.setType(MessageType.REPORT_CLIENT_DISCONNECTION); + + channel.writeAndFlush(nettyMsg); + } + + return story; + } + /** + * describe 批量新增客户端黑名单 + * + * @param nettyClientBlacklistStoryCommandList 批量新增客户端黑名单 + * @return {@link Result>} 客户端黑名单新增后领域对象集合 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + @Override + public Result> batchStory(List nettyClientBlacklistStoryCommandList) { + List nettyClientBlacklistList = nettyClientBlacklistStoryCommandList.stream().map( NettyClientBlacklistDTOAssembler.INSTANCE::toNettyClientBlacklist).collect(Collectors.toList()); + return nettyClientBlacklistRepository.batchStory(nettyClientBlacklistList); + } + /** + * describe 更新客户端黑名单 + * + * @param nettyClientBlacklistUpdateCommand 更新客户端黑名单 + * @return {@link Result} 客户端黑名单领域对象 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + @Override + public Result updateOne(NettyClientBlacklistUpdateCommand nettyClientBlacklistUpdateCommand) { + NettyClientBlacklist nettyClientBlacklist = NettyClientBlacklistDTOAssembler.INSTANCE.toNettyClientBlacklist(nettyClientBlacklistUpdateCommand); + return nettyClientBlacklistRepository.story(nettyClientBlacklist); + } + + /** + * describe 查询单个客户端黑名单 + * + * @param nettyClientBlacklistQueryOneCommand 查询单个客户端黑名单 + * @return {@link Result} 客户端黑名单DTO对象 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + @Override + public Result findOne(NettyClientBlacklistQueryOneCommand nettyClientBlacklistQueryOneCommand) { + NettyClientBlacklist nettyClientBlacklist = NettyClientBlacklistDTOAssembler.INSTANCE.toNettyClientBlacklist(nettyClientBlacklistQueryOneCommand); + return nettyClientBlacklistRepository.findOne(nettyClientBlacklist).convert(NettyClientBlacklistDTOAssembler.INSTANCE::fromNettyClientBlacklist); + } + + /** + * describe 查询多个客户端黑名单 + * + * @param nettyClientBlacklistQueryListCommand 查询多个客户端黑名单 + * @return {@link Result>} 客户端黑名单DTO对象 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + @Override + public Result> findList(NettyClientBlacklistQueryListCommand nettyClientBlacklistQueryListCommand) { + NettyClientBlacklist nettyClientBlacklist = NettyClientBlacklistDTOAssembler.INSTANCE.toNettyClientBlacklist(nettyClientBlacklistQueryListCommand); + return nettyClientBlacklistRepository.findList(nettyClientBlacklist) .convert(nettyClientBlacklists -> nettyClientBlacklists.stream().map(NettyClientBlacklistDTOAssembler.INSTANCE::fromNettyClientBlacklist).collect(Collectors.toList())) ; + } + + /** + * describe 分页查询多个客户端黑名单 + * + * @param nettyClientBlacklistQueryListCommand 分页查询多个客户端黑名单 + * @return {@link Result>} 分页客户端黑名单DTO对象 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + @Override + public Result> findPage(int size,int current,NettyClientBlacklistQueryListCommand nettyClientBlacklistQueryListCommand) { + NettyClientBlacklist nettyClientBlacklist = NettyClientBlacklistDTOAssembler.INSTANCE.toNettyClientBlacklist(nettyClientBlacklistQueryListCommand); + return nettyClientBlacklistRepository.findPage(size,current,nettyClientBlacklist) .convert(page -> page.convert(NettyClientBlacklistDTOAssembler.INSTANCE::fromNettyClientBlacklist)) ; + } + + /** + * describe 删除客户端黑名单 + * + * @param nettyClientBlacklistRemoveCommand 删除客户端黑名单 + * @return {@link Result} 客户端黑名单 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + @Override + public Result remove(NettyClientBlacklistRemoveCommand nettyClientBlacklistRemoveCommand) { + NettyClientBlacklist nettyClientBlacklist = NettyClientBlacklistDTOAssembler.INSTANCE.toNettyClientBlacklist(nettyClientBlacklistRemoveCommand); + return nettyClientBlacklistRepository.remove(nettyClientBlacklist); + } + + /** + * describe 是否存在客户端黑名单 + * + * @param nettyClientBlacklist 是否存在客户端黑名单 + * @return {@link Result} 客户端黑名单是否存在 + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + @Override + public Result exists(NettyClientBlacklist nettyClientBlacklist) { + return nettyClientBlacklistRepository.exists(nettyClientBlacklist); + } +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/impl/NettyClientStateApplicationImpl.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/impl/NettyClientStateApplicationImpl.java new file mode 100644 index 0000000..a92655b --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/impl/NettyClientStateApplicationImpl.java @@ -0,0 +1,141 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.application.impl; + + + +import wu.framework.middleground.on.cloud.heartbeat.server.domain.application.NettyClientStateApplication; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.application.assembler.NettyClientStateDTOAssembler; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.application.command.netty.client.state.NettyClientStateStoryCommand; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.application.command.netty.client.state.*; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.application.dto.NettyClientStateDTO; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.model.netty.client.state.NettyClientState; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.model.netty.client.state.NettyClientStateRepository; +import com.wu.framework.database.lazy.web.plus.stereotype.LazyApplication; +import com.wu.framework.inner.lazy.database.expand.database.persistence.domain.LazyPage; +import com.wu.framework.response.Result; +import jakarta.annotation.Resource; + +import java.util.List; +import java.util.stream.Collectors; +/** + * describe 客户端状态 + * + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + * @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyApplicationImpl + **/ +@LazyApplication +public class NettyClientStateApplicationImpl implements NettyClientStateApplication { + + @Resource + NettyClientStateRepository nettyClientStateRepository; + /** + * describe 新增客户端状态 + * + * @param nettyClientStateStoryCommand 新增客户端状态 + * @return {@link Result} 客户端状态新增后领域对象 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + @Override + public Result story(NettyClientStateStoryCommand nettyClientStateStoryCommand) { + NettyClientState nettyClientState = NettyClientStateDTOAssembler.INSTANCE.toNettyClientState(nettyClientStateStoryCommand); + return nettyClientStateRepository.story(nettyClientState); + } + /** + * describe 批量新增客户端状态 + * + * @param nettyClientStateStoryCommandList 批量新增客户端状态 + * @return {@link Result>} 客户端状态新增后领域对象集合 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + @Override + public Result> batchStory(List nettyClientStateStoryCommandList) { + List nettyClientStateList = nettyClientStateStoryCommandList.stream().map( NettyClientStateDTOAssembler.INSTANCE::toNettyClientState).collect(Collectors.toList()); + return nettyClientStateRepository.batchStory(nettyClientStateList); + } + /** + * describe 更新客户端状态 + * + * @param nettyClientStateUpdateCommand 更新客户端状态 + * @return {@link Result} 客户端状态领域对象 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + @Override + public Result updateOne(NettyClientStateUpdateCommand nettyClientStateUpdateCommand) { + NettyClientState nettyClientState = NettyClientStateDTOAssembler.INSTANCE.toNettyClientState(nettyClientStateUpdateCommand); + return nettyClientStateRepository.story(nettyClientState); + } + + /** + * describe 查询单个客户端状态 + * + * @param nettyClientStateQueryOneCommand 查询单个客户端状态 + * @return {@link Result} 客户端状态DTO对象 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + @Override + public Result findOne(NettyClientStateQueryOneCommand nettyClientStateQueryOneCommand) { + NettyClientState nettyClientState = NettyClientStateDTOAssembler.INSTANCE.toNettyClientState(nettyClientStateQueryOneCommand); + return nettyClientStateRepository.findOne(nettyClientState).convert(NettyClientStateDTOAssembler.INSTANCE::fromNettyClientState); + } + + /** + * describe 查询多个客户端状态 + * + * @param nettyClientStateQueryListCommand 查询多个客户端状态 + * @return {@link Result>} 客户端状态DTO对象 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + @Override + public Result> findList(NettyClientStateQueryListCommand nettyClientStateQueryListCommand) { + NettyClientState nettyClientState = NettyClientStateDTOAssembler.INSTANCE.toNettyClientState(nettyClientStateQueryListCommand); + return nettyClientStateRepository.findList(nettyClientState) .convert(nettyClientStates -> nettyClientStates.stream().map(NettyClientStateDTOAssembler.INSTANCE::fromNettyClientState).collect(Collectors.toList())) ; + } + + /** + * describe 分页查询多个客户端状态 + * + * @param nettyClientStateQueryListCommand 分页查询多个客户端状态 + * @return {@link Result>} 分页客户端状态DTO对象 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + @Override + public Result> findPage(int size,int current,NettyClientStateQueryListCommand nettyClientStateQueryListCommand) { + NettyClientState nettyClientState = NettyClientStateDTOAssembler.INSTANCE.toNettyClientState(nettyClientStateQueryListCommand); + return nettyClientStateRepository.findPage(size,current,nettyClientState) .convert(page -> page.convert(NettyClientStateDTOAssembler.INSTANCE::fromNettyClientState)) ; + } + + /** + * describe 删除客户端状态 + * + * @param nettyClientStateRemoveCommand 删除客户端状态 + * @return {@link Result} 客户端状态 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + @Override + public Result remove(NettyClientStateRemoveCommand nettyClientStateRemoveCommand) { + NettyClientState nettyClientState = NettyClientStateDTOAssembler.INSTANCE.toNettyClientState(nettyClientStateRemoveCommand); + return nettyClientStateRepository.remove(nettyClientState); + } + +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/impl/ServerNettyConfigApplicationImpl.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/impl/ServerNettyConfigApplicationImpl.java new file mode 100644 index 0000000..b69d4ec --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/application/impl/ServerNettyConfigApplicationImpl.java @@ -0,0 +1,97 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.application.impl; + + +import com.wu.framework.database.lazy.web.plus.stereotype.LazyApplication; +import wu.framework.middleground.cloud.heartbeat.common.constant.ClientConfigKeyUtils; +import wu.framework.middleground.cloud.heartbeat.common.enums.NettyClientStatus; + +import wu.framework.middleground.on.cloud.heartbeat.server.domain.application.ServerNettyConfigApplication; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.model.netty.client.state.NettyClientState; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.model.netty.client.state.NettyClientStateRepository; +import lombok.extern.slf4j.Slf4j; + + +@Slf4j +@LazyApplication +public class ServerNettyConfigApplicationImpl implements ServerNettyConfigApplication { + + private final NettyClientStateRepository nettyClientStateRepository; + + + public ServerNettyConfigApplicationImpl(NettyClientStateRepository nettyClientStateRepository) { + + this.nettyClientStateRepository = nettyClientStateRepository; + } + + + /** + * 客户端在线 + * + * @param clientId 客户端ID + */ + @Override + public void clientOnLine(String clientId) { + // 如果可以已经在线状态不推送 + String clientStatusKey = ClientConfigKeyUtils.getClientStatusKey(clientId); +// stringRedisTemplate.opsForValue().set(clientStatusKey, NettyClientStatus.ON_LINE.name()); + NettyClientState nettyClientState = new NettyClientState(); + nettyClientState.setClientId(clientId); + nettyClientState.setOnLineState(NettyClientStatus.ON_LINE); + nettyClientStateRepository.updateOnLIneState(nettyClientState); + // 触发暂存扫描 +// ClientOnLineState clientOnLineState = new ClientOnLineState(); +// clientOnLineState.setClientId(clientId); +// clientOnLineState.setOnLineState(NettyClientStatus.ON_LINE.name()); +// stringRedisTemplate.convertAndSend(REDIS_CLIENT_ONLINE_OR_OFFLINE_CHANNEL,clientOnLineState); + } + + /** + * 客户端离线 + * + * @param clientId 客户端ID + */ + @Override + public void clientOffLine(String clientId) { + // 如果可以已经在线状态不推送 + String clientStatusKey = ClientConfigKeyUtils.getClientStatusKey(clientId); +// stringRedisTemplate.opsForValue().set(clientStatusKey, NettyClientStatus.OFF_LINE.name()); + // 修改客户端状态 离线 + NettyClientState nettyClientState = new NettyClientState(); + nettyClientState.setClientId(clientId); + nettyClientState.setOnLineState(NettyClientStatus.OFF_LINE); + nettyClientState.setStagingState("OPENED"); + nettyClientStateRepository.updateOnLIneState(nettyClientState); +// // 触发暂存扫描 +// ClientOnLineState clientOnLineState = new ClientOnLineState(); +// clientOnLineState.setClientId(clientId); +// clientOnLineState.setOnLineState(NettyClientStatus.OFF_LINE.name()); +// stringRedisTemplate.convertAndSend(REDIS_CLIENT_ONLINE_OR_OFFLINE_CHANNEL,clientOnLineState); + + } + + /** + * 客户端暂存关闭 + * + * @param clientId 客户端ID + */ + @Override + public void stagingClosed(String clientId) { + NettyClientState nettyClientState = new NettyClientState(); + nettyClientState.setClientId(clientId); + nettyClientState.setStagingState("CLOSED"); + nettyClientStateRepository.updateStagingState(nettyClientState); + } + + /** + * 客户端暂存开启 + * + * @param clientId 客户端ID + */ + @Override + public void stagingOpened(String clientId) { + NettyClientState nettyClientState = new NettyClientState(); + nettyClientState.setClientId(clientId); + nettyClientState.setStagingState("OPENED"); + nettyClientStateRepository.updateStagingState(nettyClientState); + } +} diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/controller/ChannelController.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/controller/ChannelController.java new file mode 100644 index 0000000..a1bb783 --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/controller/ChannelController.java @@ -0,0 +1,111 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.controller; + + + +import com.wu.framework.inner.layer.web.EasyController; +import com.wu.framework.response.Result; +import com.wu.framework.response.ResultFactory; +import io.netty.channel.Channel; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import wu.framework.middleground.cloud.heartbeat.common.ChannelContext; +import wu.framework.middleground.cloud.heartbeat.common.InternalNetworkPenetrationRealClient; +import wu.framework.middleground.cloud.heartbeat.common.MessageType; +import wu.framework.middleground.cloud.heartbeat.common.NettyProxyMsg; + +import java.nio.charset.StandardCharsets; +import java.util.List; + +/** + * 通道管理 + */ +@Slf4j +@Tag(name = "服务端Netty通道管理") +@EasyController("/channel") +public class ChannelController { + + @Operation(summary = "服务端访问客户端") + @GetMapping("/{clientId}") + public void fetchClientId(@PathVariable("clientId") String clientId) { + log.info("clientId:" + clientId); + // 获取客户端channel + ChannelContext.ClientChannel clientChannel = ChannelContext.get(clientId.getBytes(StandardCharsets.UTF_8)); + + if (clientChannel == null) { + if (log.isDebugEnabled()) { + for (ChannelContext.ClientChannel exisitClientChannel : ChannelContext.get()) { + log.debug("当前存在的通道:{}", new String(exisitClientChannel.getClientId())); + } + } + return; + } + // 发送消息 + Channel channel = clientChannel.getChannel(); + NettyProxyMsg nettyMsg = new NettyProxyMsg(); + nettyMsg.setClientId(clientId); + // 下发 客户端消息 + nettyMsg.setType(MessageType.DISTRIBUTE_CLIENT_TRANSFER); + + channel.writeAndFlush(nettyMsg); + } + + /** + * 获取当前服务端所有通道 + */ + @Operation(summary = "获取当前服务端所有通道") + @GetMapping("/findClientIdList") + public Result> findClientIdList() { + List clientChannels = ChannelContext.get(); + return ResultFactory.successOf(clientChannels.stream().map(clientChannel -> new String(clientChannel.getClientId())).toList()); + } + + /** + * 批量调度客户端 数据转换接收 + */ + @Operation(summary = "批量调度客户端 数据转换接收") + @PostMapping("/batchTransfer") + public Result> batchTransfer(@RequestBody InternalNetworkPenetrationRealClient internalNetworkPenetrationRealClient) { + + String data = "GET /swagger-ui/index.html HTTP/1.1\n" + + "Host: 127.0.0.1:19080\n" + + "Connection: keep-alive\n" + + "Cache-Control: max-age=0\n" + + "sec-ch-ua: \"Not_A Brand\";v=\"8\", \"Chromium\";v=\"120\", \"Google Chrome\";v=\"120\"\n" + + "sec-ch-ua-mobile: ?0\n" + + "sec-ch-ua-platform: \"macOS\"\n" + + "Upgrade-Insecure-Requests: 1\n" + + "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36\n" + + "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7\n" + + "Sec-Fetch-Site: none\n" + + "Sec-Fetch-Mode: navigate\n" + + "Sec-Fetch-User: ?1\n" + + "Sec-Fetch-Dest: document\n" + + "Accept-Encoding: gzip, deflate, br\n" + + "Accept-Language: zh-CN,zh;q=0.9\n" + + "Cookie: XXL_JOB_LOGIN_IDENTITY=7b226964223a312c22757365726e616d65223a2261646d696e222c2270617373776f7264223a226531306164633339343962613539616262653536653035376632306638383365222c22726f6c65223a312c227065726d697373696f6e223a6e756c6c7d; Hm_lvt_173e771eef816c412396d2cb4fe2d632=1703040917\n"; + + List clientChannels = ChannelContext.get(); + String clientTargetIp = internalNetworkPenetrationRealClient.getClientTargetIp(); + Integer clientTargetPort = internalNetworkPenetrationRealClient.getClientTargetPort(); + Integer visitorPort = internalNetworkPenetrationRealClient.getVisitorPort(); + for (ChannelContext.ClientChannel clientChannel : clientChannels) { + Channel channel = clientChannel.getChannel(); + NettyProxyMsg nettyProxyMsg = new NettyProxyMsg(); + // 下发 客户端消息 + nettyProxyMsg.setType(MessageType.DISTRIBUTE_CLIENT_TRANSFER); + nettyProxyMsg.setClientId(clientChannel.getClientId()); + nettyProxyMsg.setVisitorPort(visitorPort); + nettyProxyMsg.setClientTargetIp(clientTargetIp); + nettyProxyMsg.setClientTargetPort(clientTargetPort); + nettyProxyMsg.setData(data.getBytes(StandardCharsets.UTF_8)); + channel.writeAndFlush(nettyProxyMsg); + } + return ResultFactory.successOf(); + } + +} diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/controller/InternalNetworkPenetrationMappingProvider.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/controller/InternalNetworkPenetrationMappingProvider.java new file mode 100644 index 0000000..2110c32 --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/controller/InternalNetworkPenetrationMappingProvider.java @@ -0,0 +1,138 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.controller; + + +import wu.framework.middleground.on.cloud.heartbeat.server.domain.application.InternalNetworkPenetrationMappingApplication; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.application.command.internal.network.penetration.mapping.*; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.application.dto.InternalNetworkPenetrationMappingDTO; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.model.internal.network.penetration.mapping.InternalNetworkPenetrationMapping; +import com.wu.framework.inner.layer.web.EasyController; +import com.wu.framework.inner.lazy.database.expand.database.persistence.domain.LazyPage; +import com.wu.framework.response.Result; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * describe 内网穿透映射 + * + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + * @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyController + **/ +@Tag(name = "内网穿透映射提供者") +@EasyController("/internal/network/penetration/mapping") +public class InternalNetworkPenetrationMappingProvider { + + @Resource + private InternalNetworkPenetrationMappingApplication internalNetworkPenetrationMappingApplication; + + /** + * describe 新增内网穿透映射 + * + * @param internalNetworkPenetrationMappingStoryCommand 新增内网穿透映射 + * @return {@link Result} 内网穿透映射新增后领域对象 + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + **/ + + @Operation(summary = "新增内网穿透映射") + @PostMapping("/story") + public Result story(@RequestBody InternalNetworkPenetrationMappingStoryCommand internalNetworkPenetrationMappingStoryCommand) { + return internalNetworkPenetrationMappingApplication.story(internalNetworkPenetrationMappingStoryCommand); + } + + /** + * describe 批量新增内网穿透映射 + * + * @param internalNetworkPenetrationMappingStoryCommandList 批量新增内网穿透映射 + * @return {@link Result>} 内网穿透映射新增后领域对象集合 + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + **/ + + @Operation(summary = "批量新增内网穿透映射") + @PostMapping("/batchStory") + public Result> batchStory(@RequestBody List internalNetworkPenetrationMappingStoryCommandList) { + return internalNetworkPenetrationMappingApplication.batchStory(internalNetworkPenetrationMappingStoryCommandList); + } + + /** + * describe 更新内网穿透映射 + * + * @param internalNetworkPenetrationMappingUpdateCommand 更新内网穿透映射 + * @return {@link Result} 内网穿透映射领域对象 + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + **/ + + @Operation(summary = "更新内网穿透映射") + @PutMapping("/updateOne") + public Result updateOne(@RequestBody InternalNetworkPenetrationMappingUpdateCommand internalNetworkPenetrationMappingUpdateCommand) { + return internalNetworkPenetrationMappingApplication.updateOne(internalNetworkPenetrationMappingUpdateCommand); + } + + /** + * describe 查询单个内网穿透映射 + * + * @param internalNetworkPenetrationMappingQueryOneCommand 查询单个内网穿透映射 + * @return {@link Result} 内网穿透映射DTO对象 + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + **/ + + @Operation(summary = "查询单个内网穿透映射") + @GetMapping("/findOne") + public Result findOne(@ModelAttribute InternalNetworkPenetrationMappingQueryOneCommand internalNetworkPenetrationMappingQueryOneCommand) { + return internalNetworkPenetrationMappingApplication.findOne(internalNetworkPenetrationMappingQueryOneCommand); + } + + /** + * describe 查询多个内网穿透映射 + * + * @param internalNetworkPenetrationMappingQueryListCommand 查询多个内网穿透映射 + * @return {@link Result>} 内网穿透映射DTO对象 + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + **/ + + @Operation(summary = "查询多个内网穿透映射") + @GetMapping("/findList") + public Result> findList(@ModelAttribute InternalNetworkPenetrationMappingQueryListCommand internalNetworkPenetrationMappingQueryListCommand) { + return internalNetworkPenetrationMappingApplication.findList(internalNetworkPenetrationMappingQueryListCommand); + } + + /** + * describe 分页查询多个内网穿透映射 + * + * @param internalNetworkPenetrationMappingQueryListCommand 分页查询多个内网穿透映射 + * @return {@link Result>} 分页内网穿透映射DTO对象 + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + **/ + + @Operation(summary = "分页查询多个内网穿透映射") + @GetMapping("/findPage") + public Result> findPage(@Parameter(description = "分页大小") @RequestParam(defaultValue = "10", value = "size") int size, + @Parameter(description = "当前页数") @RequestParam(defaultValue = "1", value = "current") int current, @ModelAttribute InternalNetworkPenetrationMappingQueryListCommand internalNetworkPenetrationMappingQueryListCommand) { + return internalNetworkPenetrationMappingApplication.findPage(size, current, internalNetworkPenetrationMappingQueryListCommand); + } + + /** + * describe 删除内网穿透映射 + * + * @param internalNetworkPenetrationMappingRemoveCommand 删除内网穿透映射 + * @return {@link Result} 内网穿透映射 + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + **/ + + @Operation(summary = "删除内网穿透映射") + @DeleteMapping("/remove") + public Result remove(@ModelAttribute InternalNetworkPenetrationMappingRemoveCommand internalNetworkPenetrationMappingRemoveCommand) { + return internalNetworkPenetrationMappingApplication.remove(internalNetworkPenetrationMappingRemoveCommand); + } +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/controller/NettyClientBlacklistProvider.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/controller/NettyClientBlacklistProvider.java new file mode 100644 index 0000000..b15a389 --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/controller/NettyClientBlacklistProvider.java @@ -0,0 +1,140 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.controller; + + +import wu.framework.middleground.on.cloud.heartbeat.server.domain.application.NettyClientBlacklistApplication; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.application.command.netty.client.blacklist.*; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.application.dto.NettyClientBlacklistDTO; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.model.netty.client.blacklist.NettyClientBlacklist; +import com.wu.framework.inner.layer.web.EasyController; +import com.wu.framework.inner.lazy.database.expand.database.persistence.domain.LazyPage; +import com.wu.framework.response.Result; +import com.wu.framework.response.mark.ValidType; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * describe 客户端黑名单 + * + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + * @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyController + **/ +@Tag(name = "客户端黑名单提供者") +@EasyController("/netty/client/blacklist") +public class NettyClientBlacklistProvider { + + @Resource + private NettyClientBlacklistApplication nettyClientBlacklistApplication; + + /** + * describe 新增客户端黑名单 + * + * @param nettyClientBlacklistStoryCommand 新增客户端黑名单 + * @return {@link Result} 客户端黑名单新增后领域对象 + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + @Operation(summary = "新增客户端黑名单") + @PostMapping("/story") + public Result story(@Validated(ValidType.Create.class) @RequestBody NettyClientBlacklistStoryCommand nettyClientBlacklistStoryCommand) { + return nettyClientBlacklistApplication.story(nettyClientBlacklistStoryCommand); + } + + /** + * describe 批量新增客户端黑名单 + * + * @param nettyClientBlacklistStoryCommandList 批量新增客户端黑名单 + * @return {@link Result>} 客户端黑名单新增后领域对象集合 + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + @Operation(summary = "批量新增客户端黑名单") + @PostMapping("/batchStory") + public Result> batchStory(@Validated(ValidType.Create.class) @RequestBody List nettyClientBlacklistStoryCommandList) { + return nettyClientBlacklistApplication.batchStory(nettyClientBlacklistStoryCommandList); + } + + /** + * describe 更新客户端黑名单 + * + * @param nettyClientBlacklistUpdateCommand 更新客户端黑名单 + * @return {@link Result} 客户端黑名单领域对象 + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + @Operation(summary = "更新客户端黑名单") + @PutMapping("/updateOne") + public Result updateOne(@RequestBody NettyClientBlacklistUpdateCommand nettyClientBlacklistUpdateCommand) { + return nettyClientBlacklistApplication.updateOne(nettyClientBlacklistUpdateCommand); + } + + /** + * describe 查询单个客户端黑名单 + * + * @param nettyClientBlacklistQueryOneCommand 查询单个客户端黑名单 + * @return {@link Result< NettyClientBlacklistDTO >} 客户端黑名单DTO对象 + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + @Operation(summary = "查询单个客户端黑名单") + @GetMapping("/findOne") + public Result findOne(@ModelAttribute NettyClientBlacklistQueryOneCommand nettyClientBlacklistQueryOneCommand) { + return nettyClientBlacklistApplication.findOne(nettyClientBlacklistQueryOneCommand); + } + + /** + * describe 查询多个客户端黑名单 + * + * @param nettyClientBlacklistQueryListCommand 查询多个客户端黑名单 + * @return {@link Result>} 客户端黑名单DTO对象 + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + @Operation(summary = "查询多个客户端黑名单") + @GetMapping("/findList") + public Result> findList(@ModelAttribute NettyClientBlacklistQueryListCommand nettyClientBlacklistQueryListCommand) { + return nettyClientBlacklistApplication.findList(nettyClientBlacklistQueryListCommand); + } + + /** + * describe 分页查询多个客户端黑名单 + * + * @param nettyClientBlacklistQueryListCommand 分页查询多个客户端黑名单 + * @return {@link Result>} 分页客户端黑名单DTO对象 + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + @Operation(summary = "分页查询多个客户端黑名单") + @GetMapping("/findPage") + public Result> findPage(@Parameter(description = "分页大小") @RequestParam(defaultValue = "10", value = "size") int size, + @Parameter(description = "当前页数") @RequestParam(defaultValue = "1", value = "current") int current, @ModelAttribute NettyClientBlacklistQueryListCommand nettyClientBlacklistQueryListCommand) { + return nettyClientBlacklistApplication.findPage(size, current, nettyClientBlacklistQueryListCommand); + } + + /** + * describe 删除客户端黑名单 + * + * @param nettyClientBlacklistRemoveCommand 删除客户端黑名单 + * @return {@link Result} 客户端黑名单 + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + @Operation(summary = "删除客户端黑名单") + @DeleteMapping("/remove") + public Result remove(@ModelAttribute NettyClientBlacklistRemoveCommand nettyClientBlacklistRemoveCommand) { + return nettyClientBlacklistApplication.remove(nettyClientBlacklistRemoveCommand); + } +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/controller/NettyClientStateProvider.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/controller/NettyClientStateProvider.java new file mode 100644 index 0000000..3da6bc1 --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/controller/NettyClientStateProvider.java @@ -0,0 +1,139 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.controller; + + +import com.wu.framework.inner.layer.web.EasyController; +import com.wu.framework.inner.lazy.database.expand.database.persistence.domain.LazyPage; +import com.wu.framework.response.Result; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import org.springframework.web.bind.annotation.*; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.application.NettyClientStateApplication; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.application.command.netty.client.state.*; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.application.dto.NettyClientStateDTO; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.model.netty.client.state.NettyClientState; + +import java.util.List; + +/** + * describe 客户端状态 + * + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + * @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyController + **/ +@Tag(name = "客户端状态提供者") +@EasyController("/netty/client/state") +public class NettyClientStateProvider { + + @Resource + private NettyClientStateApplication nettyClientStateApplication; + + /** + * describe 新增客户端状态 + * + * @param nettyClientStateStoryCommand 新增客户端状态 + * @return {@link Result< NettyClientState >} 客户端状态新增后领域对象 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + @Operation(summary = "新增客户端状态") + @PostMapping("/story") + public Result story(@RequestBody NettyClientStateStoryCommand nettyClientStateStoryCommand){ + return nettyClientStateApplication.story(nettyClientStateStoryCommand); + } + /** + * describe 批量新增客户端状态 + * + * @param nettyClientStateStoryCommandList 批量新增客户端状态 + * @return {@link Result >} 客户端状态新增后领域对象集合 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + @Operation(summary = "批量新增客户端状态") + @PostMapping("/batchStory") + public Result> batchStory(@RequestBody List nettyClientStateStoryCommandList){ + return nettyClientStateApplication.batchStory(nettyClientStateStoryCommandList); + } + /** + * describe 更新客户端状态 + * + * @param nettyClientStateUpdateCommand 更新客户端状态 + * @return {@link Result} 客户端状态领域对象 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + @Operation(summary = "更新客户端状态") + @PutMapping("/updateOne") + public Result updateOne(@RequestBody NettyClientStateUpdateCommand nettyClientStateUpdateCommand){ + return nettyClientStateApplication.updateOne(nettyClientStateUpdateCommand); + } + /** + * describe 查询单个客户端状态 + * + * @param nettyClientStateQueryOneCommand 查询单个客户端状态 + * @return {@link Result< NettyClientStateDTO >} 客户端状态DTO对象 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + @Operation(summary = "查询单个客户端状态") + @GetMapping("/findOne") + public Result findOne(@ModelAttribute NettyClientStateQueryOneCommand nettyClientStateQueryOneCommand){ + return nettyClientStateApplication.findOne(nettyClientStateQueryOneCommand); + } + /** + * describe 查询多个客户端状态 + * + * @param nettyClientStateQueryListCommand 查询多个客户端状态 + * @return {@link Result>} 客户端状态DTO对象 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + @Operation(summary = "查询多个客户端状态") + @GetMapping("/findList") + public Result> findList(@ModelAttribute NettyClientStateQueryListCommand nettyClientStateQueryListCommand){ + return nettyClientStateApplication.findList(nettyClientStateQueryListCommand); + } + /** + * describe 分页查询多个客户端状态 + * + * @param nettyClientStateQueryListCommand 分页查询多个客户端状态 + * @return {@link Result< LazyPage >} 分页客户端状态DTO对象 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + @Operation(summary = "分页查询多个客户端状态") + @GetMapping("/findPage") + public Result> findPage(@Parameter(description ="分页大小") @RequestParam(defaultValue = "10", value = "size") int size, + @Parameter(description ="当前页数") @RequestParam(defaultValue = "1", value = "current") int current, @ModelAttribute NettyClientStateQueryListCommand nettyClientStateQueryListCommand){ + return nettyClientStateApplication.findPage(size,current,nettyClientStateQueryListCommand); + } + /** + * describe 删除客户端状态 + * + * @param nettyClientStateRemoveCommand 删除客户端状态 + * @return {@link Result} 客户端状态 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + @Operation(summary = "删除客户端状态") + @DeleteMapping("/remove") + public Result remove(@ModelAttribute NettyClientStateRemoveCommand nettyClientStateRemoveCommand){ + return nettyClientStateApplication.remove(nettyClientStateRemoveCommand); + } +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/infrastructure/converter/InternalNetworkPenetrationMappingConverter.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/infrastructure/converter/InternalNetworkPenetrationMappingConverter.java new file mode 100644 index 0000000..a566b82 --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/infrastructure/converter/InternalNetworkPenetrationMappingConverter.java @@ -0,0 +1,48 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.infrastructure.converter; + +import wu.framework.middleground.on.cloud.heartbeat.server.domain.model.internal.network.penetration.mapping.InternalNetworkPenetrationMapping; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.infrastructure.entity.InternalNetworkPenetrationMappingDO; +/** + * describe 内网穿透映射 + * + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + * @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyInfrastructureConverter + **/ +@Mapper +public interface InternalNetworkPenetrationMappingConverter { + + + /** + * describe MapStruct 创建的代理对象 + * + + + + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + **/ + InternalNetworkPenetrationMappingConverter INSTANCE = Mappers.getMapper(InternalNetworkPenetrationMappingConverter.class); + /** + * describe 实体对象 转换成领域对象 + * + * @param internalNetworkPenetrationMappingDO 内网穿透映射实体对象 + * @return {@link InternalNetworkPenetrationMapping} 内网穿透映射领域对象 + + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + **/ + InternalNetworkPenetrationMapping toInternalNetworkPenetrationMapping(InternalNetworkPenetrationMappingDO internalNetworkPenetrationMappingDO); + /** + * describe 领域对象 转换成实体对象 + * + * @param internalNetworkPenetrationMapping 内网穿透映射领域对象 + * @return {@link InternalNetworkPenetrationMappingDO} 内网穿透映射实体对象 + + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + **/ + InternalNetworkPenetrationMappingDO fromInternalNetworkPenetrationMapping(InternalNetworkPenetrationMapping internalNetworkPenetrationMapping); +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/infrastructure/converter/NettyClientBlacklistConverter.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/infrastructure/converter/NettyClientBlacklistConverter.java new file mode 100644 index 0000000..5405939 --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/infrastructure/converter/NettyClientBlacklistConverter.java @@ -0,0 +1,50 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.infrastructure.converter; + + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.infrastructure.entity.NettyClientBlacklistDO; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.model.netty.client.blacklist.*; + +/** + * describe 客户端黑名单 + * + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + * @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyInfrastructureConverter + **/ +@Mapper +public interface NettyClientBlacklistConverter { + + + /** + * describe MapStruct 创建的代理对象 + * + + + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + NettyClientBlacklistConverter INSTANCE = Mappers.getMapper(NettyClientBlacklistConverter.class); + /** + * describe 实体对象 转换成领域对象 + * + * @param nettyClientBlacklistDO 客户端黑名单实体对象 + * @return {@link NettyClientBlacklist} 客户端黑名单领域对象 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + NettyClientBlacklist toNettyClientBlacklist(NettyClientBlacklistDO nettyClientBlacklistDO); + /** + * describe 领域对象 转换成实体对象 + * + * @param nettyClientBlacklist 客户端黑名单领域对象 + * @return {@link NettyClientBlacklistDO} 客户端黑名单实体对象 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + NettyClientBlacklistDO fromNettyClientBlacklist(NettyClientBlacklist nettyClientBlacklist); +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/infrastructure/converter/NettyClientStateConverter.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/infrastructure/converter/NettyClientStateConverter.java new file mode 100644 index 0000000..c0c20f0 --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/infrastructure/converter/NettyClientStateConverter.java @@ -0,0 +1,48 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.infrastructure.converter; + +import wu.framework.middleground.on.cloud.heartbeat.server.domain.model.netty.client.state.NettyClientState; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.infrastructure.entity.NettyClientStateDO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; +/** + * describe 客户端状态 + * + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + * @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyInfrastructureConverter + **/ +@Mapper +public interface NettyClientStateConverter { + + + /** + * describe MapStruct 创建的代理对象 + * + + + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + NettyClientStateConverter INSTANCE = Mappers.getMapper(NettyClientStateConverter.class); + /** + * describe 实体对象 转换成领域对象 + * + * @param nettyClientStateDO 客户端状态实体对象 + * @return {@link NettyClientState} 客户端状态领域对象 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + NettyClientState toNettyClientState(NettyClientStateDO nettyClientStateDO); + /** + * describe 领域对象 转换成实体对象 + * + * @param nettyClientState 客户端状态领域对象 + * @return {@link NettyClientStateDO} 客户端状态实体对象 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + NettyClientStateDO fromNettyClientState(NettyClientState nettyClientState); +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/infrastructure/entity/InternalNetworkPenetrationMappingDO.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/infrastructure/entity/InternalNetworkPenetrationMappingDO.java new file mode 100644 index 0000000..35048e1 --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/infrastructure/entity/InternalNetworkPenetrationMappingDO.java @@ -0,0 +1,94 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.infrastructure.entity; + +import com.wu.framework.inner.lazy.stereotype.*; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.time.LocalDateTime; +/** + * describe 内网穿透映射 + * + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + * @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyInfrastructureEntity + **/ +@Data +@Accessors(chain = true) +@LazyTable(tableName = "internal_network_penetration_mapping",schema = "middleground_cloud_netty_server",comment = "内网穿透映射") +@Schema(title = "internal_network_penetration_mapping",description = "内网穿透映射") +public class InternalNetworkPenetrationMappingDO { + + + /** + * + * 客户端ID + */ + @Schema(description ="客户端ID",name ="clientId",example = "") + @LazyTableField(name="client_id",comment="客户端ID",columnType="varchar(255)") + private String clientId; + + /** + * + * 客户端目标地址 + */ + @Schema(description ="客户端目标地址",name ="clientTargetIp",example = "") + @LazyTableField(name="client_target_ip",comment="客户端目标地址",columnType="varchar(255)",defaultValue = "'0.0.0.0'") + private String clientTargetIp; + + /** + * + * 客户端目标端口 + */ + @Schema(description ="客户端目标端口",name ="clientTargetPort",example = "") + @LazyTableField(name="client_target_port",comment="客户端目标端口",columnType="int",notNull = true) + private Integer clientTargetPort; + + /** + * + * 创建时间 + */ + @Schema(description ="创建时间",name ="createTime",example = "") + @LazyTableFieldCreateTime + private LocalDateTime createTime; + + /** + * + * 主键自增 + */ + @Schema(description ="主键自增",name ="id",example = "") + @LazyTableFieldId + private Long id; + + /** + * + * 是否删除 默认否 + */ + @Schema(description ="是否删除 默认否",name ="isDeleted",example = "") + @LazyTableField(name="is_deleted",comment="是否删除 默认否",columnType="tinyint",defaultValue = "'0'") + private Boolean isDeleted; + + /** + * + * 修改时间 + */ + @Schema(description ="修改时间",name ="updateTime",example = "") + @LazyTableFieldUpdateTime + private LocalDateTime updateTime; + + /** + * + * 访问端口 + */ + @Schema(description ="访问端口",name ="visitorPort",example = "") + @LazyTableFieldUnique(comment = "访问端口",notNull = true) + private Integer visitorPort; + /** + * + * 描述 + */ + @Schema(description ="描述",name ="describe",example = "") + @LazyTableField(comment = "描述") + private String describe; + +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/infrastructure/entity/NettyClientBlacklistDO.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/infrastructure/entity/NettyClientBlacklistDO.java new file mode 100644 index 0000000..25e25e8 --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/infrastructure/entity/NettyClientBlacklistDO.java @@ -0,0 +1,59 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.infrastructure.entity; + +import com.wu.framework.inner.lazy.stereotype.*; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.time.LocalDateTime; + +/** + * describe 客户端黑名单 + * + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + * @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyInfrastructureEntity + **/ +@Data +@Accessors(chain = true) +@LazyTable(tableName = "netty_client_blacklist", schema = "middleground_cloud_netty_server", comment = "客户端黑名单") +@Schema(title = "netty_client_blacklist", description = "客户端黑名单") +public class NettyClientBlacklistDO { + + + /** + * 客户端ID + */ + @Schema(description = "客户端ID", name = "clientId", example = "") + @LazyTableFieldUnique(name = "client_id", comment = "客户端ID", columnType = "varchar(255)") + private String clientId; + + /** + * 创建时间 + */ + @Schema(description = "创建时间", name = "createTime", example = "") + @LazyTableFieldCreateTime + private LocalDateTime createTime; + + /** + * 主键 + */ + @Schema(description = "主键", name = "id", example = "") + @LazyTableFieldId(name = "id", comment = "主键") + private Long id; + + /** + * 是否删除 + */ + @Schema(description = "是否删除", name = "isDeleted", example = "") + @LazyTableField(name = "is_deleted", comment = "是否删除", columnType = "tinyint") + private Boolean isDeleted; + + /** + * 更新时间 + */ + @Schema(description = "更新时间", name = "updateTime", example = "") + @LazyTableFieldUpdateTime + private LocalDateTime updateTime; + +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/infrastructure/entity/NettyClientStateDO.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/infrastructure/entity/NettyClientStateDO.java new file mode 100644 index 0000000..9ea3e12 --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/infrastructure/entity/NettyClientStateDO.java @@ -0,0 +1,74 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.infrastructure.entity; + +import wu.framework.middleground.cloud.heartbeat.common.enums.NettyClientStatus; +import com.wu.framework.inner.lazy.stereotype.*; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.time.LocalDateTime; + +/** + * describe 客户端状态 + * + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + * @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyInfrastructureEntity + **/ +@Data +@Accessors(chain = true) +@LazyTable(tableName = "netty_client_state", schema = "middleground_cloud_netty_server", comment = "客户端状态") +@Schema(title = "netty_client_state", description = "客户端状态") +public class NettyClientStateDO { + + + /** + * 客户端ID + */ + @Schema(description = "客户端ID", name = "clientId", example = "") + @LazyTableFieldUnique(name = "client_id", comment = "客户端ID", columnType = "varchar(255)") + private String clientId; + + /** + * 创建时间 + */ + @Schema(description = "创建时间", name = "createTime", example = "") + @LazyTableFieldCreateTime + private LocalDateTime createTime; + + /** + * 主键 + */ + @Schema(description = "主键", name = "id", example = "") + @LazyTableFieldId(name = "id", comment = "主键") + private Long id; + + /** + * 是否删除 + */ + @Schema(description = "是否删除", name = "isDeleted", example = "") + @LazyTableField(name = "is_deleted", comment = "是否删除",defaultValue = "'0'",columnType = "tinyint") + private Boolean isDeleted; + + /** + * 在线状态(true在线,false离线) + */ + @Schema(description = "在线状态(true在线,false离线)", name = "onLineState", example = "") + @LazyTableField(name = "on_line_state", comment = "在线状态(true在线,false离线)", columnType = "varchar(255)") + private NettyClientStatus onLineState; + + /** + * 暂存状态(开启、关闭) + */ + @Schema(description = "暂存状态(开启、关闭)", name = "staging", example = "") + @LazyTableField(name = "staging", comment = "暂存状态(开启、关闭)", columnType = "varchar(255)") + private String stagingState; + + /** + * 修改时间 + */ + @Schema(description = "修改时间", name = "updateTime", example = "") + @LazyTableFieldUpdateTime + private LocalDateTime updateTime; + +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/infrastructure/mapper/InternalNetworkPenetrationMappingMapper.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/infrastructure/mapper/InternalNetworkPenetrationMappingMapper.java new file mode 100644 index 0000000..9d5f59c --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/infrastructure/mapper/InternalNetworkPenetrationMappingMapper.java @@ -0,0 +1,15 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.infrastructure.mapper; + +/** + * describe 内网穿透映射 + * + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + * @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyInfrastructureMapper + **/ + +public interface InternalNetworkPenetrationMappingMapper { + + + +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/infrastructure/mapper/NettyClientBlacklistMapper.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/infrastructure/mapper/NettyClientBlacklistMapper.java new file mode 100644 index 0000000..bf48b50 --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/infrastructure/mapper/NettyClientBlacklistMapper.java @@ -0,0 +1,15 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.infrastructure.mapper; + +/** + * describe 客户端黑名单 + * + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + * @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyInfrastructureMapper + **/ + +public interface NettyClientBlacklistMapper { + + + +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/infrastructure/mapper/NettyClientStateMapper.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/infrastructure/mapper/NettyClientStateMapper.java new file mode 100644 index 0000000..73a5d69 --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/infrastructure/mapper/NettyClientStateMapper.java @@ -0,0 +1,15 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.infrastructure.mapper; + +/** + * describe 客户端状态 + * + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + * @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyInfrastructureMapper + **/ + +public interface NettyClientStateMapper { + + + +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/infrastructure/persistence/InternalNetworkPenetrationMappingRepositoryImpl.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/infrastructure/persistence/InternalNetworkPenetrationMappingRepositoryImpl.java new file mode 100644 index 0000000..31cdec1 --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/infrastructure/persistence/InternalNetworkPenetrationMappingRepositoryImpl.java @@ -0,0 +1,152 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.infrastructure.persistence; + +import wu.framework.middleground.on.cloud.heartbeat.server.domain.infrastructure.converter.InternalNetworkPenetrationMappingConverter; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.infrastructure.entity.InternalNetworkPenetrationMappingDO; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.model.internal.network.penetration.mapping.InternalNetworkPenetrationMapping; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.model.internal.network.penetration.mapping.InternalNetworkPenetrationMappingRepository; +import com.wu.framework.inner.lazy.database.expand.database.persistence.domain.LazyPage; +import com.wu.framework.inner.lazy.database.expand.database.persistence.stream.lambda.LazyLambdaStream; +import com.wu.framework.inner.lazy.database.expand.database.persistence.stream.wrapper.LazyWrappers; +import com.wu.framework.response.Result; +import com.wu.framework.response.ResultFactory; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Repository; + +import java.util.List; +import java.util.stream.Collectors; +/** + * describe 内网穿透映射 + * + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + * @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyInfrastructurePersistence + **/ +@Repository +public class InternalNetworkPenetrationMappingRepositoryImpl implements InternalNetworkPenetrationMappingRepository { + + @Resource + LazyLambdaStream lazyLambdaStream; + + /** + * describe 新增内网穿透映射 + * + * @param internalNetworkPenetrationMapping 新增内网穿透映射 + * @return {@link Result} 内网穿透映射新增后领域对象 + + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + **/ + + @Override + public Result story(InternalNetworkPenetrationMapping internalNetworkPenetrationMapping) { + InternalNetworkPenetrationMappingDO internalNetworkPenetrationMappingDO = InternalNetworkPenetrationMappingConverter.INSTANCE.fromInternalNetworkPenetrationMapping(internalNetworkPenetrationMapping); + lazyLambdaStream.upsert(internalNetworkPenetrationMappingDO); + return ResultFactory.successOf(); + } + + /** + * describe 批量新增内网穿透映射 + * + * @param internalNetworkPenetrationMappingList 批量新增内网穿透映射 + * @return {@link Result>} 内网穿透映射新增后领域对象集合 + + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + **/ + + @Override + public Result> batchStory(List internalNetworkPenetrationMappingList) { + List internalNetworkPenetrationMappingDOList = internalNetworkPenetrationMappingList.stream().map(InternalNetworkPenetrationMappingConverter.INSTANCE::fromInternalNetworkPenetrationMapping).collect(Collectors.toList()); + lazyLambdaStream.upsert(internalNetworkPenetrationMappingDOList); + return ResultFactory.successOf(); + } + + /** + * describe 查询单个内网穿透映射 + * + * @param internalNetworkPenetrationMapping 查询单个内网穿透映射 + * @return {@link Result} 内网穿透映射领域对象 + + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + **/ + + @Override + public Result findOne(InternalNetworkPenetrationMapping internalNetworkPenetrationMapping) { + InternalNetworkPenetrationMappingDO internalNetworkPenetrationMappingDO = InternalNetworkPenetrationMappingConverter.INSTANCE.fromInternalNetworkPenetrationMapping(internalNetworkPenetrationMapping); + InternalNetworkPenetrationMapping internalNetworkPenetrationMappingOne = lazyLambdaStream.selectOne(LazyWrappers.lambdaWrapperBean(internalNetworkPenetrationMappingDO), InternalNetworkPenetrationMapping.class); + return ResultFactory.successOf(internalNetworkPenetrationMappingOne); + } + + /** + * describe 查询多个内网穿透映射 + * + * @param internalNetworkPenetrationMapping 查询多个内网穿透映射 + * @return {@link Result>} 内网穿透映射领域对象 + + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + **/ + + @Override + public Result> findList(InternalNetworkPenetrationMapping internalNetworkPenetrationMapping) { + InternalNetworkPenetrationMappingDO internalNetworkPenetrationMappingDO = InternalNetworkPenetrationMappingConverter.INSTANCE.fromInternalNetworkPenetrationMapping(internalNetworkPenetrationMapping); + List internalNetworkPenetrationMappingList = lazyLambdaStream.selectList(LazyWrappers.lambdaWrapperBean(internalNetworkPenetrationMappingDO), InternalNetworkPenetrationMapping.class); + return ResultFactory.successOf(internalNetworkPenetrationMappingList); + } + + /** + * describe 分页查询多个内网穿透映射 + * + * @param size 当前页数 + * @param current 当前页 + * @param internalNetworkPenetrationMapping 分页查询多个内网穿透映射 + * @return {@link Result>} 分页内网穿透映射领域对象 + + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + **/ + + @Override + public Result> findPage(int size,int current,InternalNetworkPenetrationMapping internalNetworkPenetrationMapping) { + InternalNetworkPenetrationMappingDO internalNetworkPenetrationMappingDO = InternalNetworkPenetrationMappingConverter.INSTANCE.fromInternalNetworkPenetrationMapping(internalNetworkPenetrationMapping); + LazyPage lazyPage = new LazyPage<>(current,size); + LazyPage internalNetworkPenetrationMappingLazyPage = lazyLambdaStream.selectPage(LazyWrappers.lambdaWrapperBean(internalNetworkPenetrationMappingDO),lazyPage, InternalNetworkPenetrationMapping.class); + return ResultFactory.successOf(internalNetworkPenetrationMappingLazyPage); + } + + /** + * describe 删除内网穿透映射 + * + * @param internalNetworkPenetrationMapping 删除内网穿透映射 + * @return {@link Result} 内网穿透映射 + + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + **/ + + @Override + public Result remove(InternalNetworkPenetrationMapping internalNetworkPenetrationMapping) { + InternalNetworkPenetrationMappingDO internalNetworkPenetrationMappingDO = InternalNetworkPenetrationMappingConverter.INSTANCE.fromInternalNetworkPenetrationMapping(internalNetworkPenetrationMapping); + // lazyLambdaStream.delete(LazyWrappers.lambdaWrapperBean(internalNetworkPenetrationMappingDO)); + return ResultFactory.successOf(); + } + + /** + * describe 是否存在内网穿透映射 + * + * @param internalNetworkPenetrationMapping 内网穿透映射领域对象 + * @return {@link Result} 是否存在 true 存在,false 不存在 + + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + **/ + + @Override + public Result exists(InternalNetworkPenetrationMapping internalNetworkPenetrationMapping) { + InternalNetworkPenetrationMappingDO internalNetworkPenetrationMappingDO = InternalNetworkPenetrationMappingConverter.INSTANCE.fromInternalNetworkPenetrationMapping(internalNetworkPenetrationMapping); + Boolean exists=lazyLambdaStream.exists(LazyWrappers.lambdaWrapperBean(internalNetworkPenetrationMappingDO)); + return ResultFactory.successOf(exists); + } + +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/infrastructure/persistence/NettyClientBlacklistRepositoryImpl.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/infrastructure/persistence/NettyClientBlacklistRepositoryImpl.java new file mode 100644 index 0000000..5218730 --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/infrastructure/persistence/NettyClientBlacklistRepositoryImpl.java @@ -0,0 +1,146 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.infrastructure.persistence; + +import wu.framework.middleground.on.cloud.heartbeat.server.domain.infrastructure.converter.NettyClientBlacklistConverter; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.infrastructure.entity.NettyClientBlacklistDO; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.model.netty.client.blacklist.NettyClientBlacklist; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.model.netty.client.blacklist.NettyClientBlacklistRepository; +import com.wu.framework.inner.lazy.database.expand.database.persistence.domain.LazyPage; +import com.wu.framework.inner.lazy.database.expand.database.persistence.stream.lambda.LazyLambdaStream; +import com.wu.framework.inner.lazy.database.expand.database.persistence.stream.wrapper.LazyWrappers; +import com.wu.framework.response.Result; +import com.wu.framework.response.ResultFactory; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Repository; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * describe 客户端黑名单 + * + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + * @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyInfrastructurePersistence + **/ +@Repository +public class NettyClientBlacklistRepositoryImpl implements NettyClientBlacklistRepository { + + @Resource + LazyLambdaStream lazyLambdaStream; + + /** + * describe 新增客户端黑名单 + * + * @param nettyClientBlacklist 新增客户端黑名单 + * @return {@link Result} 客户端黑名单新增后领域对象 + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + @Override + public Result story(NettyClientBlacklist nettyClientBlacklist) { + NettyClientBlacklistDO nettyClientBlacklistDO = NettyClientBlacklistConverter.INSTANCE.fromNettyClientBlacklist(nettyClientBlacklist); + lazyLambdaStream.upsert(nettyClientBlacklistDO); + return ResultFactory.successOf(); + } + + /** + * describe 批量新增客户端黑名单 + * + * @param nettyClientBlacklistList 批量新增客户端黑名单 + * @return {@link Result>} 客户端黑名单新增后领域对象集合 + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + @Override + public Result> batchStory(List nettyClientBlacklistList) { + List nettyClientBlacklistDOList = nettyClientBlacklistList.stream().map(NettyClientBlacklistConverter.INSTANCE::fromNettyClientBlacklist).collect(Collectors.toList()); + lazyLambdaStream.upsert(nettyClientBlacklistDOList); + return ResultFactory.successOf(); + } + + /** + * describe 查询单个客户端黑名单 + * + * @param nettyClientBlacklist 查询单个客户端黑名单 + * @return {@link Result} 客户端黑名单领域对象 + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + @Override + public Result findOne(NettyClientBlacklist nettyClientBlacklist) { + NettyClientBlacklistDO nettyClientBlacklistDO = NettyClientBlacklistConverter.INSTANCE.fromNettyClientBlacklist(nettyClientBlacklist); + NettyClientBlacklist nettyClientBlacklistOne = lazyLambdaStream.selectOne(LazyWrappers.lambdaWrapperBean(nettyClientBlacklistDO), NettyClientBlacklist.class); + return ResultFactory.successOf(nettyClientBlacklistOne); + } + + /** + * describe 查询多个客户端黑名单 + * + * @param nettyClientBlacklist 查询多个客户端黑名单 + * @return {@link Result>} 客户端黑名单领域对象 + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + @Override + public Result> findList(NettyClientBlacklist nettyClientBlacklist) { + NettyClientBlacklistDO nettyClientBlacklistDO = NettyClientBlacklistConverter.INSTANCE.fromNettyClientBlacklist(nettyClientBlacklist); + List nettyClientBlacklistList = lazyLambdaStream.selectList(LazyWrappers.lambdaWrapperBean(nettyClientBlacklistDO), NettyClientBlacklist.class); + return ResultFactory.successOf(nettyClientBlacklistList); + } + + /** + * describe 分页查询多个客户端黑名单 + * + * @param size 当前页数 + * @param current 当前页 + * @param nettyClientBlacklist 分页查询多个客户端黑名单 + * @return {@link Result>} 分页客户端黑名单领域对象 + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + @Override + public Result> findPage(int size, int current, NettyClientBlacklist nettyClientBlacklist) { + NettyClientBlacklistDO nettyClientBlacklistDO = NettyClientBlacklistConverter.INSTANCE.fromNettyClientBlacklist(nettyClientBlacklist); + LazyPage lazyPage = new LazyPage<>(current, size); + LazyPage nettyClientBlacklistLazyPage = lazyLambdaStream.selectPage(LazyWrappers.lambdaWrapperBean(nettyClientBlacklistDO), lazyPage, NettyClientBlacklist.class); + return ResultFactory.successOf(nettyClientBlacklistLazyPage); + } + + /** + * describe 删除客户端黑名单 + * + * @param nettyClientBlacklist 删除客户端黑名单 + * @return {@link Result} 客户端黑名单 + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + @Override + public Result remove(NettyClientBlacklist nettyClientBlacklist) { + NettyClientBlacklistDO nettyClientBlacklistDO = NettyClientBlacklistConverter.INSTANCE.fromNettyClientBlacklist(nettyClientBlacklist); + // lazyLambdaStream.delete(LazyWrappers.lambdaWrapperBean(nettyClientBlacklistDO)); + return ResultFactory.successOf(); + } + + /** + * describe 是否存在客户端黑名单 + * + * @param nettyClientBlacklist 客户端黑名单领域对象 + * @return {@link Result} 是否存在 true 存在,false 不存在 + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + @Override + public Result exists(NettyClientBlacklist nettyClientBlacklist) { + NettyClientBlacklistDO nettyClientBlacklistDO = NettyClientBlacklistConverter.INSTANCE.fromNettyClientBlacklist(nettyClientBlacklist); + Boolean exists = lazyLambdaStream.exists(LazyWrappers.lambdaWrapperBean(nettyClientBlacklistDO)); + return ResultFactory.successOf(exists); + } + +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/infrastructure/persistence/NettyClientStateRepositoryImpl.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/infrastructure/persistence/NettyClientStateRepositoryImpl.java new file mode 100644 index 0000000..536c2bf --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/infrastructure/persistence/NettyClientStateRepositoryImpl.java @@ -0,0 +1,178 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.infrastructure.persistence; + +import wu.framework.middleground.on.cloud.heartbeat.server.domain.infrastructure.converter.NettyClientStateConverter; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.model.netty.client.state.NettyClientState; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.model.netty.client.state.NettyClientStateRepository; +import com.wu.framework.inner.lazy.database.expand.database.persistence.domain.LazyPage; +import com.wu.framework.inner.lazy.database.expand.database.persistence.stream.lambda.LazyLambdaStream; +import com.wu.framework.inner.lazy.database.expand.database.persistence.stream.wrapper.LazyWrappers; +import com.wu.framework.response.Result; +import com.wu.framework.response.ResultFactory; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Repository; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.infrastructure.entity.NettyClientStateDO; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * describe 客户端状态 + * + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + * @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyInfrastructurePersistence + **/ +@Repository +public class NettyClientStateRepositoryImpl implements NettyClientStateRepository { + + @Resource + LazyLambdaStream lazyLambdaStream; + + /** + * describe 新增客户端状态 + * + * @param nettyClientState 新增客户端状态 + * @return {@link Result} 客户端状态新增后领域对象 + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + @Override + public Result story(NettyClientState nettyClientState) { + + NettyClientStateDO nettyClientStateDO = NettyClientStateConverter.INSTANCE.fromNettyClientState(nettyClientState); + lazyLambdaStream.upsert(nettyClientStateDO); + return ResultFactory.successOf(); + } + + /** + * describe 批量新增客户端状态 + * + * @param nettyClientStateList 批量新增客户端状态 + * @return {@link Result>} 客户端状态新增后领域对象集合 + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + @Override + public Result> batchStory(List nettyClientStateList) { + List nettyClientStateDOList = nettyClientStateList.stream().map(NettyClientStateConverter.INSTANCE::fromNettyClientState).collect(Collectors.toList()); + lazyLambdaStream.upsert(nettyClientStateDOList); + return ResultFactory.successOf(); + } + + /** + * describe 查询单个客户端状态 + * + * @param nettyClientState 查询单个客户端状态 + * @return {@link Result} 客户端状态领域对象 + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + @Override + public Result findOne(NettyClientState nettyClientState) { + NettyClientStateDO nettyClientStateDO = NettyClientStateConverter.INSTANCE.fromNettyClientState(nettyClientState); + NettyClientState nettyClientStateOne = lazyLambdaStream.selectOne(LazyWrappers.lambdaWrapperBean(nettyClientStateDO), NettyClientState.class); + return ResultFactory.successOf(nettyClientStateOne); + } + + /** + * describe 查询多个客户端状态 + * + * @param nettyClientState 查询多个客户端状态 + * @return {@link Result>} 客户端状态领域对象 + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + @Override + public Result> findList(NettyClientState nettyClientState) { + NettyClientStateDO nettyClientStateDO = NettyClientStateConverter.INSTANCE.fromNettyClientState(nettyClientState); + List nettyClientStateList = lazyLambdaStream.selectList(LazyWrappers.lambdaWrapperBean(nettyClientStateDO), NettyClientState.class); + return ResultFactory.successOf(nettyClientStateList); + } + + /** + * describe 分页查询多个客户端状态 + * + * @param size 当前页数 + * @param current 当前页 + * @param nettyClientState 分页查询多个客户端状态 + * @return {@link Result>} 分页客户端状态领域对象 + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + @Override + public Result> findPage(int size, int current, NettyClientState nettyClientState) { + NettyClientStateDO nettyClientStateDO = NettyClientStateConverter.INSTANCE.fromNettyClientState(nettyClientState); + LazyPage lazyPage = new LazyPage<>(current, size); + LazyPage nettyClientStateLazyPage = lazyLambdaStream.selectPage(LazyWrappers.lambdaWrapperBean(nettyClientStateDO), lazyPage, NettyClientState.class); + return ResultFactory.successOf(nettyClientStateLazyPage); + } + + /** + * describe 删除客户端状态 + * + * @param nettyClientState 删除客户端状态 + * @return {@link Result} 客户端状态 + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + @Override + public Result remove(NettyClientState nettyClientState) { + NettyClientStateDO nettyClientStateDO = NettyClientStateConverter.INSTANCE.fromNettyClientState(nettyClientState); + // lazyLambdaStream.delete(LazyWrappers.lambdaWrapperBean(nettyClientStateDO)); + return ResultFactory.successOf(); + } + + /** + * describe 是否存在客户端状态 + * + * @param nettyClientState 客户端状态领域对象 + * @return {@link Result} 是否存在 true 存在,false 不存在 + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + @Override + public Result exists(NettyClientState nettyClientState) { + NettyClientStateDO nettyClientStateDO = NettyClientStateConverter.INSTANCE.fromNettyClientState(nettyClientState); + Boolean exists = lazyLambdaStream.exists(LazyWrappers.lambdaWrapperBean(nettyClientStateDO)); + return ResultFactory.successOf(exists); + } + + /** + * 修改客户端状态 + * + * @param nettyClientState 客户端状态 + * @return Result + */ + @Override + public Result updateOnLIneState(NettyClientState nettyClientState) { + NettyClientStateDO nettyClientStateDO = NettyClientStateConverter.INSTANCE.fromNettyClientState(nettyClientState); + // 查询客户端是否存在 + // 存在更新客户端在线状态 + // 不存在新增一条 + lazyLambdaStream.upsertRemoveNull(nettyClientStateDO); + return ResultFactory.successOf(); + } + + /** + * 修改客户端暂存状态 + * + * @param nettyClientState 客户端信息 + * @return Result + */ + @Override + public Result updateStagingState(NettyClientState nettyClientState) { + NettyClientStateDO nettyClientStateDO = NettyClientStateConverter.INSTANCE.fromNettyClientState(nettyClientState); + // 查询客户端是否存在 + // 存在更新客户端在线状态 + // 不存在新增一条 + lazyLambdaStream.upsertRemoveNull(nettyClientStateDO); + return ResultFactory.successOf(); + } +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/model/internal/network/penetration/mapping/InternalNetworkPenetrationMapping.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/model/internal/network/penetration/mapping/InternalNetworkPenetrationMapping.java new file mode 100644 index 0000000..9e3c42f --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/model/internal/network/penetration/mapping/InternalNetworkPenetrationMapping.java @@ -0,0 +1,85 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.model.internal.network.penetration.mapping; + +import com.wu.framework.inner.lazy.stereotype.LazyTableField; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.time.LocalDateTime; +/** + * describe 内网穿透映射 + * + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + * @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyDomain + **/ +@Data +@Accessors(chain = true) +@Schema(title = "internal_network_penetration_mapping",description = "内网穿透映射") +public class InternalNetworkPenetrationMapping { + + + /** + * + * 客户端ID + */ + @Schema(description ="客户端ID",name ="clientId",example = "") + private String clientId; + + /** + * + * 客户端目标地址 + */ + @Schema(description ="客户端目标地址",name ="clientTargetIp",example = "") + private String clientTargetIp; + + /** + * + * 客户端目标端口 + */ + @Schema(description ="客户端目标端口",name ="clientTargetPort",example = "") + private Integer clientTargetPort; + + /** + * + * 创建时间 + */ + @Schema(description ="创建时间",name ="createTime",example = "") + private LocalDateTime createTime; + + /** + * + * 主键自增 + */ + @Schema(description ="主键自增",name ="id",example = "") + private Long id; + + /** + * + * 是否删除 默认否 + */ + @Schema(description ="是否删除 默认否",name ="isDeleted",example = "") + private Boolean isDeleted; + + /** + * + * 修改时间 + */ + @Schema(description ="修改时间",name ="updateTime",example = "") + private LocalDateTime updateTime; + + /** + * + * 访问端口 + */ + @Schema(description ="访问端口",name ="visitorPort",example = "") + private Integer visitorPort; + + /** + * + * 描述 + */ + @Schema(description ="描述",name ="describe",example = "") + private String describe; + +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/model/internal/network/penetration/mapping/InternalNetworkPenetrationMappingRepository.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/model/internal/network/penetration/mapping/InternalNetworkPenetrationMappingRepository.java new file mode 100644 index 0000000..2b32e90 --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/model/internal/network/penetration/mapping/InternalNetworkPenetrationMappingRepository.java @@ -0,0 +1,104 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.model.internal.network.penetration.mapping; + +import com.wu.framework.inner.lazy.database.expand.database.persistence.domain.LazyPage; +import com.wu.framework.response.Result; + +import java.util.List; +/** + * describe 内网穿透映射 + * + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + * @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyDomainRepository + **/ + +public interface InternalNetworkPenetrationMappingRepository { + + + /** + * describe 新增内网穿透映射 + * + * @param internalNetworkPenetrationMapping 新增内网穿透映射 + * @return {@link Result} 内网穿透映射新增后领域对象 + + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + **/ + + Result story(InternalNetworkPenetrationMapping internalNetworkPenetrationMapping); + + /** + * describe 批量新增内网穿透映射 + * + * @param internalNetworkPenetrationMappingList 批量新增内网穿透映射 + * @return {@link Result>} 内网穿透映射新增后领域对象集合 + + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + **/ + + Result> batchStory(List internalNetworkPenetrationMappingList); + + /** + * describe 查询单个内网穿透映射 + * + * @param internalNetworkPenetrationMapping 查询单个内网穿透映射 + * @return {@link Result} 内网穿透映射DTO对象 + + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + **/ + + Result findOne(InternalNetworkPenetrationMapping internalNetworkPenetrationMapping); + + /** + * describe 查询多个内网穿透映射 + * + * @param internalNetworkPenetrationMapping 查询多个内网穿透映射 + * @return {@link Result>} 内网穿透映射DTO对象 + + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + **/ + + Result> findList(InternalNetworkPenetrationMapping internalNetworkPenetrationMapping); + + /** + * describe 分页查询多个内网穿透映射 + * + * @param size 当前页数 + * @param current 当前页 + * @param internalNetworkPenetrationMapping 分页查询多个内网穿透映射 + * @return {@link Result>} 分页内网穿透映射领域对象 + + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + **/ + + Result> findPage(int size,int current,InternalNetworkPenetrationMapping internalNetworkPenetrationMapping); + + /** + * describe 删除内网穿透映射 + * + * @param internalNetworkPenetrationMapping 删除内网穿透映射 + * @return {@link Result} 内网穿透映射 + + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + **/ + + Result remove(InternalNetworkPenetrationMapping internalNetworkPenetrationMapping); + + /** + * describe 是否存在内网穿透映射 + * + * @param internalNetworkPenetrationMapping 是否存在内网穿透映射 + * @return {@link Result} 内网穿透映射是否存在 + + * @author Jia wei Wu + * @date 2023/12/29 05:21 下午 + **/ + + Result exists(InternalNetworkPenetrationMapping internalNetworkPenetrationMapping); + +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/model/netty/client/blacklist/NettyClientBlacklist.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/model/netty/client/blacklist/NettyClientBlacklist.java new file mode 100644 index 0000000..9187094 --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/model/netty/client/blacklist/NettyClientBlacklist.java @@ -0,0 +1,56 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.model.netty.client.blacklist; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.time.LocalDateTime; +/** + * describe 客户端黑名单 + * + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + * @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyDomain + **/ +@Data +@Accessors(chain = true) +@Schema(title = "netty_client_blacklist",description = "客户端黑名单") +public class NettyClientBlacklist { + + + /** + * + * 客户端ID + */ + @Schema(description ="客户端ID",name ="clientId",example = "") + private String clientId; + + /** + * + * 创建时间 + */ + @Schema(description ="创建时间",name ="createTime",example = "") + private LocalDateTime createTime; + + /** + * + * 主键 + */ + @Schema(description ="主键",name ="id",example = "") + private Long id; + + /** + * + * 是否删除 + */ + @Schema(description ="是否删除",name ="isDeleted",example = "") + private Boolean isDeleted; + + /** + * + * 更新时间 + */ + @Schema(description ="更新时间",name ="updateTime",example = "") + private LocalDateTime updateTime; + +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/model/netty/client/blacklist/NettyClientBlacklistRepository.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/model/netty/client/blacklist/NettyClientBlacklistRepository.java new file mode 100644 index 0000000..aa0d9a7 --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/model/netty/client/blacklist/NettyClientBlacklistRepository.java @@ -0,0 +1,104 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.model.netty.client.blacklist; + +import com.wu.framework.inner.lazy.database.expand.database.persistence.domain.LazyPage; +import com.wu.framework.response.Result; + +import java.util.List; +/** + * describe 客户端黑名单 + * + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + * @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyDomainRepository + **/ + +public interface NettyClientBlacklistRepository { + + + /** + * describe 新增客户端黑名单 + * + * @param nettyClientBlacklist 新增客户端黑名单 + * @return {@link Result} 客户端黑名单新增后领域对象 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + Result story(NettyClientBlacklist nettyClientBlacklist); + + /** + * describe 批量新增客户端黑名单 + * + * @param nettyClientBlacklistList 批量新增客户端黑名单 + * @return {@link Result>} 客户端黑名单新增后领域对象集合 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + Result> batchStory(List nettyClientBlacklistList); + + /** + * describe 查询单个客户端黑名单 + * + * @param nettyClientBlacklist 查询单个客户端黑名单 + * @return {@link Result} 客户端黑名单DTO对象 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + Result findOne(NettyClientBlacklist nettyClientBlacklist); + + /** + * describe 查询多个客户端黑名单 + * + * @param nettyClientBlacklist 查询多个客户端黑名单 + * @return {@link Result>} 客户端黑名单DTO对象 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + Result> findList(NettyClientBlacklist nettyClientBlacklist); + + /** + * describe 分页查询多个客户端黑名单 + * + * @param size 当前页数 + * @param current 当前页 + * @param nettyClientBlacklist 分页查询多个客户端黑名单 + * @return {@link Result>} 分页客户端黑名单领域对象 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + Result> findPage(int size,int current,NettyClientBlacklist nettyClientBlacklist); + + /** + * describe 删除客户端黑名单 + * + * @param nettyClientBlacklist 删除客户端黑名单 + * @return {@link Result} 客户端黑名单 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + Result remove(NettyClientBlacklist nettyClientBlacklist); + + /** + * describe 是否存在客户端黑名单 + * + * @param nettyClientBlacklist 是否存在客户端黑名单 + * @return {@link Result} 客户端黑名单是否存在 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + Result exists(NettyClientBlacklist nettyClientBlacklist); + +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/model/netty/client/state/NettyClientState.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/model/netty/client/state/NettyClientState.java new file mode 100644 index 0000000..a3ff75f --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/model/netty/client/state/NettyClientState.java @@ -0,0 +1,71 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.model.netty.client.state; + +import wu.framework.middleground.cloud.heartbeat.common.enums.NettyClientStatus; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.time.LocalDateTime; +/** + * describe 客户端状态 + * + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + * @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyDomain + **/ +@Data +@Accessors(chain = true) +@Schema(title = "netty_client_state",description = "客户端状态") +public class NettyClientState { + + + /** + * + * 客户端ID + */ + @Schema(description ="客户端ID",name ="clientId",example = "") + private String clientId; + + /** + * + * 创建时间 + */ + @Schema(description ="创建时间",name ="createTime",example = "") + private LocalDateTime createTime; + + /** + * + * 主键 + */ + @Schema(description ="主键",name ="id",example = "") + private Long id; + + /** + * + * 是否删除 + */ + @Schema(description ="是否删除",name ="isDeleted",example = "") + private Boolean isDeleted; + + /** + * + * 在线状态(true在线,false离线) + */ + @Schema(description ="在线状态(true在线,false离线)",name ="onLineState",example = "") + private NettyClientStatus onLineState; + + /** + * + * 暂存状态(开启、关闭) + */ + @Schema(description ="暂存状态(开启、关闭)",name ="staging",example = "") + private String stagingState; + + /** + * + * 修改时间 + */ + @Schema(description ="修改时间",name ="updateTime",example = "") + private LocalDateTime updateTime; + +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/model/netty/client/state/NettyClientStateRepository.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/model/netty/client/state/NettyClientStateRepository.java new file mode 100644 index 0000000..8069cb9 --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/model/netty/client/state/NettyClientStateRepository.java @@ -0,0 +1,118 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.model.netty.client.state; + +import com.wu.framework.inner.lazy.database.expand.database.persistence.domain.LazyPage; +import com.wu.framework.response.Result; + +import java.util.List; +/** + * describe 客户端状态 + * + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + * @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyDomainRepository + **/ + +public interface NettyClientStateRepository { + + + /** + * describe 新增客户端状态 + * + * @param nettyClientState 新增客户端状态 + * @return {@link Result} 客户端状态新增后领域对象 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + Result story(NettyClientState nettyClientState); + + /** + * describe 批量新增客户端状态 + * + * @param nettyClientStateList 批量新增客户端状态 + * @return {@link Result>} 客户端状态新增后领域对象集合 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + Result> batchStory(List nettyClientStateList); + + /** + * describe 查询单个客户端状态 + * + * @param nettyClientState 查询单个客户端状态 + * @return {@link Result} 客户端状态DTO对象 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + Result findOne(NettyClientState nettyClientState); + + /** + * describe 查询多个客户端状态 + * + * @param nettyClientState 查询多个客户端状态 + * @return {@link Result>} 客户端状态DTO对象 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + Result> findList(NettyClientState nettyClientState); + + /** + * describe 分页查询多个客户端状态 + * + * @param size 当前页数 + * @param current 当前页 + * @param nettyClientState 分页查询多个客户端状态 + * @return {@link Result>} 分页客户端状态领域对象 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + Result> findPage(int size,int current,NettyClientState nettyClientState); + + /** + * describe 删除客户端状态 + * + * @param nettyClientState 删除客户端状态 + * @return {@link Result} 客户端状态 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + Result remove(NettyClientState nettyClientState); + + /** + * describe 是否存在客户端状态 + * + * @param nettyClientState 是否存在客户端状态 + * @return {@link Result} 客户端状态是否存在 + + * @author Jia wei Wu + * @date 2023/12/27 03:46 下午 + **/ + + Result exists(NettyClientState nettyClientState); + + /** + * 修改客户端在线状态 + * + * @param nettyClientState 客户端状态 + * @return Result + */ + Result updateOnLIneState(NettyClientState nettyClientState); + + /** + * 修改客户端暂存状态 + * @param nettyClientState 客户端信息 + * @return Result + */ + Result updateStagingState(NettyClientState nettyClientState); +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/advanced/ServerChannelHeartbeatTypeAdvanced.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/advanced/ServerChannelHeartbeatTypeAdvanced.java new file mode 100644 index 0000000..6af54e2 --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/advanced/ServerChannelHeartbeatTypeAdvanced.java @@ -0,0 +1,32 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.netty.advanced; + + +import wu.framework.middleground.cloud.heartbeat.common.MessageType; +import wu.framework.middleground.cloud.heartbeat.common.NettyProxyMsg; +import wu.framework.middleground.cloud.heartbeat.common.advanced.AbstractChannelHeartbeatTypeAdvanced; +import io.netty.channel.Channel; +import org.springframework.stereotype.Component; + + +/** + * 服务端 处理客户端心跳 + * TYPE_HEARTBEAT + */ +@Component +public class ServerChannelHeartbeatTypeAdvanced extends AbstractChannelHeartbeatTypeAdvanced { + + /** + * 处理当前数据 + * + * @param channel 当前通道 + * @param msg 通道数据 + */ + @Override + public void doHandler(Channel channel, NettyProxyMsg msg) { + NettyProxyMsg hb = new NettyProxyMsg(); + hb.setType(MessageType.TYPE_HEARTBEAT); + channel.writeAndFlush(hb); + } + + +} diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/advanced/ServerReportChannelTransferTypeAdvanced.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/advanced/ServerReportChannelTransferTypeAdvanced.java new file mode 100644 index 0000000..d948a57 --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/advanced/ServerReportChannelTransferTypeAdvanced.java @@ -0,0 +1,41 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.netty.advanced; + + +import wu.framework.middleground.cloud.heartbeat.common.NettyProxyMsg; +import wu.framework.middleground.cloud.heartbeat.common.NettyRealIdContext; +import wu.framework.middleground.cloud.heartbeat.common.advanced.server.AbstractReportChannelTransferTypeAdvanced; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + + +/** + * 服务端处理客户端数据传输 + * REPORT_CLIENT_STAGING_CLOSED + */ +@Slf4j +@Component +public class ServerReportChannelTransferTypeAdvanced extends AbstractReportChannelTransferTypeAdvanced { + + /** + * 处理当前数据 + * + * @param channel 当前通道 + * @param msg 通道数据 + */ + @Override + public void doHandler(Channel channel, NettyProxyMsg msg) { + log.debug("接收到客户端:[{}]内网穿透返回的数据:[{}]", new String(msg.getClientId()), new String(msg.getData())); + // 将数据转发访客通道 + byte[] visitorId = msg.getVisitorId(); + Channel visitor = NettyRealIdContext.getVisitor(visitorId); + if (visitor != null) { + ByteBuf buf = visitor.config().getAllocator().buffer(msg.getData().length); + buf.writeBytes(msg.getData()); + visitor.writeAndFlush(buf); + } + + } + +} diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/advanced/ServerReportConnectSuccessTypeAdvanced.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/advanced/ServerReportConnectSuccessTypeAdvanced.java new file mode 100644 index 0000000..991bcd6 --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/advanced/ServerReportConnectSuccessTypeAdvanced.java @@ -0,0 +1,91 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.netty.advanced; + + +import com.alibaba.fastjson.JSON; +import wu.framework.middleground.cloud.heartbeat.common.ChannelContext; +import wu.framework.middleground.cloud.heartbeat.common.MessageType; +import wu.framework.middleground.cloud.heartbeat.common.NettyProxyMsg; +import wu.framework.middleground.cloud.heartbeat.common.advanced.server.AbstractReportConnectSuccessTypeAdvanced; +import wu.framework.middleground.cloud.heartbeat.common.utils.ChannelAttributeKeyUtils; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.application.InternalNetworkPenetrationMappingApplication; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.application.NettyClientBlacklistApplication; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.application.ServerNettyConfigApplication; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.model.netty.client.blacklist.NettyClientBlacklist; +import io.netty.channel.Channel; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.nio.charset.StandardCharsets; +import java.util.List; + + +/** + * 服务端连接成功处理 + * REPORT_CLIENT_CONNECT_SUCCESS + */ +@Slf4j +@Component +public class ServerReportConnectSuccessTypeAdvanced extends AbstractReportConnectSuccessTypeAdvanced { + + private final ServerNettyConfigApplication serverNettyConfigApplication; + private final NettyClientBlacklistApplication nettyClientBlacklistApplication; + private final InternalNetworkPenetrationMappingApplication internalNetworkPenetrationMappingApplication; + + public ServerReportConnectSuccessTypeAdvanced(ServerNettyConfigApplication serverNettyConfigApplication, NettyClientBlacklistApplication nettyClientBlacklistApplication, InternalNetworkPenetrationMappingApplication internalNetworkPenetrationMappingApplication) { + this.serverNettyConfigApplication = serverNettyConfigApplication; + this.nettyClientBlacklistApplication = nettyClientBlacklistApplication; + this.internalNetworkPenetrationMappingApplication = internalNetworkPenetrationMappingApplication; + } + + + /** + * 处理当前数据 + * + * @param newChannel 当前通道 + * @param msg 通道数据 + */ + @Override + public void doHandler(Channel newChannel, NettyProxyMsg msg) { + ChannelContext.push(newChannel, msg); + + String clientId = new String(msg.getClientId()); + + ChannelAttributeKeyUtils.buildClientId(newChannel,clientId); + log.info("客户端:{}连接成功",new String(msg.getClientId())); + // 验证客户端是否时黑名单 + NettyClientBlacklist nettyClientBlacklist = new NettyClientBlacklist(); + nettyClientBlacklist.setClientId(clientId); + nettyClientBlacklist.setIsDeleted(false); + nettyClientBlacklistApplication.exists(nettyClientBlacklist).accept(exists -> { + if(!exists){ + // 服务状态在线 + serverNettyConfigApplication.clientOnLine(clientId); + List clientChannels = ChannelContext.get(); + log.info("当前在线客户端数量:{}", clientChannels.size()); + // 所有的客户端ID + List clientIdList = clientChannels.stream().map(clientChannel1 -> new String(clientChannel1.getClientId())).toList(); + + // TODO 多副本本地channel 无法共享问题 + // 通知所有客户端有人上线了 + for (ChannelContext.ClientChannel clientChannel : clientChannels) { + Channel channel = clientChannel.getChannel(); + NettyProxyMsg nettyMsg = new NettyProxyMsg(); + nettyMsg.setType(MessageType.DISTRIBUTE_CLIENT_CONNECTION_SUCCESS_NOTIFICATION); + nettyMsg.setData((JSON.toJSONString(clientIdList).toString() + .getBytes(StandardCharsets.UTF_8))); + // 发送所有客户端ID + channel.writeAndFlush(nettyMsg); + } + // 创建访问者(内网穿透连接创建) + internalNetworkPenetrationMappingApplication.createVisitor(clientId); + + }else { + // 黑名单客户端 + + } + }); + + + } + +} diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/advanced/ServerReportDisconnectTypeAdvanced.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/advanced/ServerReportDisconnectTypeAdvanced.java new file mode 100644 index 0000000..c9e0b54 --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/advanced/ServerReportDisconnectTypeAdvanced.java @@ -0,0 +1,73 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.netty.advanced; + + +import wu.framework.middleground.cloud.heartbeat.common.ChannelContext; +import wu.framework.middleground.cloud.heartbeat.common.MessageType; +import wu.framework.middleground.cloud.heartbeat.common.NettyProxyMsg; +import wu.framework.middleground.cloud.heartbeat.common.advanced.server.AbstractReportDisconnectTypeAdvanced; +import io.netty.channel.Channel; +import io.netty.channel.ChannelId; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.application.ServerNettyConfigApplication; + +import java.util.List; + + +/** + * 服务端处理客户端断开连接处理 + * TYPE_DISCONNECT + */ +@Slf4j +@Component +public class ServerReportDisconnectTypeAdvanced extends AbstractReportDisconnectTypeAdvanced { + private final ServerNettyConfigApplication serverNettyConfigApplication; + + public ServerReportDisconnectTypeAdvanced(ServerNettyConfigApplication serverNettyConfigApplication) { + this.serverNettyConfigApplication = serverNettyConfigApplication; + } + + /** + * 处理当前数据 + * + * @param deathChannel 关闭的通道 + * @param msg 通道数据 + */ + @Override + public void doHandler(Channel deathChannel, NettyProxyMsg msg) { + // 关闭连接通知 + byte[] clientIdByte = msg.getClientId(); + log.info("关闭客户端:{} 的通道",new String(clientIdByte)); + ChannelId deathChannelId = deathChannel.id(); + ChannelContext.ClientChannel deathClientChannelDTO = ChannelContext.get(deathChannelId); + + if (deathClientChannelDTO != null) { + byte[] clientId = deathClientChannelDTO.getClientId(); + // 服务状态离线 + String tenantId = new String(clientId); + serverNettyConfigApplication.clientOffLine(tenantId); + ChannelContext.remove(deathChannelId); + List clientChannels = ChannelContext.get(); + + // 通知其他客户端 channelId 关闭了 + for (ChannelContext.ClientChannel clientChannel : clientChannels) { + Channel channel = clientChannel.getChannel(); + + // 离线通知 + NettyProxyMsg nettyMsg = new NettyProxyMsg(); + nettyMsg.setType(MessageType.DISTRIBUTE_CLIENT_DISCONNECTION_NOTIFICATION); + nettyMsg.setClientId(clientId); + nettyMsg.setData(clientId); + channel.writeAndFlush(nettyMsg); + // 暂存通知 + NettyProxyMsg stagingNettyProxyMsg = new NettyProxyMsg(); + stagingNettyProxyMsg.setType(MessageType.DISTRIBUTE_CLIENT_STAGING_OPENED_NOTIFICATION); + stagingNettyProxyMsg.setData(clientId); + stagingNettyProxyMsg.setClientId(clientId); + channel.writeAndFlush(stagingNettyProxyMsg); + } + } + } + + +} diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/advanced/ServerReportSingleClientCloseVisitorTypeAdvanced.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/advanced/ServerReportSingleClientCloseVisitorTypeAdvanced.java new file mode 100644 index 0000000..57f6288 --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/advanced/ServerReportSingleClientCloseVisitorTypeAdvanced.java @@ -0,0 +1,32 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.netty.advanced; + +import wu.framework.middleground.cloud.heartbeat.common.NettyCommunicationIdContext; +import wu.framework.middleground.cloud.heartbeat.common.NettyProxyMsg; +import wu.framework.middleground.cloud.heartbeat.common.NettyRealIdContext; +import wu.framework.middleground.cloud.heartbeat.common.advanced.server.AbstractReportSingleClientCloseVisitorTypeAdvanced; +import io.netty.channel.Channel; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * 服务端处理客户端 关闭一个访客 + */ +@Slf4j +@Component +public class ServerReportSingleClientCloseVisitorTypeAdvanced extends AbstractReportSingleClientCloseVisitorTypeAdvanced { + + + /** + * 处理当前数据 + * + * @param channel 当前通道 + * @param nettyProxyMsg 通道数据 + */ + @Override + protected void doHandler(Channel channel, NettyProxyMsg nettyProxyMsg) { + // 关闭访客通道 + byte[] visitorId = nettyProxyMsg.getVisitorId(); + NettyCommunicationIdContext.clear(visitorId); + NettyRealIdContext.clear(visitorId); + } +} diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/advanced/ServerReportSingleClientRealConnectTypeAdvanced.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/advanced/ServerReportSingleClientRealConnectTypeAdvanced.java new file mode 100644 index 0000000..1f15281 --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/advanced/ServerReportSingleClientRealConnectTypeAdvanced.java @@ -0,0 +1,46 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.netty.advanced; + +import wu.framework.middleground.cloud.heartbeat.common.NettyCommunicationIdContext; +import wu.framework.middleground.cloud.heartbeat.common.NettyProxyMsg; +import wu.framework.middleground.cloud.heartbeat.common.NettyRealIdContext; +import wu.framework.middleground.cloud.heartbeat.common.advanced.server.AbstractReportSingleClientRealConnectTypeAdvanced; +import wu.framework.middleground.cloud.heartbeat.common.utils.ChannelAttributeKeyUtils; +import io.netty.channel.Channel; +import io.netty.channel.ChannelOption; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +public class ServerReportSingleClientRealConnectTypeAdvanced extends AbstractReportSingleClientRealConnectTypeAdvanced { + + /** + * 处理当前数据 + * + * @param channel 当前通道 + * @param nettyProxyMsg 通道数据 + */ + @Override + protected void doHandler(Channel channel, NettyProxyMsg nettyProxyMsg) { + // 客户端绑定端口成功 + byte[] clientId = nettyProxyMsg.getClientId(); + byte[] clientTargetIp = nettyProxyMsg.getClientTargetIp(); + byte[] clientTargetPort = nettyProxyMsg.getClientTargetPort(); + byte[] visitorPort = nettyProxyMsg.getVisitorPort(); + byte[] visitorId = nettyProxyMsg.getVisitorId(); + log.info("客户端:{},绑定真实服务ip:{},port:{},成功", new String(clientId), new String(clientTargetIp), new String(clientTargetPort)); + // 绑定服务端访客通信通道 + NettyCommunicationIdContext.pushVisitor(channel,new String(visitorId)); + ChannelAttributeKeyUtils.buildVisitorId(channel, visitorId); + ChannelAttributeKeyUtils.buildClientId(channel, clientId); + // 访客通道开启自动读取 + Channel visitorRealChannel = NettyRealIdContext.getVisitor(new String(visitorId)); + visitorRealChannel.config().setOption(ChannelOption.AUTO_READ, true); + + // 或许此处还应该通知服务端 这个访客绑定的客户端真实通道打开 + + // 下发客户端 真实通道自动读写开启 + + + } +} diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/advanced/ServerReportStagingClosedTypeAdvanced.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/advanced/ServerReportStagingClosedTypeAdvanced.java new file mode 100644 index 0000000..ead359b --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/advanced/ServerReportStagingClosedTypeAdvanced.java @@ -0,0 +1,61 @@ + +package wu.framework.middleground.on.cloud.heartbeat.server.domain.netty.advanced; + +import wu.framework.middleground.cloud.heartbeat.common.ChannelContext; +import wu.framework.middleground.cloud.heartbeat.common.MessageType; +import wu.framework.middleground.cloud.heartbeat.common.NettyProxyMsg; +import wu.framework.middleground.cloud.heartbeat.common.advanced.server.AbstractReportStagingClosedTypeAdvanced; + +import io.netty.channel.Channel; +import io.netty.channel.ChannelId; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.application.ServerNettyConfigApplication; + +import java.nio.charset.StandardCharsets; +import java.util.List; + +/** + * 服务端处理上报的暂存关闭 + */ +@Slf4j +@Component +public class ServerReportStagingClosedTypeAdvanced extends AbstractReportStagingClosedTypeAdvanced { + private final ServerNettyConfigApplication serverNettyConfigApplication; + + public ServerReportStagingClosedTypeAdvanced(ServerNettyConfigApplication serverNettyConfigApplication) { + this.serverNettyConfigApplication = serverNettyConfigApplication; + } + + /** + * 处理当前数据 + * + * @param stagingClosedChannel 关闭暂存的通道 + * @param msg 通道数据 + */ + @Override + protected void doHandler(Channel stagingClosedChannel, NettyProxyMsg msg) { + byte[] clientIdBytes = msg.getClientId(); + // 获取所有通道 + List clientChannels = ChannelContext.get(); + ChannelId stagingClosedChannelId = stagingClosedChannel.id(); + ChannelContext.ClientChannel stagingOpenedClientChannel = ChannelContext.get(stagingClosedChannelId); + if (stagingOpenedClientChannel != null) { + String clientId = new String(clientIdBytes); + // 存储当前客户端暂存关闭 + serverNettyConfigApplication.stagingClosed(clientId); + for (ChannelContext.ClientChannel clientChannel : clientChannels) { + // 告诉他们 当前参数这个通道 暂存关闭了 + Channel channel = clientChannel.getChannel(); + NettyProxyMsg nettyMsg = new NettyProxyMsg(); + nettyMsg.setType(MessageType.DISTRIBUTE_CLIENT_STAGING_CLOSED_NOTIFICATION); + nettyMsg.setData((clientId + .getBytes(StandardCharsets.UTF_8))); + nettyMsg.setClientId((clientId + .getBytes(StandardCharsets.UTF_8))); + channel.writeAndFlush(nettyMsg); + } + } + + } +} diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/advanced/ServerReportStagingOpenedTypeAdvanced.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/advanced/ServerReportStagingOpenedTypeAdvanced.java new file mode 100644 index 0000000..e47bb29 --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/advanced/ServerReportStagingOpenedTypeAdvanced.java @@ -0,0 +1,61 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.netty.advanced; + +import wu.framework.middleground.cloud.heartbeat.common.ChannelContext; +import wu.framework.middleground.cloud.heartbeat.common.MessageType; +import wu.framework.middleground.cloud.heartbeat.common.NettyProxyMsg; +import wu.framework.middleground.cloud.heartbeat.common.advanced.server.AbstractReportStagingOpenedTypeAdvanced; +import io.netty.channel.Channel; +import io.netty.channel.ChannelId; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.application.ServerNettyConfigApplication; + +import java.nio.charset.StandardCharsets; +import java.util.List; + +/** + * 服务端处理上报的暂存开启 + */ +@Slf4j +@Component +public class ServerReportStagingOpenedTypeAdvanced extends AbstractReportStagingOpenedTypeAdvanced { + + private final ServerNettyConfigApplication serverNettyConfigApplication; + + public ServerReportStagingOpenedTypeAdvanced(ServerNettyConfigApplication serverNettyConfigApplication) { + this.serverNettyConfigApplication = serverNettyConfigApplication; + } + + /** + * 处理当前数据 + * + * @param stagingOpenedChannel 开启暂存的通道 + * @param msg 通道数据 + */ + @Override + protected void doHandler(Channel stagingOpenedChannel, NettyProxyMsg msg) { + // 获取所有通道 + byte[] clientIdBytes = msg.getClientId(); + List clientChannels = ChannelContext.get(); + ChannelId stagingOpenedChannelId = stagingOpenedChannel.id(); + ChannelContext.ClientChannel stagingOpenedClientChannel = ChannelContext.get(stagingOpenedChannelId); + if (stagingOpenedClientChannel != null) { + for (ChannelContext.ClientChannel clientChannel : clientChannels) { + // 存储当前客户端暂存关闭 + String clientId = new String(clientIdBytes); + serverNettyConfigApplication.stagingOpened(clientId); + // 告诉他们 当前参数这个通道 暂存开启了 + Channel channel = clientChannel.getChannel(); + NettyProxyMsg nettyMsg = new NettyProxyMsg(); + nettyMsg.setType(MessageType.DISTRIBUTE_CLIENT_STAGING_OPENED_NOTIFICATION); + nettyMsg.setData((clientId + .getBytes(StandardCharsets.UTF_8))); + nettyMsg.setClientId((clientId + .getBytes(StandardCharsets.UTF_8))); + channel.writeAndFlush(nettyMsg); + } + } + + + } +} diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/config/AutoConfiguration.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/config/AutoConfiguration.java new file mode 100644 index 0000000..aa345fa --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/config/AutoConfiguration.java @@ -0,0 +1,64 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.netty.config; + + +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.autoconfigure.web.ServerProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.netty.filter.NettyServerFilter; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.netty.socket.NettyOnCloudNettyServerSocket; + +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + + +/** + * description 自动配置 + * + * @author 吴佳伟 + * @date 2023/09/12 18:22 + */ +@Slf4j +@Configuration +public class AutoConfiguration implements CommandLineRunner { + + private final ServerProperties serverProperties; + private final NettyServerFilter nettyServerFilter; + ThreadPoolExecutor NETTY_SERVER_EXECUTOR = new ThreadPoolExecutor(1, 1, 200, TimeUnit.MILLISECONDS, + new ArrayBlockingQueue<>(1)); + + public AutoConfiguration(ServerProperties serverProperties, NettyServerFilter nettyServerFilter) { + this.serverProperties = serverProperties; + this.nettyServerFilter = nettyServerFilter; + } + + + @Bean(destroyMethod = "shutdown") + public NettyOnCloudNettyServerSocket nettyServerSocket(){ + return new NettyOnCloudNettyServerSocket(nettyServerFilter); + } + /** + * @param args + * @throws Exception + */ + @Override + public void run(String... args) throws Exception { + + NettyOnCloudNettyServerSocket serverSocket = new NettyOnCloudNettyServerSocket(nettyServerFilter); + log.info("当前服务启动端口:{}", serverProperties.getPort()); + int nettyServerPort = serverProperties.getPort() + 1000; + Thread thread = new Thread(() -> { + try { + serverSocket.startServer(nettyServerPort); + } catch (Exception e) { + throw new RuntimeException(e); + } + + }); + log.info("当前服务启动Netty端口:{}", nettyServerPort); + NETTY_SERVER_EXECUTOR.execute(thread); + + } +} diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/filter/NettyServerFilter.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/filter/NettyServerFilter.java new file mode 100644 index 0000000..ad1ab1d --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/filter/NettyServerFilter.java @@ -0,0 +1,51 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.netty.filter; + +import wu.framework.middleground.cloud.heartbeat.common.adapter.ChannelTypeAdapter; +import wu.framework.middleground.cloud.heartbeat.common.advanced.ChannelTypeAdvanced; +import wu.framework.middleground.cloud.heartbeat.common.decoder.NettyProxyMsgDecoder; +import wu.framework.middleground.cloud.heartbeat.common.encoder.NettyProxyMsgEncoder; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelPipeline; +import io.netty.channel.socket.SocketChannel; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; +import io.netty.handler.timeout.IdleStateHandler; +import org.springframework.stereotype.Component; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.netty.handler.NettyServerHandler; + +import java.util.List; +import java.util.concurrent.TimeUnit; + +/** + * description + * + * @author 吴佳伟 + * @date 2023/09/13 10:26 + */ +@Component +public class NettyServerFilter extends ChannelInitializer { + private final List channelTypeAdvancedList; + + public NettyServerFilter( List channelTypeAdvancedList) { + this.channelTypeAdvancedList = channelTypeAdvancedList; + } + + @Override + protected void initChannel(SocketChannel ch) throws Exception { + ChannelPipeline pipeline = ch.pipeline(); + // 以("\n")为结尾分割的 解码器 + // 解码、编码 + pipeline.addLast(new NettyProxyMsgDecoder(Integer.MAX_VALUE, 0, 4, -4, 0)); + pipeline.addLast(new NettyProxyMsgEncoder()); +// ph.addLast("framer", new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter())); + // 解码和编码,应和客户端一致 + //入参说明: 读超时时间、写超时时间、所有类型的超时时间、时间格式 + + pipeline.addLast(new IdleStateHandler(5, 0, 0, TimeUnit.SECONDS)); + pipeline.addLast("decoder", new StringDecoder()); + pipeline.addLast("encoder", new StringEncoder()); + // 类型处理器适配器 + ChannelTypeAdapter channelTypeAdapter = new ChannelTypeAdapter(channelTypeAdvancedList); + pipeline.addLast("doHandler", new NettyServerHandler(channelTypeAdapter));// 服务端业务逻辑 + } +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/filter/VisitorFilter.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/filter/VisitorFilter.java new file mode 100644 index 0000000..7d58c0d --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/filter/VisitorFilter.java @@ -0,0 +1,31 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.netty.filter; + +import wu.framework.middleground.cloud.heartbeat.common.InternalNetworkPenetrationRealClient; +import io.netty.channel.*; +import io.netty.channel.socket.SocketChannel; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.netty.handler.VisitorHandler; + +public class VisitorFilter extends ChannelInitializer { + private final InternalNetworkPenetrationRealClient internalNetworkPenetrationRealClient; + + public VisitorFilter(InternalNetworkPenetrationRealClient internalNetworkPenetrationRealClient) { + this.internalNetworkPenetrationRealClient = internalNetworkPenetrationRealClient; + } + + /** + * This method will be called once the {@link Channel} was registered. After the method returns this instance + * will be removed from the {@link ChannelPipeline} of the {@link Channel}. + * + * @param ch the {@link Channel} which was registered. + * @throws Exception is thrown if an error occurs. In that case it will be handled by + * {@link #exceptionCaught(ChannelHandlerContext, Throwable)} which will by default close + * the {@link Channel}. + */ + @Override + protected void initChannel(SocketChannel ch) throws Exception { + ChannelPipeline pipeline = ch.pipeline(); + pipeline.addLast(new ChannelDuplexHandler()); + pipeline.addLast(new VisitorHandler(internalNetworkPenetrationRealClient)); + + } +} diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/handler/HeartBeatServerHandler.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/handler/HeartBeatServerHandler.java new file mode 100644 index 0000000..af27161 --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/handler/HeartBeatServerHandler.java @@ -0,0 +1,45 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.netty.handler; + +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import io.netty.handler.timeout.IdleState; +import io.netty.handler.timeout.IdleStateEvent; +import io.netty.util.AttributeKey; + +@Deprecated +public class HeartBeatServerHandler extends ChannelInboundHandlerAdapter { + + AttributeKey channelAttributeKeyId = AttributeKey.valueOf("channelAttributeTenantId"); + private int lossConnectCount = 0; + + @Override + public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { + String channelAttributeId = ctx.channel().attr(channelAttributeKeyId).get(); + System.out.println("channelAttributeTenantId:" + channelAttributeId); + System.out.println("已经5秒未收到客户端的消息了!"); + + if (evt instanceof IdleStateEvent) { + IdleStateEvent event = (IdleStateEvent) evt; + if (event.state() == IdleState.READER_IDLE) { + lossConnectCount++; + if (lossConnectCount > 2) { + System.out.println("关闭这个不活跃通道!"); +// ctx.channel().close(); + } + } + } else { + super.userEventTriggered(ctx, evt); + } + } + + @Override + public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { + lossConnectCount = 0; + System.out.println("client says: " + msg.toString()); + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + ctx.close(); + } +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/handler/LazyServerIdleStateHandler.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/handler/LazyServerIdleStateHandler.java new file mode 100644 index 0000000..904bded --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/handler/LazyServerIdleStateHandler.java @@ -0,0 +1,553 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.netty.handler; + +import io.netty.bootstrap.ServerBootstrap; +import io.netty.channel.*; +import io.netty.handler.timeout.*; +import io.netty.util.concurrent.Future; +import io.netty.util.internal.ObjectUtil; + +import java.util.concurrent.TimeUnit; + +/** + * Raises a {@link ReadTimeoutException} when no data was read within a certain + * period of time. + * + *
+ * // The connection is closed when there is no inbound traffic
+ * // for 30 seconds.
+ *
+ * public class MyChannelInitializer extends {@link ChannelInitializer}<{@link Channel}> {
+ *     public void initChannel({@link Channel} channel) {
+ *         channel.pipeline().addLast("readTimeoutHandler", new {@link LazyServerIdleStateHandler}(30));
+ *         channel.pipeline().addLast("myHandler", new MyHandler());
+ *     }
+ * }
+ *
+ * // Handler should handle the {@link ReadTimeoutException}.
+ * public class MyHandler extends {@link ChannelDuplexHandler} {
+ *     {@code @Override}
+ *     public void exceptionCaught({@link ChannelHandlerContext} ctx, {@link Throwable} cause)
+ *             throws {@link Exception} {
+ *         if (cause instanceof {@link ReadTimeoutException}) {
+ *             // do something
+ *         } else {
+ *             super.exceptionCaught(ctx, cause);
+ *         }
+ *     }
+ * }
+ *
+ * {@link ServerBootstrap} bootstrap = ...;
+ * ...
+ * bootstrap.childHandler(new MyChannelInitializer());
+ * ...
+ * 
+ * @see WriteTimeoutHandler + * @see IdleStateHandler + */ +public class LazyServerIdleStateHandler extends ChannelDuplexHandler { + private static final long MIN_TIMEOUT_NANOS = TimeUnit.MILLISECONDS.toNanos(1); + + // Not create a new ChannelFutureListener per write operation to reduce GC pressure. + private final ChannelFutureListener writeListener = new ChannelFutureListener() { + @Override + public void operationComplete(ChannelFuture future) throws Exception { + lastWriteTime = ticksInNanos(); + firstWriterIdleEvent = firstAllIdleEvent = true; + } + }; + + private final boolean observeOutput; + private final long readerIdleTimeNanos; + private final long writerIdleTimeNanos; + private final long allIdleTimeNanos; + + private Future readerIdleTimeout; + private long lastReadTime; + private boolean firstReaderIdleEvent = true; + + private Future writerIdleTimeout; + private long lastWriteTime; + private boolean firstWriterIdleEvent = true; + + private Future allIdleTimeout; + private boolean firstAllIdleEvent = true; + + private byte state; // 0 - none, 1 - initialized, 2 - destroyed + private boolean reading; + + private long lastChangeCheckTimeStamp; + private int lastMessageHashCode; + private long lastPendingWriteBytes; + private long lastFlushProgress; + + /** + * Creates a new instance firing {@link IdleStateEvent}s. + * + * @param readerIdleTimeSeconds + * an {@link IdleStateEvent} whose state is {@link IdleState#READER_IDLE} + * will be triggered when no read was performed for the specified + * period of time. Specify {@code 0} to disable. + * @param writerIdleTimeSeconds + * an {@link IdleStateEvent} whose state is {@link IdleState#WRITER_IDLE} + * will be triggered when no write was performed for the specified + * period of time. Specify {@code 0} to disable. + * @param allIdleTimeSeconds + * an {@link IdleStateEvent} whose state is {@link IdleState#ALL_IDLE} + * will be triggered when neither read nor write was performed for + * the specified period of time. Specify {@code 0} to disable. + */ + public LazyServerIdleStateHandler( + int readerIdleTimeSeconds, + int writerIdleTimeSeconds, + int allIdleTimeSeconds) { + + this(readerIdleTimeSeconds, writerIdleTimeSeconds, allIdleTimeSeconds, + TimeUnit.SECONDS); + } + + /** + * @see #LazyServerIdleStateHandler(boolean, long, long, long, TimeUnit) + */ + public LazyServerIdleStateHandler( + long readerIdleTime, long writerIdleTime, long allIdleTime, + TimeUnit unit) { + this(false, readerIdleTime, writerIdleTime, allIdleTime, unit); + } + + /** + * Creates a new instance firing {@link IdleStateEvent}s. + * + * @param observeOutput + * whether or not the consumption of {@code bytes} should be taken into + * consideration when assessing write idleness. The default is {@code false}. + * @param readerIdleTime + * an {@link IdleStateEvent} whose state is {@link IdleState#READER_IDLE} + * will be triggered when no read was performed for the specified + * period of time. Specify {@code 0} to disable. + * @param writerIdleTime + * an {@link IdleStateEvent} whose state is {@link IdleState#WRITER_IDLE} + * will be triggered when no write was performed for the specified + * period of time. Specify {@code 0} to disable. + * @param allIdleTime + * an {@link IdleStateEvent} whose state is {@link IdleState#ALL_IDLE} + * will be triggered when neither read nor write was performed for + * the specified period of time. Specify {@code 0} to disable. + * @param unit + * the {@link TimeUnit} of {@code readerIdleTime}, + * {@code writeIdleTime}, and {@code allIdleTime} + */ + public LazyServerIdleStateHandler(boolean observeOutput, + long readerIdleTime, long writerIdleTime, long allIdleTime, + TimeUnit unit) { + ObjectUtil.checkNotNull(unit, "unit"); + + this.observeOutput = observeOutput; + + if (readerIdleTime <= 0) { + readerIdleTimeNanos = 0; + } else { + readerIdleTimeNanos = Math.max(unit.toNanos(readerIdleTime), MIN_TIMEOUT_NANOS); + } + if (writerIdleTime <= 0) { + writerIdleTimeNanos = 0; + } else { + writerIdleTimeNanos = Math.max(unit.toNanos(writerIdleTime), MIN_TIMEOUT_NANOS); + } + if (allIdleTime <= 0) { + allIdleTimeNanos = 0; + } else { + allIdleTimeNanos = Math.max(unit.toNanos(allIdleTime), MIN_TIMEOUT_NANOS); + } + } + + /** + * Return the readerIdleTime that was given when instance this class in milliseconds. + * + */ + public long getReaderIdleTimeInMillis() { + return TimeUnit.NANOSECONDS.toMillis(readerIdleTimeNanos); + } + + /** + * Return the writerIdleTime that was given when instance this class in milliseconds. + * + */ + public long getWriterIdleTimeInMillis() { + return TimeUnit.NANOSECONDS.toMillis(writerIdleTimeNanos); + } + + /** + * Return the allIdleTime that was given when instance this class in milliseconds. + * + */ + public long getAllIdleTimeInMillis() { + return TimeUnit.NANOSECONDS.toMillis(allIdleTimeNanos); + } + + @Override + public void handlerAdded(ChannelHandlerContext ctx) throws Exception { + if (ctx.channel().isActive() && ctx.channel().isRegistered()) { + // channelActive() event has been fired already, which means this.channelActive() will + // not be invoked. We have to initialize here instead. + initialize(ctx); + } else { + // channelActive() event has not been fired yet. this.channelActive() will be invoked + // and initialization will occur there. + } + } + + @Override + public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { + destroy(); + } + + @Override + public void channelRegistered(ChannelHandlerContext ctx) throws Exception { + // Initialize early if channel is active already. + if (ctx.channel().isActive()) { + initialize(ctx); + } + super.channelRegistered(ctx); + } + + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + // This method will be invoked only if this doHandler was added + // before channelActive() event is fired. If a user adds this doHandler + // after the channelActive() event, initialize() will be called by beforeAdd(). + initialize(ctx); + super.channelActive(ctx); + } + + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + destroy(); + super.channelInactive(ctx); + } + + @Override + public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { + if (readerIdleTimeNanos > 0 || allIdleTimeNanos > 0) { + reading = true; + firstReaderIdleEvent = firstAllIdleEvent = true; + } + ctx.fireChannelRead(msg); + System.out.println("channelRead"); + } + + @Override + public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { + if ((readerIdleTimeNanos > 0 || allIdleTimeNanos > 0) && reading) { + lastReadTime = ticksInNanos(); + reading = false; + } + ctx.fireChannelReadComplete(); + System.out.println("channelReadComplete"); + } + + @Override + public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { + // Allow writing with void promise if doHandler is only configured for read timeout events. + if (writerIdleTimeNanos > 0 || allIdleTimeNanos > 0) { + ctx.write(msg, promise.unvoid()).addListener(writeListener); + } else { + ctx.write(msg, promise); + } + System.out.println("write"); + } + + private void initialize(ChannelHandlerContext ctx) { + // Avoid the case where destroy() is called before scheduling timeouts. + // See: https://github.com/netty/netty/issues/143 + switch (state) { + case 1: + case 2: + return; + default: + break; + } + + state = 1; + initOutputChanged(ctx); + + lastReadTime = lastWriteTime = ticksInNanos(); + if (readerIdleTimeNanos > 0) { + readerIdleTimeout = schedule(ctx, new ReaderIdleTimeoutTask(ctx), + readerIdleTimeNanos, TimeUnit.NANOSECONDS); + } + if (writerIdleTimeNanos > 0) { + writerIdleTimeout = schedule(ctx, new WriterIdleTimeoutTask(ctx), + writerIdleTimeNanos, TimeUnit.NANOSECONDS); + } + if (allIdleTimeNanos > 0) { + allIdleTimeout = schedule(ctx, new AllIdleTimeoutTask(ctx), + allIdleTimeNanos, TimeUnit.NANOSECONDS); + } + } + + /** + * This method is visible for testing! + */ + long ticksInNanos() { + return System.nanoTime(); + } + + /** + * This method is visible for testing! + */ + Future schedule(ChannelHandlerContext ctx, Runnable task, long delay, TimeUnit unit) { + return ctx.executor().schedule(task, delay, unit); + } + + private void destroy() { + state = 2; + + if (readerIdleTimeout != null) { + readerIdleTimeout.cancel(false); + readerIdleTimeout = null; + } + if (writerIdleTimeout != null) { + writerIdleTimeout.cancel(false); + writerIdleTimeout = null; + } + if (allIdleTimeout != null) { + allIdleTimeout.cancel(false); + allIdleTimeout = null; + } + } + + /** + * Is called when an {@link IdleStateEvent} should be fired. This implementation calls + * {@link ChannelHandlerContext#fireUserEventTriggered(Object)}. + */ + protected void channelIdle(ChannelHandlerContext ctx, IdleStateEvent evt) throws Exception { + ctx.fireUserEventTriggered(evt); + } + + /** + * Returns a {@link IdleStateEvent}. + */ + protected IdleStateEvent newIdleStateEvent(IdleState state, boolean first) { + switch (state) { + case ALL_IDLE: + return first ? IdleStateEvent.FIRST_ALL_IDLE_STATE_EVENT : IdleStateEvent.ALL_IDLE_STATE_EVENT; + case READER_IDLE: + return first ? IdleStateEvent.FIRST_READER_IDLE_STATE_EVENT : IdleStateEvent.READER_IDLE_STATE_EVENT; + case WRITER_IDLE: + return first ? IdleStateEvent.FIRST_WRITER_IDLE_STATE_EVENT : IdleStateEvent.WRITER_IDLE_STATE_EVENT; + default: + throw new IllegalArgumentException("Unhandled: state=" + state + ", first=" + first); + } + } + + /** + * @see #hasOutputChanged(ChannelHandlerContext, boolean) + */ + private void initOutputChanged(ChannelHandlerContext ctx) { + if (observeOutput) { + Channel channel = ctx.channel(); + Channel.Unsafe unsafe = channel.unsafe(); + ChannelOutboundBuffer buf = unsafe.outboundBuffer(); + + if (buf != null) { + lastMessageHashCode = System.identityHashCode(buf.current()); + lastPendingWriteBytes = buf.totalPendingWriteBytes(); + lastFlushProgress = buf.currentProgress(); + } + } + } + + /** + * Returns {@code true} if and only if the {@link IdleStateHandler} was constructed + * with {@link #observeOutput} enabled and there has been an observed change in the + * {@link ChannelOutboundBuffer} between two consecutive calls of this method. + * + * https://github.com/netty/netty/issues/6150 + */ + private boolean hasOutputChanged(ChannelHandlerContext ctx, boolean first) { + if (observeOutput) { + + // We can take this shortcut if the ChannelPromises that got passed into write() + // appear to complete. It indicates "change" on message level and we simply assume + // that there's change happening on byte level. If the user doesn't observe channel + // writability events then they'll eventually OOME and there's clearly a different + // problem and idleness is least of their concerns. + if (lastChangeCheckTimeStamp != lastWriteTime) { + lastChangeCheckTimeStamp = lastWriteTime; + + // But this applies only if it's the non-first call. + if (!first) { + return true; + } + } + + Channel channel = ctx.channel(); + Channel.Unsafe unsafe = channel.unsafe(); + ChannelOutboundBuffer buf = unsafe.outboundBuffer(); + + if (buf != null) { + int messageHashCode = System.identityHashCode(buf.current()); + long pendingWriteBytes = buf.totalPendingWriteBytes(); + + if (messageHashCode != lastMessageHashCode || pendingWriteBytes != lastPendingWriteBytes) { + lastMessageHashCode = messageHashCode; + lastPendingWriteBytes = pendingWriteBytes; + + if (!first) { + return true; + } + } + + long flushProgress = buf.currentProgress(); + if (flushProgress != lastFlushProgress) { + lastFlushProgress = flushProgress; + return !first; + } + } + } + + return false; + } + + private abstract static class AbstractIdleTask implements Runnable { + + private final ChannelHandlerContext ctx; + + AbstractIdleTask(ChannelHandlerContext ctx) { + this.ctx = ctx; + } + + @Override + public void run() { + if (!ctx.channel().isOpen()) { + return; + } + + run(ctx); + } + + protected abstract void run(ChannelHandlerContext ctx); + } + + private final class ReaderIdleTimeoutTask extends AbstractIdleTask { + + ReaderIdleTimeoutTask(ChannelHandlerContext ctx) { + super(ctx); + } + + @Override + protected void run(ChannelHandlerContext ctx) { + long nextDelay = readerIdleTimeNanos; + if (!reading) { + nextDelay -= ticksInNanos() - lastReadTime; + } + + if (nextDelay <= 0) { + // Reader is idle - set a new timeout and notify the callback. + readerIdleTimeout = schedule(ctx, this, readerIdleTimeNanos, TimeUnit.NANOSECONDS); + + boolean first = firstReaderIdleEvent; + firstReaderIdleEvent = false; + + try { + IdleStateEvent event = newIdleStateEvent(IdleState.READER_IDLE, first); + channelIdle(ctx, event); + } catch (Throwable t) { + ctx.fireExceptionCaught(t); + } + } else { + // Read occurred before the timeout - set a new timeout with shorter delay. + readerIdleTimeout = schedule(ctx, this, nextDelay, TimeUnit.NANOSECONDS); + } + } + } + + private final class WriterIdleTimeoutTask extends AbstractIdleTask { + + WriterIdleTimeoutTask(ChannelHandlerContext ctx) { + super(ctx); + } + + @Override + protected void run(ChannelHandlerContext ctx) { + + long lastWriteTime = LazyServerIdleStateHandler.this.lastWriteTime; + long nextDelay = writerIdleTimeNanos - (ticksInNanos() - lastWriteTime); + if (nextDelay <= 0) { + // Writer is idle - set a new timeout and notify the callback. + writerIdleTimeout = schedule(ctx, this, writerIdleTimeNanos, TimeUnit.NANOSECONDS); + + boolean first = firstWriterIdleEvent; + firstWriterIdleEvent = false; + + try { + if (hasOutputChanged(ctx, first)) { + return; + } + + IdleStateEvent event = newIdleStateEvent(IdleState.WRITER_IDLE, first); + channelIdle(ctx, event); + } catch (Throwable t) { + ctx.fireExceptionCaught(t); + } + } else { + // Write occurred before the timeout - set a new timeout with shorter delay. + writerIdleTimeout = schedule(ctx, this, nextDelay, TimeUnit.NANOSECONDS); + } + } + } + + private final class AllIdleTimeoutTask extends AbstractIdleTask { + + AllIdleTimeoutTask(ChannelHandlerContext ctx) { + super(ctx); + } + + @Override + protected void run(ChannelHandlerContext ctx) { + + long nextDelay = allIdleTimeNanos; + if (!reading) { + nextDelay -= ticksInNanos() - Math.max(lastReadTime, lastWriteTime); + } + if (nextDelay <= 0) { + // Both reader and writer are idle - set a new timeout and + // notify the callback. + allIdleTimeout = schedule(ctx, this, allIdleTimeNanos, TimeUnit.NANOSECONDS); + + boolean first = firstAllIdleEvent; + firstAllIdleEvent = false; + + try { + if (hasOutputChanged(ctx, first)) { + return; + } + + IdleStateEvent event = newIdleStateEvent(IdleState.ALL_IDLE, first); + channelIdle(ctx, event); + } catch (Throwable t) { + ctx.fireExceptionCaught(t); + } + } else { + // Either read or write occurred before the timeout - set a new + // timeout with shorter delay. + allIdleTimeout = schedule(ctx, this, nextDelay, TimeUnit.NANOSECONDS); + } + } + } +} diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/handler/NettyServerHandler.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/handler/NettyServerHandler.java new file mode 100644 index 0000000..e5ceed9 --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/handler/NettyServerHandler.java @@ -0,0 +1,114 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.netty.handler; + +import wu.framework.middleground.cloud.heartbeat.common.MessageType; +import wu.framework.middleground.cloud.heartbeat.common.NettyCommunicationIdContext; +import wu.framework.middleground.cloud.heartbeat.common.NettyProxyMsg; +import wu.framework.middleground.cloud.heartbeat.common.NettyRealIdContext; +import wu.framework.middleground.cloud.heartbeat.common.adapter.ChannelTypeAdapter; +import wu.framework.middleground.cloud.heartbeat.common.utils.ChannelAttributeKeyUtils; +import io.netty.channel.*; +import io.netty.handler.timeout.IdleState; +import io.netty.handler.timeout.IdleStateEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.util.ObjectUtils; + +/** + * description 服务端数据处理器 + * + * @author 吴佳伟 + * @date 2023/09/13 10:27 + */ +@Slf4j +public class NettyServerHandler extends SimpleChannelInboundHandler { + + private final ChannelTypeAdapter channelTypeAdapter; + + public NettyServerHandler(ChannelTypeAdapter channelTypeAdapter) { + this.channelTypeAdapter = channelTypeAdapter; + } + + /** + * Is called for each message of type {@link I}. + * + * @param ctx the {@link ChannelHandlerContext} which this {@link SimpleChannelInboundHandler} + * belongs to + * @param nettyMsg the message to handle + * @throws Exception is thrown if an error occurred + */ + @Override + protected void channelRead0(ChannelHandlerContext ctx, NettyProxyMsg nettyMsg) throws Exception { + // 客户端读取到代理过来的数据了 + Channel channel = ctx.channel(); + byte type = nettyMsg.getType(); +// byte[] data = nettyMsg.getData(); +// log.info("客户端发送数据类型:{},发送数据:{}", type, new String(data)); + channelTypeAdapter.handler(channel, nettyMsg); + + } + + /** + * 空闲次数 + */ + private int idle_count = 1; + + /** + * 超时处理 * 如果5秒没有接受客户端的心跳,就触发; * 如果超过两次,则直接关闭; + */ + @Override + public void userEventTriggered(ChannelHandlerContext ctx, Object obj) throws Exception { + Channel channel = ctx.channel(); + if (obj instanceof IdleStateEvent) { + IdleStateEvent event = (IdleStateEvent) obj; + if (IdleState.READER_IDLE.equals(event.state())) { //如果读通道处于空闲状态,说明没有接收到心跳命令 + String clientId = ChannelAttributeKeyUtils.getClientId(channel); + String visitorId = ChannelAttributeKeyUtils.getVisitorId(channel); + log.warn("已经5秒没有接收到客户端:{}的信息了",clientId); + if (idle_count > 2) { + + if(ObjectUtils.isEmpty(visitorId)){ + log.warn("关闭这个不活跃的channel client:{}", clientId); + // 给所有客户端发送 这个客户端离线了 + NettyProxyMsg nettyMsg = new NettyProxyMsg(); + nettyMsg.setClientId(clientId); + nettyMsg.setVisitorId(visitorId); + nettyMsg.setType(MessageType.REPORT_CLIENT_DISCONNECTION); + channelTypeAdapter.handler(channel, nettyMsg); + channel.close(); + }else { + log.info("关闭访客:【{}】的连接",visitorId); + NettyCommunicationIdContext.clear(visitorId); + NettyRealIdContext.clear(visitorId); + } + + } + idle_count++; + } + } else { + super.userEventTriggered(ctx, obj); + } + } + + + /** + * Calls {@link ChannelHandlerContext#fireChannelInactive()} to forward + * to the next {@link ChannelInboundHandler} in the {@link ChannelPipeline}. + *

+ * Sub-classes may override this method to change behavior. + * + * @param ctx + */ + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + Channel channel = ctx.channel(); + boolean open = channel.isOpen(); + // 下发当前客户端通道断开连接 + + String clientId = ChannelAttributeKeyUtils.getClientId(channel); + log.info("断开客户端的连接:{}", clientId); + NettyProxyMsg nettyMsg = new NettyProxyMsg(); + nettyMsg.setType(MessageType.REPORT_CLIENT_DISCONNECTION); + nettyMsg.setClientId(clientId); + channelTypeAdapter.handler(channel, nettyMsg); + super.channelInactive(ctx); + } +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/handler/VisitorHandler.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/handler/VisitorHandler.java new file mode 100644 index 0000000..0df9923 --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/handler/VisitorHandler.java @@ -0,0 +1,161 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.netty.handler; + + + +import wu.framework.middleground.cloud.heartbeat.common.*; +import wu.framework.middleground.cloud.heartbeat.common.utils.ChannelAttributeKeyUtils; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelOption; +import io.netty.channel.SimpleChannelInboundHandler; +import io.netty.util.internal.StringUtil; +import lombok.extern.slf4j.Slf4j; + +import java.util.UUID; + +@Slf4j +public class VisitorHandler extends SimpleChannelInboundHandler { + private final InternalNetworkPenetrationRealClient internalNetworkPenetrationRealClient; + + public VisitorHandler(InternalNetworkPenetrationRealClient internalNetworkPenetrationRealClient) { + this.internalNetworkPenetrationRealClient = internalNetworkPenetrationRealClient; + } + + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + // 访客连接上代理服务器了 + Channel visitorChannel = ctx.channel(); + // 先不读取访客数据 + visitorChannel.config().setOption(ChannelOption.AUTO_READ, false); + + + // 生成访客ID + String visitorId = UUID.randomUUID().toString(); + String clientId = internalNetworkPenetrationRealClient.getClientId(); + Integer visitorPort = internalNetworkPenetrationRealClient.getVisitorPort(); + String clientTargetIp = internalNetworkPenetrationRealClient.getClientTargetIp(); + Integer clientTargetPort = internalNetworkPenetrationRealClient.getClientTargetPort(); + // 绑定访客真实通道 + NettyRealIdContext.pushVisitor(visitorChannel, visitorId); + // 当前通道绑定访客ID + ChannelAttributeKeyUtils.buildVisitorId(visitorChannel, visitorId); + ChannelAttributeKeyUtils.buildClientId(visitorChannel, clientId); + NettyProxyMsg myMsg = new NettyProxyMsg(); + myMsg.setType(MessageType.DISTRIBUTE_SINGLE_CLIENT_REAL_CONNECT); + myMsg.setClientId(clientId); + myMsg.setVisitorPort(visitorPort); + myMsg.setClientTargetIp(clientTargetIp); + myMsg.setClientTargetPort(clientTargetPort); + + myMsg.setVisitorId(visitorId); + + ChannelContext.ClientChannel clientChannel = ChannelContext.get(clientId); + if (clientChannel != null) { + Channel channel = clientChannel.getChannel(); + channel.writeAndFlush(myMsg); + } + + + // 等待访客ID传输到客户端后绑定客户端真实服务后开启 + + + log.info("服务端访客端口连接成功了"); + super.channelActive(ctx); + } + + @Override + public void channelRead0(ChannelHandlerContext ctx, ByteBuf buf) { + + String clientId = internalNetworkPenetrationRealClient.getClientId(); + String clientTargetIp = internalNetworkPenetrationRealClient.getClientTargetIp(); + Integer clientTargetPort = internalNetworkPenetrationRealClient.getClientTargetPort(); + Integer visitorPort = internalNetworkPenetrationRealClient.getVisitorPort(); + String visitorId = ChannelAttributeKeyUtils.getVisitorId(ctx.channel()); + if (StringUtil.isNullOrEmpty(clientId)) { + return; + } + byte[] bytes = new byte[buf.readableBytes()]; + buf.readBytes(bytes); + // 获取客户端通道,而后进行数据下发 + log.debug("服务端访客端口成功接收数据:{}", new String(bytes)); + // 使用访客的通信通道 + Channel visitorCommunicationChannel = NettyCommunicationIdContext.getVisitor(visitorId); + + NettyProxyMsg nettyProxyMsg = new NettyProxyMsg(); + nettyProxyMsg.setType(MessageType.DISTRIBUTE_CLIENT_TRANSFER); + nettyProxyMsg.setClientId(clientId); + nettyProxyMsg.setClientTargetIp(clientTargetIp); + nettyProxyMsg.setClientTargetPort(clientTargetPort); + nettyProxyMsg.setVisitorPort(visitorPort); + nettyProxyMsg.setVisitorId(visitorId); + nettyProxyMsg.setData(bytes); + visitorCommunicationChannel.writeAndFlush(nettyProxyMsg); + log.debug("服务端访客端口成功发送数据了"); + } + + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + String visitorId = ChannelAttributeKeyUtils.getVisitorId(ctx.channel()); + String clientId = ChannelAttributeKeyUtils.getClientId(ctx.channel()); + if (StringUtil.isNullOrEmpty(visitorId)) { + super.channelInactive(ctx); + return; + } + // 通信通道自动读写打开 ,然后关闭通信通道 + Channel visitorChannel = NettyCommunicationIdContext.getVisitor(visitorId); + if (visitorChannel != null && visitorChannel.isActive()) { + + visitorChannel.config().setOption(ChannelOption.AUTO_READ, true); + + // 通知服务端 关闭访问通道、真实通道 + NettyProxyMsg myMsg = new NettyProxyMsg(); + myMsg.setType(MessageType.DISTRIBUTE_SINGLE_CLIENT_REAL_CLOSE_VISITOR); + myMsg.setVisitorId(visitorId); + visitorChannel.writeAndFlush(myMsg); + } + // 关闭 访客通信通道、访客真实通道 + NettyRealIdContext.clear(visitorId); + NettyCommunicationIdContext.clear(visitorId); + log.warn("服务端访客端口断开连接"); + super.channelInactive(ctx); + } + + @Override + public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception { + +// Channel visitorChannel = ctx.channel(); +// String vid = visitorChannel.attr(Constant.VID).get(); +// if (StringUtil.isNullOrEmpty(vid)) { +// super.channelWritabilityChanged(ctx); +// return; +// } +// Channel clientChannel = Constant.vcc.get(vid); +// if (clientChannel != null) { +// clientChannel.config().setOption(ChannelOption.AUTO_READ, visitorChannel.isWritable()); +// } + log.info("channelWritabilityChanged"); + super.channelWritabilityChanged(ctx); + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + log.error("exceptionCaught"); + + Channel channel = ctx.channel(); + String clientId = ChannelAttributeKeyUtils.getClientId(channel); + String visitorId = ChannelAttributeKeyUtils.getVisitorId(channel); + // 使用通信通道 下发关闭访客 + Channel visitorChannel = NettyCommunicationIdContext.getVisitor(visitorId); + if (visitorChannel != null) { + // 下发关闭访客 + NettyProxyMsg closeRealClient = new NettyProxyMsg(); + closeRealClient.setType(MessageType.DISTRIBUTE_SINGLE_CLIENT_REAL_CONNECT_AUTO_READ); + closeRealClient.setClientId(clientId); + closeRealClient.setVisitorId(visitorId); + visitorChannel.writeAndFlush(closeRealClient); + } + + ctx.close(); + } +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/socket/NettyOnCloudNettyServerSocket.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/socket/NettyOnCloudNettyServerSocket.java new file mode 100644 index 0000000..c81804e --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/socket/NettyOnCloudNettyServerSocket.java @@ -0,0 +1,62 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.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 wu.framework.middleground.on.cloud.heartbeat.server.domain.netty.filter.NettyServerFilter; + +public class NettyOnCloudNettyServerSocket { + private final EventLoopGroup bossGroup = new NioEventLoopGroup(); + private final EventLoopGroup workerGroup = new NioEventLoopGroup(); + private ChannelFuture channelFuture; + private final NettyServerFilter nettyServerFilter;// 通道业务处理 + + 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(); + } + } +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/socket/NettyVisitorSocket.java b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/socket/NettyVisitorSocket.java new file mode 100644 index 0000000..fe24beb --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/java/wu/framework/middleground/on/cloud/heartbeat/server/domain/netty/socket/NettyVisitorSocket.java @@ -0,0 +1,55 @@ +package wu.framework.middleground.on.cloud.heartbeat.server.domain.netty.socket; + +import wu.framework.middleground.cloud.heartbeat.common.NettyVisitorContext; +import io.netty.bootstrap.ServerBootstrap; +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.NioServerSocketChannel; +import lombok.extern.slf4j.Slf4j; +import wu.framework.middleground.on.cloud.heartbeat.server.domain.netty.filter.VisitorFilter; + +/** + * 访客链接socket + */ +@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) { + this.visitorFilter = visitorFilter; + } + + /** + * 启动服务代理 + * + * @param visitorPort 访客代理端口 + * @throws Exception + */ + public void startServer(int visitorPort) throws Exception { + + Channel visitor = NettyVisitorContext.getVisitor(visitorPort); + if (visitor == null) { + ServerBootstrap b = new ServerBootstrap(); + b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class) + .childHandler(visitorFilter); + ChannelFuture sync = b.bind(visitorPort).sync(); + sync.addListener((ChannelFutureListener) future -> { + if(future.isSuccess()){ + Channel channel = future.channel(); + log.info("访客端口:{} 开启", visitorPort); + NettyVisitorContext.pushVisitor(visitorPort, channel); + } + }); + + } else { + log.warn("访客端口:{} 重复启动", visitorPort); + } + + } + +} \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/resources/application-dev.yml b/lazy-cloud-heartbeat-server/src/main/resources/application-dev.yml new file mode 100644 index 0000000..e3b91b3 --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/resources/application-dev.yml @@ -0,0 +1,14 @@ +spring: + data: + redis: + host: 192.168.17.221 + port: 30553 + password: laihui + database: 2 + datasource: + url: jdbc:mysql://127.0.0.1:3306/middleground_cloud_netty_server?allowMultiQueries=true&useUnicode=true&autoReconnect=true&useAffectedRows=true&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&databaseTerm=SCHEMA + username: root + password: wujiawei + driver-class-name: com.mysql.cj.jdbc.Driver + ##druid + type: com.alibaba.druid.pool.DruidDataSource diff --git a/lazy-cloud-heartbeat-server/src/main/resources/application-prod.yml b/lazy-cloud-heartbeat-server/src/main/resources/application-prod.yml new file mode 100644 index 0000000..e0873e5 --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/resources/application-prod.yml @@ -0,0 +1,10 @@ +spring: + datasource: + url: jdbc:mysql://${MAIN_DB_HOST}/middleground_cloud_netty_server?allowMultiQueries=true&useUnicode=true&autoReconnect=true&useAffectedRows=true&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&databaseTerm=SCHEMA + username: middleground_cloud_netty_server + password: laihui + driver-class-name: com.mysql.cj.jdbc.Driver + ##druid + type: com.alibaba.druid.pool.DruidDataSource + main: + allow-bean-definition-overriding: true \ No newline at end of file diff --git a/lazy-cloud-heartbeat-server/src/main/resources/application.yml b/lazy-cloud-heartbeat-server/src/main/resources/application.yml new file mode 100644 index 0000000..3a655c9 --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/resources/application.yml @@ -0,0 +1,9 @@ + +server: + port: 6001 + +spring: + profiles: + active: dev + lazy: + enable-auto-schema: true diff --git a/lazy-cloud-heartbeat-server/src/main/resources/bootstrap.yml b/lazy-cloud-heartbeat-server/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..103b7d0 --- /dev/null +++ b/lazy-cloud-heartbeat-server/src/main/resources/bootstrap.yml @@ -0,0 +1,15 @@ + + + +spring: + application: + name: middleground-on-cloud-heartbeat-server + cloud: + nacos: + server-addr: 192.168.17.221:30569 + discovery: + server-addr: 192.168.17.221:30569 +# metadata: +# version: 2.0 + config: + server-addr: 192.168.17.221:30569 diff --git a/netty-proxy-client/pom.xml b/netty-proxy-client/pom.xml deleted file mode 100644 index db5ff27..0000000 --- a/netty-proxy-client/pom.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - netty-proxy - com.wu - 0.0.1-SNAPSHOT - - 4.0.0 - - netty-proxy-client - - - 8 - 8 - - - - com.wu - netty-proxy-common - 0.0.1-SNAPSHOT - - - top.wu2020 - wu-framework-web - 1.1.9-JDK1.8-SNAPSHOT - - - org.springframework.boot - spring-boot-starter-web - - - io.springfox - springfox-boot-starter - 3.0.0 - - - - \ No newline at end of file diff --git a/netty-proxy-client/src/main/java/com/luck/client/ClientStart.java b/netty-proxy-client/src/main/java/com/luck/client/ClientStart.java deleted file mode 100644 index 39fb082..0000000 --- a/netty-proxy-client/src/main/java/com/luck/client/ClientStart.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.luck.client; - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class ClientStart { - - public static void main(String[] args) throws Exception { - if (null != args && args.length == 3) { - int realPort = Integer.parseInt(args[2]); - int serverPort = Integer.parseInt(args[1]); - String serverIp = args[0]; - Constant.serverIp = serverIp; - Constant.serverPort = serverPort; - Constant.realPort = realPort; - } - log.info(" 服务端地址: " + Constant.serverIp + " 服务端端口:" + Constant.serverPort + "\n 真实端口: " + Constant.realPort); - // 连接代理服务 - ProxySocket.connectProxyServer(); - } -} \ No newline at end of file diff --git a/netty-proxy-client/src/main/java/com/luck/client/Constant.java b/netty-proxy-client/src/main/java/com/luck/client/Constant.java deleted file mode 100644 index 18e09a7..0000000 --- a/netty-proxy-client/src/main/java/com/luck/client/Constant.java +++ /dev/null @@ -1,87 +0,0 @@ -package com.luck.client; - -import io.netty.channel.Channel; -import io.netty.util.AttributeKey; -import io.netty.util.internal.StringUtil; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -public class Constant { - /** - * 绑定访客id - */ - public static final AttributeKey VID = AttributeKey.newInstance("vid"); - /** - * 代理服务channel - */ - public static Channel proxyChannel = null; - /** - * 访客,代理服务channel - */ - public static Map vpc = new ConcurrentHashMap<>(); - - /** - * 访客,真实服务channel - */ - public static Map vrc = new ConcurrentHashMap<>(); - - /** - * 真实服务端口 - */ - public static int realPort = 8080; - - /** - * 服务端口 - */ - public static int serverPort = 16001; - - /** - * 服务IP - */ - public static String serverIp = "127.0.0.1"; - - /** - * 清除连接 - * - * @param vid 访客ID - */ - public static void clearvpcvrc(String vid) { - if (StringUtil.isNullOrEmpty(vid)) { - return; - } - Channel clientChannel = vpc.get(vid); - if (null != clientChannel) { - clientChannel.attr(VID).set(null); - vpc.remove(vid); - } - Channel visitorChannel = vrc.get(vid); - if (null != visitorChannel) { - visitorChannel.attr(VID).set(null); - vrc.remove(vid); - } - } - - /** - * 清除关闭连接 - * - * @param vid 访客ID - */ - public static void clearvpcvrcAndClose(String vid) { - if (StringUtil.isNullOrEmpty(vid)) { - return; - } - Channel clientChannel = vpc.get(vid); - if (null != clientChannel) { - clientChannel.attr(VID).set(null); - vpc.remove(vid); - clientChannel.close(); - } - Channel visitorChannel = vrc.get(vid); - if (null != visitorChannel) { - visitorChannel.attr(VID).set(null); - vrc.remove(vid); - visitorChannel.close(); - } - } -} \ No newline at end of file diff --git a/netty-proxy-client/src/main/java/com/luck/client/ProxyHandler.java b/netty-proxy-client/src/main/java/com/luck/client/ProxyHandler.java deleted file mode 100644 index 35932bc..0000000 --- a/netty-proxy-client/src/main/java/com/luck/client/ProxyHandler.java +++ /dev/null @@ -1,98 +0,0 @@ -package com.luck.client; - -import com.luck.msg.MyMsg; -import io.netty.buffer.ByteBuf; -import io.netty.channel.Channel; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelOption; -import io.netty.channel.SimpleChannelInboundHandler; -import io.netty.handler.timeout.IdleStateEvent; -import io.netty.util.internal.StringUtil; - -public class ProxyHandler extends SimpleChannelInboundHandler { - - @Override - public void channelRead0(ChannelHandlerContext ctx, MyMsg myMsg) { - // 客户端读取到代理过来的数据了 - byte type = myMsg.getType(); - String vid = new String(myMsg.getData()); - switch (type) { - case MyMsg.TYPE_HEARTBEAT: - break; - case MyMsg.TYPE_CONNECT: - RealSocket.connectRealServer(vid); - break; - case MyMsg.TYPE_DISCONNECT: - Constant.clearvpcvrcAndClose(vid); - break; - case MyMsg.TYPE_TRANSFER: - // 把数据转到真实服务 - ByteBuf buf = ctx.alloc().buffer(myMsg.getData().length); - buf.writeBytes(myMsg.getData()); - - String visitorId = ctx.channel().attr(Constant.VID).get(); - Channel rchannel = Constant.vrc.get(visitorId); - if (null != rchannel) { - rchannel.writeAndFlush(buf); - } - break; - default: - // 操作有误 - } - // 客户端发数据到真实服务了 - } - - @Override - public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception { - String vid = ctx.channel().attr(Constant.VID).get(); - if (StringUtil.isNullOrEmpty(vid)) { - super.channelWritabilityChanged(ctx); - return; - } - Channel realChannel = Constant.vrc.get(vid); - if (realChannel != null) { - realChannel.config().setOption(ChannelOption.AUTO_READ, ctx.channel().isWritable()); - } - - super.channelWritabilityChanged(ctx); - } - - @Override - public void channelInactive(ChannelHandlerContext ctx) throws Exception { - String vid = ctx.channel().attr(Constant.VID).get(); - if (StringUtil.isNullOrEmpty(vid)) { - super.channelInactive(ctx); - return; - } - Channel realChannel = Constant.vrc.get(vid); - if (realChannel != null && realChannel.isActive()) { - realChannel.close(); - } - super.channelInactive(ctx); - } - - @Override - public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { - super.exceptionCaught(ctx, cause); - cause.printStackTrace(); - } - - @Override - public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { - if (evt instanceof IdleStateEvent) { - IdleStateEvent event = (IdleStateEvent) evt; - switch (event.state()) { - case READER_IDLE: - ctx.channel().close(); - break; - case WRITER_IDLE: - MyMsg myMsg = new MyMsg(); - myMsg.setType(MyMsg.TYPE_HEARTBEAT); - ctx.channel().writeAndFlush(myMsg); - break; - case ALL_IDLE: - break; - } - } - } -} \ No newline at end of file diff --git a/netty-proxy-client/src/main/java/com/luck/client/ProxySocket.java b/netty-proxy-client/src/main/java/com/luck/client/ProxySocket.java deleted file mode 100644 index 236a2a7..0000000 --- a/netty-proxy-client/src/main/java/com/luck/client/ProxySocket.java +++ /dev/null @@ -1,101 +0,0 @@ -package com.luck.client; - -import com.luck.msg.MyMsg; -import com.luck.msg.MyMsgDecoder; -import com.luck.msg.MyMsgEncoder; -import io.netty.bootstrap.Bootstrap; -import io.netty.channel.*; -import io.netty.channel.nio.NioEventLoopGroup; -import io.netty.channel.socket.SocketChannel; -import io.netty.channel.socket.nio.NioSocketChannel; -import io.netty.handler.timeout.IdleStateHandler; -import io.netty.util.internal.StringUtil; - -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - -public class ProxySocket { - /** - * 重连代理服务 - */ - private static final ScheduledExecutorService reconnectExecutor = Executors.newSingleThreadScheduledExecutor(); - private static EventLoopGroup eventLoopGroup = new NioEventLoopGroup(); - - public static Channel connectProxyServer() throws Exception { - reconnectExecutor.scheduleAtFixedRate(() -> { - try { - connectProxyServer(null); - } catch (Exception e) { - e.printStackTrace(); - } - }, 3, 3, TimeUnit.SECONDS); - return connectProxyServer(null); - } - - public static Channel connectProxyServer(String vid) throws Exception { - if (StringUtil.isNullOrEmpty(vid)) { - if (Constant.proxyChannel == null || !Constant.proxyChannel.isActive()) { - newConnect(null); - } - return null; - } else { - Channel channel = Constant.vpc.get(vid); - if (null == channel) { - newConnect(vid); - channel = Constant.vpc.get(vid); - } - return channel; - } - } - - private static void newConnect(String vid) throws InterruptedException { - Bootstrap bootstrap = new Bootstrap(); - bootstrap.group(eventLoopGroup).channel(NioSocketChannel.class) - .handler(new ChannelInitializer() { - @Override - public void initChannel(SocketChannel ch) throws Exception { - ChannelPipeline pipeline = ch.pipeline(); - pipeline.addLast(new MyMsgDecoder(Integer.MAX_VALUE, 0, 4, -4, 0)); - pipeline.addLast(new MyMsgEncoder()); - pipeline.addLast(new IdleStateHandler(40, 8, 0)); - pipeline.addLast(new ProxyHandler()); - } - }); - - bootstrap.connect(Constant.serverIp, Constant.serverPort).addListener(new ChannelFutureListener() { - @Override - public void operationComplete(ChannelFuture future) throws Exception { - if (future.isSuccess()) { - // 客户端链接代理服务器成功 - Channel channel = future.channel(); - if (StringUtil.isNullOrEmpty(vid)) { - // 告诉服务端这条连接是client的连接 - MyMsg myMsg = new MyMsg(); - myMsg.setType(MyMsg.TYPE_CONNECT); - myMsg.setData("client".getBytes()); - channel.writeAndFlush(myMsg); - - Constant.proxyChannel = channel; - } else { - - // 告诉服务端这条连接是vid的连接 - MyMsg myMsg = new MyMsg(); - myMsg.setType(MyMsg.TYPE_CONNECT); - myMsg.setData(vid.getBytes()); - channel.writeAndFlush(myMsg); - - // 客户端绑定通道关系 - Constant.vpc.put(vid, channel); - channel.attr(Constant.VID).set(vid); - - Channel realChannel = Constant.vrc.get(vid); - if (null != realChannel) { - realChannel.config().setOption(ChannelOption.AUTO_READ, true); - } - } - } - } - }); - } -} \ No newline at end of file diff --git a/netty-proxy-client/src/main/java/com/luck/client/RealHandler.java b/netty-proxy-client/src/main/java/com/luck/client/RealHandler.java deleted file mode 100644 index 5f1d679..0000000 --- a/netty-proxy-client/src/main/java/com/luck/client/RealHandler.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.luck.client; - -import com.luck.msg.MyMsg; -import io.netty.buffer.ByteBuf; -import io.netty.channel.Channel; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelOption; -import io.netty.channel.SimpleChannelInboundHandler; -import io.netty.util.internal.StringUtil; - -public class RealHandler extends SimpleChannelInboundHandler { - - @Override - public void channelRead0(ChannelHandlerContext ctx, ByteBuf buf) { - // 客户读取到真实服务数据了 - byte[] bytes = new byte[buf.readableBytes()]; - buf.readBytes(bytes); - MyMsg myMsg = new MyMsg(); - myMsg.setType(MyMsg.TYPE_TRANSFER); - myMsg.setData(bytes); - String vid = ctx.channel().attr(Constant.VID).get(); - if (StringUtil.isNullOrEmpty(vid)) { - return; - } - Channel proxyChannel = Constant.vpc.get(vid); - if (null != proxyChannel) { - proxyChannel.writeAndFlush(myMsg); - } - // 客户端发送真实数据到代理了 - } - - @Override - public void channelActive(ChannelHandlerContext ctx) throws Exception { - super.channelActive(ctx); - } - - @Override - public void channelInactive(ChannelHandlerContext ctx) throws Exception { - String vid = ctx.channel().attr(Constant.VID).get(); - if (StringUtil.isNullOrEmpty(vid)) { - super.channelInactive(ctx); - return; - } - Channel proxyChannel = Constant.vpc.get(vid); - if (proxyChannel != null) { - MyMsg myMsg = new MyMsg(); - myMsg.setType(MyMsg.TYPE_DISCONNECT); - myMsg.setData(vid.getBytes()); - proxyChannel.writeAndFlush(myMsg); - } - - super.channelInactive(ctx); - } - - @Override - public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception { - String vid = ctx.channel().attr(Constant.VID).get(); - if (StringUtil.isNullOrEmpty(vid)) { - super.channelWritabilityChanged(ctx); - return; - } - Channel proxyChannel = Constant.vpc.get(vid); - if (proxyChannel != null) { - proxyChannel.config().setOption(ChannelOption.AUTO_READ, ctx.channel().isWritable()); - } - - super.channelWritabilityChanged(ctx); - } - - @Override - public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { - super.exceptionCaught(ctx, cause); - } -} \ No newline at end of file diff --git a/netty-proxy-client/src/main/java/com/luck/client/RealSocket.java b/netty-proxy-client/src/main/java/com/luck/client/RealSocket.java deleted file mode 100644 index 2b5d84f..0000000 --- a/netty-proxy-client/src/main/java/com/luck/client/RealSocket.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.luck.client; - -import io.netty.bootstrap.Bootstrap; -import io.netty.channel.*; -import io.netty.channel.nio.NioEventLoopGroup; -import io.netty.channel.socket.SocketChannel; -import io.netty.channel.socket.nio.NioSocketChannel; -import io.netty.util.internal.StringUtil; - -public class RealSocket { - static EventLoopGroup eventLoopGroup = new NioEventLoopGroup(); - - /** - * 连接真实服务 - * - * @param vid 访客ID - * @return - */ - public static Channel connectRealServer(String vid) { - if (StringUtil.isNullOrEmpty(vid)) { - return null; - } - Channel channel = Constant.vrc.get(vid); - if (null == channel) { - newConnect(vid); - channel = Constant.vrc.get(vid); - } - return channel; - } - - private static void newConnect(String vid) { - try { - Bootstrap bootstrap = new Bootstrap(); - bootstrap.group(eventLoopGroup).channel(NioSocketChannel.class) - .handler(new ChannelInitializer() { - @Override - public void initChannel(SocketChannel ch) throws Exception { - ChannelPipeline pipeline = ch.pipeline(); - pipeline.addLast(new RealHandler()); - } - - }); - bootstrap.connect("127.0.0.1", Constant.realPort).addListener(new ChannelFutureListener() { - @Override - public void operationComplete(ChannelFuture future) throws Exception { - if (future.isSuccess()) { - // 客户端链接真实服务成功 - future.channel().config().setOption(ChannelOption.AUTO_READ, false); - future.channel().attr(Constant.VID).set(vid); - Constant.vrc.put(vid, future.channel()); - ProxySocket.connectProxyServer(vid); - } - } - }); - } catch (Exception e) { - e.printStackTrace(); - } - } -} \ No newline at end of file diff --git a/netty-proxy-client/src/main/java/com/luck/client/controller/ClientController.java b/netty-proxy-client/src/main/java/com/luck/client/controller/ClientController.java deleted file mode 100644 index 7d33c6a..0000000 --- a/netty-proxy-client/src/main/java/com/luck/client/controller/ClientController.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.luck.client.controller; - -import com.wu.framework.inner.layer.web.EasyController; -import com.wu.framework.response.Result; -import com.wu.framework.response.ResultFactory; -import io.swagger.annotations.Api; -import org.springframework.web.bind.annotation.GetMapping; - -@Api(tags = "客户端client") -@EasyController("/client") -public class ClientController { - - @GetMapping("/version") - public Result version() { - return ResultFactory.successOf("客户端版本"); - } -} diff --git a/netty-proxy-client/src/main/resources/application.yml b/netty-proxy-client/src/main/resources/application.yml deleted file mode 100644 index b374691..0000000 --- a/netty-proxy-client/src/main/resources/application.yml +++ /dev/null @@ -1,2 +0,0 @@ -server: - port: 1003 \ No newline at end of file diff --git a/netty-proxy-common/pom.xml b/netty-proxy-common/pom.xml deleted file mode 100644 index 5e9a2e9..0000000 --- a/netty-proxy-common/pom.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - netty-proxy - com.wu - 0.0.1-SNAPSHOT - - 4.0.0 - - netty-proxy-common - - - 8 - 8 - - - - io.netty - netty-all - 4.1.74.Final - - - - \ No newline at end of file diff --git a/netty-proxy-common/src/main/java/com/luck/msg/MyMsg.java b/netty-proxy-common/src/main/java/com/luck/msg/MyMsg.java deleted file mode 100644 index c9d1087..0000000 --- a/netty-proxy-common/src/main/java/com/luck/msg/MyMsg.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.luck.msg; - -import java.util.Arrays; - -public class MyMsg { - - /** - * 心跳 - */ - public static final byte TYPE_HEARTBEAT = 0X00; - - /** - * 连接成功 - */ - public static final byte TYPE_CONNECT = 0X01; - - /** - * 数据传输 - */ - public static final byte TYPE_TRANSFER = 0X02; - - /** - * 连接断开 - */ - public static final byte TYPE_DISCONNECT = 0X09; - - /** - * 数据类型 - */ - private byte type; - - /** - * 消息传输数据 - */ - private byte[] data; - - public byte getType() { - return type; - } - - public void setType(byte type) { - this.type = type; - } - - public byte[] getData() { - return data; - } - - public void setData(byte[] data) { - this.data = data; - } - - @Override - public String toString() { - return "MyMsg [type=" + type + ", data=" + Arrays.toString(data) + "]"; - } - -} \ No newline at end of file diff --git a/netty-proxy-common/src/main/java/com/luck/msg/MyMsgDecoder.java b/netty-proxy-common/src/main/java/com/luck/msg/MyMsgDecoder.java deleted file mode 100644 index 6f9809e..0000000 --- a/netty-proxy-common/src/main/java/com/luck/msg/MyMsgDecoder.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.luck.msg; - -import io.netty.buffer.ByteBuf; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.LengthFieldBasedFrameDecoder; - -public class MyMsgDecoder extends LengthFieldBasedFrameDecoder { - - public MyMsgDecoder(int maxFrameLength, int lengthFieldOffset, int lengthFieldLength, int lengthAdjustment, - int initialBytesToStrip) { - super(maxFrameLength, lengthFieldOffset, lengthFieldLength, lengthAdjustment, initialBytesToStrip); - } - - public MyMsgDecoder(int maxFrameLength, int lengthFieldOffset, int lengthFieldLength, int lengthAdjustment, - int initialBytesToStrip, boolean failFast) { - super(maxFrameLength, lengthFieldOffset, lengthFieldLength, lengthAdjustment, initialBytesToStrip, failFast); - } - - @Override - protected MyMsg decode(ChannelHandlerContext ctx, ByteBuf in2) throws Exception { - ByteBuf in = (ByteBuf) super.decode(ctx, in2); - if (in == null) { - return null; - } - - if (in.readableBytes() < 4) { - return null; - } - - MyMsg myMsg = new MyMsg(); - int dataLength = in.readInt(); - byte type = in.readByte(); - myMsg.setType(type); - byte[] data = new byte[dataLength - 5]; - in.readBytes(data); - myMsg.setData(data); - in.release(); - - return myMsg; - } -} \ No newline at end of file diff --git a/netty-proxy-common/src/main/java/com/luck/msg/MyMsgEncoder.java b/netty-proxy-common/src/main/java/com/luck/msg/MyMsgEncoder.java deleted file mode 100644 index ec10ecf..0000000 --- a/netty-proxy-common/src/main/java/com/luck/msg/MyMsgEncoder.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.luck.msg; - -import io.netty.buffer.ByteBuf; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.MessageToByteEncoder; - -public class MyMsgEncoder extends MessageToByteEncoder { - - public MyMsgEncoder() { - - } - - @Override - protected void encode(ChannelHandlerContext ctx, MyMsg msg, ByteBuf out) throws Exception { - int bodyLength = 5; - if (msg.getData() != null) { - bodyLength += msg.getData().length; - } - - out.writeInt(bodyLength); - - out.writeByte(msg.getType()); - - if (msg.getData() != null) { - out.writeBytes(msg.getData()); - } - } -} \ No newline at end of file diff --git a/netty-proxy-server/pom.xml b/netty-proxy-server/pom.xml deleted file mode 100644 index fad37ad..0000000 --- a/netty-proxy-server/pom.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - netty-proxy - com.wu - 0.0.1-SNAPSHOT - - 4.0.0 - - netty-proxy-server - - - 8 - 8 - - - - - com.wu - netty-proxy-common - 0.0.1-SNAPSHOT - - - org.springframework.boot - spring-boot-starter-web - - - io.springfox - springfox-boot-starter - 3.0.0 - - - top.wu2020 - wu-framework-web - 1.1.9-JDK1.8-SNAPSHOT - - - \ No newline at end of file diff --git a/netty-proxy-server/src/main/java/com/luck/server/ClientHandler.java b/netty-proxy-server/src/main/java/com/luck/server/ClientHandler.java deleted file mode 100644 index 0bbb5f0..0000000 --- a/netty-proxy-server/src/main/java/com/luck/server/ClientHandler.java +++ /dev/null @@ -1,113 +0,0 @@ -package com.luck.server; - -import com.luck.msg.MyMsg; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; -import io.netty.channel.*; -import io.netty.handler.timeout.IdleStateEvent; -import io.netty.util.internal.StringUtil; - -public class ClientHandler extends SimpleChannelInboundHandler { - - @Override - public void channelRead0(ChannelHandlerContext ctx, MyMsg myMsg) { - // 代理服务器读到客户端数据了 - byte type = myMsg.getType(); - switch (type) { - case MyMsg.TYPE_HEARTBEAT: - MyMsg hb = new MyMsg(); - hb.setType(MyMsg.TYPE_HEARTBEAT); - ctx.channel().writeAndFlush(hb); - break; - case MyMsg.TYPE_CONNECT: - String vid = new String(myMsg.getData()); - if (StringUtil.isNullOrEmpty(vid) || "client".equals(vid)) { - Constant.clientChannel = ctx.channel(); - } else { - // 绑定访客和客户端的连接 - Channel visitorChannel = Constant.vvc.get(vid); - if (null != visitorChannel) { - ctx.channel().attr(Constant.VID).set(vid); - Constant.vcc.put(vid, ctx.channel()); - - // 通道绑定完成可以读取访客数据 - visitorChannel.config().setOption(ChannelOption.AUTO_READ, true); - } - } - break; - case MyMsg.TYPE_DISCONNECT: - String disVid = new String(myMsg.getData()); - Constant.clearVccVvcAndClose(disVid); - break; - case MyMsg.TYPE_TRANSFER: - // 把数据转到用户服务 - ByteBuf buf = ctx.alloc().buffer(myMsg.getData().length); - buf.writeBytes(myMsg.getData()); - - String visitorId = ctx.channel().attr(Constant.VID).get(); - Channel vchannel = Constant.vvc.get(visitorId); - if (null != vchannel) { - vchannel.writeAndFlush(buf); - } - break; - default: - // 操作有误 - } - // 代理服务器发送数据到用户了 - } - - @Override - public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception { - String vid = ctx.channel().attr(Constant.VID).get(); - if (StringUtil.isNullOrEmpty(vid)) { - super.channelWritabilityChanged(ctx); - return; - } - Channel visitorChannel = Constant.vvc.get(vid); - if (visitorChannel != null) { - visitorChannel.config().setOption(ChannelOption.AUTO_READ, ctx.channel().isWritable()); - } - - super.channelWritabilityChanged(ctx); - } - - @Override - public void channelInactive(ChannelHandlerContext ctx) throws Exception { - String vid = ctx.channel().attr(Constant.VID).get(); - if (StringUtil.isNullOrEmpty(vid)) { - super.channelInactive(ctx); - return; - } - Channel visitorChannel = Constant.vvc.get(vid); - if (visitorChannel != null && visitorChannel.isActive()) { - // 数据发送完成后再关闭连接,解决http1.0数据传输问题 - visitorChannel.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE); - visitorChannel.close(); - } else { - ctx.channel().close(); - } - Constant.clearVccVvc(vid); - super.channelInactive(ctx); - } - - @Override - public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { - super.exceptionCaught(ctx, cause); - } - - @Override - public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { - if (evt instanceof IdleStateEvent) { - IdleStateEvent event = (IdleStateEvent) evt; - switch (event.state()) { - case READER_IDLE: - ctx.channel().close(); - break; - case WRITER_IDLE: - break; - case ALL_IDLE: - break; - } - } - } -} \ No newline at end of file diff --git a/netty-proxy-server/src/main/java/com/luck/server/Constant.java b/netty-proxy-server/src/main/java/com/luck/server/Constant.java deleted file mode 100644 index ed6cde3..0000000 --- a/netty-proxy-server/src/main/java/com/luck/server/Constant.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.luck.server; - -import io.netty.channel.Channel; -import io.netty.util.AttributeKey; -import io.netty.util.internal.StringUtil; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -public class Constant { - /** - * 绑定channel_id - */ - public static final AttributeKey VID = AttributeKey.newInstance("vid"); - /** - * 客户端服务channel - */ - public static Channel clientChannel = null; - /** - * 访客,客户服务channel - */ - public static Map vcc = new ConcurrentHashMap<>(); - - /** - * 访客,访客服务channel - */ - public static Map vvc = new ConcurrentHashMap<>(); - - /** - * 服务代理端口 - */ - public static int visitorPort = 16002; - - /** - * 服务端口 - */ - public static int serverPort = 16001; - - /** - * 清除连接 - * - * @param vid 访客ID - */ - public static void clearVccVvc(String vid) { - if (StringUtil.isNullOrEmpty(vid)) { - return; - } - Channel clientChannel = vcc.get(vid); - if (null != clientChannel) { - clientChannel.attr(VID).set(null); - vcc.remove(vid); - } - Channel visitorChannel = vvc.get(vid); - if (null != visitorChannel) { - visitorChannel.attr(VID).set(null); - vvc.remove(vid); - } - } - - /** - * 清除关闭连接 - * - * @param vid 访客ID - */ - public static void clearVccVvcAndClose(String vid) { - if (StringUtil.isNullOrEmpty(vid)) { - return; - } - Channel clientChannel = vcc.get(vid); - if (null != clientChannel) { - clientChannel.attr(VID).set(null); - vcc.remove(vid); - clientChannel.close(); - } - Channel visitorChannel = vvc.get(vid); - if (null != visitorChannel) { - visitorChannel.attr(VID).set(null); - vvc.remove(vid); - visitorChannel.close(); - } - } -} \ No newline at end of file diff --git a/netty-proxy-server/src/main/java/com/luck/server/ServerSocket.java b/netty-proxy-server/src/main/java/com/luck/server/ServerSocket.java deleted file mode 100644 index 4efca69..0000000 --- a/netty-proxy-server/src/main/java/com/luck/server/ServerSocket.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.luck.server; - -import com.luck.msg.MyMsgDecoder; -import com.luck.msg.MyMsgEncoder; -import io.netty.bootstrap.ServerBootstrap; -import io.netty.channel.*; -import io.netty.channel.nio.NioEventLoopGroup; -import io.netty.channel.socket.SocketChannel; -import io.netty.channel.socket.nio.NioServerSocketChannel; -import io.netty.handler.timeout.IdleStateHandler; - -public class ServerSocket { - private static EventLoopGroup bossGroup = new NioEventLoopGroup(); - private static EventLoopGroup workerGroup = new NioEventLoopGroup(); - private static ChannelFuture channelFuture; - - /** - * 启动服务端 - * - * @throws Exception - */ - public static void startServer() throws Exception { - try { - - ServerBootstrap b = new ServerBootstrap(); - b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class) - .childHandler(new ChannelInitializer() { - @Override - public void initChannel(SocketChannel ch) throws Exception { - ChannelPipeline pipeline = ch.pipeline(); - pipeline.addLast(new MyMsgDecoder(Integer.MAX_VALUE, 0, 4, -4, 0)); - pipeline.addLast(new MyMsgEncoder()); - pipeline.addLast(new IdleStateHandler(40, 10, 0)); - pipeline.addLast(new ClientHandler()); - } - - }); - channelFuture = b.bind(Constant.serverPort).sync(); - - channelFuture.addListener((ChannelFutureListener) channelFuture -> { - // 服务器已启动 - }); - channelFuture.channel().closeFuture().sync(); - } finally { - shutdown(); - // 服务器已关闭 - } - } - - public static void shutdown() { - if (channelFuture != null) { - channelFuture.channel().close().syncUninterruptibly(); - } - if ((bossGroup != null) && (!bossGroup.isShutdown())) { - bossGroup.shutdownGracefully(); - } - if ((workerGroup != null) && (!workerGroup.isShutdown())) { - workerGroup.shutdownGracefully(); - } - } -} \ No newline at end of file diff --git a/netty-proxy-server/src/main/java/com/luck/server/ServerStart.java b/netty-proxy-server/src/main/java/com/luck/server/ServerStart.java deleted file mode 100644 index 1425ca7..0000000 --- a/netty-proxy-server/src/main/java/com/luck/server/ServerStart.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.luck.server; - - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class ServerStart { - public static void main(String[] args) throws Exception { - if (null != args && args.length == 2) { - int visitorPort = Integer.parseInt(args[1]); - int serverPort = Integer.parseInt(args[0]); - Constant.visitorPort = visitorPort; - Constant.serverPort = serverPort; - } - log.info(" 服务代理端口: " + Constant.visitorPort + " 服务端端口:" + Constant.serverPort); - // 启动访客服务端,用于接收访客请求 - VisitorSocket.startServer(); - // 启动代理服务端,用于接收客户端请求 - ServerSocket.startServer(); - } -} \ No newline at end of file diff --git a/netty-proxy-server/src/main/java/com/luck/server/VisitorHandler.java b/netty-proxy-server/src/main/java/com/luck/server/VisitorHandler.java deleted file mode 100644 index bc2124a..0000000 --- a/netty-proxy-server/src/main/java/com/luck/server/VisitorHandler.java +++ /dev/null @@ -1,97 +0,0 @@ -package com.luck.server; - -import com.luck.msg.MyMsg; -import io.netty.buffer.ByteBuf; -import io.netty.channel.Channel; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelOption; -import io.netty.channel.SimpleChannelInboundHandler; -import io.netty.util.internal.StringUtil; - -import java.util.UUID; - -public class VisitorHandler extends SimpleChannelInboundHandler { - - @Override - public void channelActive(ChannelHandlerContext ctx) throws Exception { - // 访客连接上代理服务器了 - Channel visitorChannel = ctx.channel(); - // 先不读取访客数据 - visitorChannel.config().setOption(ChannelOption.AUTO_READ, false); - - // 生成访客ID - String vid = UUID.randomUUID().toString(); - - // 绑定访客通道 - visitorChannel.attr(Constant.VID).set(vid); - Constant.vvc.put(vid, visitorChannel); - - MyMsg myMsg = new MyMsg(); - myMsg.setType(MyMsg.TYPE_CONNECT); - myMsg.setData(vid.getBytes()); - Constant.clientChannel.writeAndFlush(myMsg); - - super.channelActive(ctx); - } - - @Override - public void channelRead0(ChannelHandlerContext ctx, ByteBuf buf) { - String vid = ctx.channel().attr(Constant.VID).get(); - if (StringUtil.isNullOrEmpty(vid)) { - return; - } - byte[] bytes = new byte[buf.readableBytes()]; - buf.readBytes(bytes); - MyMsg myMsg = new MyMsg(); - myMsg.setType(MyMsg.TYPE_TRANSFER); - myMsg.setData(bytes); - - // 代理服务器发送数据到客户端了 - Channel clientChannel = Constant.vcc.get(vid); - clientChannel.writeAndFlush(myMsg); - } - - @Override - public void channelInactive(ChannelHandlerContext ctx) throws Exception { - String vid = ctx.channel().attr(Constant.VID).get(); - if (StringUtil.isNullOrEmpty(vid)) { - super.channelInactive(ctx); - return; - } - Channel clientChannel = Constant.vcc.get(vid); - if (clientChannel != null && clientChannel.isActive()) { - - clientChannel.config().setOption(ChannelOption.AUTO_READ, true); - - // 通知客户端,访客连接已经断开 - MyMsg myMsg = new MyMsg(); - myMsg.setType(MyMsg.TYPE_DISCONNECT); - myMsg.setData(vid.getBytes()); - clientChannel.writeAndFlush(myMsg); - } - Constant.clearVccVvc(vid); - super.channelInactive(ctx); - } - - @Override - public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception { - - Channel visitorChannel = ctx.channel(); - String vid = visitorChannel.attr(Constant.VID).get(); - if (StringUtil.isNullOrEmpty(vid)) { - super.channelWritabilityChanged(ctx); - return; - } - Channel clientChannel = Constant.vcc.get(vid); - if (clientChannel != null) { - clientChannel.config().setOption(ChannelOption.AUTO_READ, visitorChannel.isWritable()); - } - - super.channelWritabilityChanged(ctx); - } - - @Override - public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { - ctx.close(); - } -} \ No newline at end of file diff --git a/netty-proxy-server/src/main/java/com/luck/server/VisitorSocket.java b/netty-proxy-server/src/main/java/com/luck/server/VisitorSocket.java deleted file mode 100644 index 2affe79..0000000 --- a/netty-proxy-server/src/main/java/com/luck/server/VisitorSocket.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.luck.server; - -import io.netty.bootstrap.ServerBootstrap; -import io.netty.channel.ChannelDuplexHandler; -import io.netty.channel.ChannelInitializer; -import io.netty.channel.ChannelPipeline; -import io.netty.channel.EventLoopGroup; -import io.netty.channel.nio.NioEventLoopGroup; -import io.netty.channel.socket.SocketChannel; -import io.netty.channel.socket.nio.NioServerSocketChannel; - -public class VisitorSocket { - private static EventLoopGroup bossGroup = new NioEventLoopGroup(); - private static EventLoopGroup workerGroup = new NioEventLoopGroup(); - - /** - * 启动服务代理 - * - * @throws Exception - */ - public static void startServer() throws Exception { - - ServerBootstrap b = new ServerBootstrap(); - b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class) - .childHandler(new ChannelInitializer() { - @Override - public void initChannel(SocketChannel ch) throws Exception { - ChannelPipeline pipeline = ch.pipeline(); - pipeline.addLast(new ChannelDuplexHandler()); - pipeline.addLast(new VisitorHandler()); - } - }); - b.bind(Constant.visitorPort).get(); - - } - -} \ No newline at end of file diff --git a/netty-proxy-server/src/main/java/com/luck/server/controller/ServerController.java b/netty-proxy-server/src/main/java/com/luck/server/controller/ServerController.java deleted file mode 100644 index 9e09362..0000000 --- a/netty-proxy-server/src/main/java/com/luck/server/controller/ServerController.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.luck.server.controller; - -import com.wu.framework.inner.layer.web.EasyController; -import com.wu.framework.response.Result; -import com.wu.framework.response.ResultFactory; -import io.swagger.annotations.Api; -import org.springframework.web.bind.annotation.GetMapping; - -@Api(tags = "服务端") -@EasyController("/server") -public class ServerController { - - @GetMapping("/version") - public Result version() { - return ResultFactory.successOf("服务端端版本"); - } -} diff --git a/netty-proxy-server/src/main/resources/application.yml b/netty-proxy-server/src/main/resources/application.yml deleted file mode 100644 index b374691..0000000 --- a/netty-proxy-server/src/main/resources/application.yml +++ /dev/null @@ -1,2 +0,0 @@ -server: - port: 1003 \ No newline at end of file diff --git a/pom.xml b/pom.xml index d2d7958..bf21f02 100644 --- a/pom.xml +++ b/pom.xml @@ -1,68 +1,69 @@ - + 4.0.0 - pom + - org.springframework.boot - spring-boot-starter-parent - 3.0.2 - + wu-framework-parent + top.wu2020 + 1.2.1-JDK17-SNAPSHOT + - com.wu - netty-proxy - 0.0.1-SNAPSHOT - netty-proxy - netty-proxy - - 19 - + + top.wu2020 + lazy-cloud-network + pom + 1.2.1-JDK17-SNAPSHOT + 云上云下 + - netty-proxy-common - netty-proxy-server - netty-proxy-client + + lazy-cloud-heartbeat-server + lazy-cloud-heartbeat-client + lazy-cloud-heartbeat-common - - - org.springframework.boot - spring-boot-starter - + + + + - org.springframework.boot - spring-boot-starter-test - test + org.projectlombok + lombok + 1.18.26 + + + org.projectlombok + lombok-mapstruct-binding + 0.2.0 + + + org.mapstruct + mapstruct + 1.5.5.Final + + + org.mapstruct + mapstruct-processor + 1.5.5.Final - - - oss.snapshots - oss.sonatype.org - https://oss.sonatype.org/content/repositories/snapshots/ - - false - - - true - - - + + + + top.wu2020 + wu-framework-dependencies + 1.2.1-JDK17-SNAPSHOT + pom + import + + + - - - - org.graalvm.buildtools - native-maven-plugin - - - org.springframework.boot - spring-boot-maven-plugin - - - - + \ No newline at end of file