【fix】添加 @Role(BeanDefinition.ROLE_INFRASTRUCTURE)

This commit is contained in:
wujiawei
2025-05-07 17:47:23 +08:00
parent 2e40988ef4
commit fe3adeee03
28 changed files with 1086 additions and 177 deletions

View File

@ -443,5 +443,17 @@ public class ClientAutoConfiguration {
public ClientHandleDistributeSocksClientProxyClientTransferTransferRequestAdvanced clientHandleDistributeSocksClientProxyClientTransferTransferRequestAdvanced(){
return new ClientHandleDistributeSocksClientProxyClientTransferTransferRequestAdvanced();
}
@Bean
public ClientHandleSocksDistributeServerProxyClientConnectionInitTypeAdvanced clientHandleSocksDistributeServerProxyClientConnectionInitTypeAdvanced(){
return new ClientHandleSocksDistributeServerProxyClientConnectionInitTypeAdvanced();
}
@Bean
public ClientHandleSocksDistributeServerProxyClientRequestTypeAdvanced clientHandleSocksDistributeServerProxyClientRequestTypeAdvanced(){
return new ClientHandleSocksDistributeServerProxyClientRequestTypeAdvanced();
}
@Bean
public ClientHandleSocksDistributeServerProxyClientTransferCloseAdvanced clientHandleSocksDistributeServerProxyClientTransferCloseAdvanced(){
return new ClientHandleSocksDistributeServerProxyClientTransferCloseAdvanced();
}
}
}

View File

@ -0,0 +1,73 @@
package org.framework.lazy.cloud.network.heartbeat.client.netty.proxy.socks.advanced;
import io.netty.channel.Channel;
import io.netty.handler.codec.socksx.v5.Socks5AddressType;
import lombok.extern.slf4j.Slf4j;
import org.framework.lazy.cloud.network.heartbeat.client.config.NettyClientProperties;
import org.framework.lazy.cloud.network.heartbeat.client.netty.proxy.socks.NettySocksClientProxyClient;
import org.framework.lazy.cloud.network.heartbeat.client.netty.proxy.socks.socket.NettySocksServerProxyClientRealSocket;
import org.framework.lazy.cloud.network.heartbeat.common.advanced.HandleChannelTypeAdvanced;
import org.framework.lazy.cloud.network.heartbeat.common.advanced.payload.NettyChannelContext;
import org.framework.lazy.cloud.network.heartbeat.common.advanced.payload.NettyProxyMsg;
import org.framework.lazy.cloud.network.heartbeat.common.advanced.proxy.socks.client.AbstractHandleSocksDistributeServerProxyClientConnectionInitTypeAdvanced;
import org.framework.lazy.cloud.network.heartbeat.common.utils.ChannelAttributeKeyUtils;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Role;
import org.wu.framework.spring.utils.SpringContextHolder;
import java.util.ArrayList;
import java.util.List;
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
@Slf4j
public class ClientHandleSocksDistributeServerProxyClientConnectionInitTypeAdvanced extends
AbstractHandleSocksDistributeServerProxyClientConnectionInitTypeAdvanced<NettyProxyMsg> {
/**
* 处理当前数据
*
* @param nettyChannelContext 当前通道
* @param nettyProxyMsg 通道数据
*/
@Override
protected void doHandler(NettyChannelContext nettyChannelContext, NettyProxyMsg nettyProxyMsg) {
// 创建传输通道
// 绑定真实通道
Channel channel = nettyChannelContext.channel();
String clientId = nettyProxyMsg.getClientIdString();
byte[] visitorId = nettyProxyMsg.getVisitorId();
String targetIp = nettyProxyMsg.getTargetIpString();
Integer targetPort = Integer.parseInt(nettyProxyMsg.getTargetPortString());
byte[] data = nettyProxyMsg.getData();
byte socks5AddressType = data[0];
List<HandleChannelTypeAdvanced> handleChannelTypeAdvancedList = new ArrayList<>(SpringContextHolder.getApplicationContext().getBeansOfType(HandleChannelTypeAdvanced.class).values());
NettyClientProperties nettyClientProperties = SpringContextHolder.getBean(NettyClientProperties.class);
NettySocksClientProxyClient nettySocksClientProxyClient = new NettySocksClientProxyClient();
nettySocksClientProxyClient.setTargetClientId(clientId);
nettySocksClientProxyClient.setNettyClientProperties(nettyClientProperties);
nettySocksClientProxyClient.setHandleChannelTypeAdvancedList(handleChannelTypeAdvancedList);
nettySocksClientProxyClient.setTargetIp(targetIp);
nettySocksClientProxyClient.setTargetPort(targetPort);
ChannelAttributeKeyUtils.buildVisitorId(channel, visitorId);
ChannelAttributeKeyUtils.buildSocks5AddressType(channel,socks5AddressType);
// 创建真实通道
NettySocksServerProxyClientRealSocket.buildRealServer(
clientId,
targetIp,
targetPort,
new String(visitorId),
nettyClientProperties,
handleChannelTypeAdvancedList
);
}
}

View File

@ -0,0 +1,43 @@
package org.framework.lazy.cloud.network.heartbeat.client.netty.proxy.socks.advanced;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import lombok.extern.slf4j.Slf4j;
import org.framework.lazy.cloud.network.heartbeat.client.netty.proxy.socks.handler.NettySocksServerProxyClientRealHandler;
import org.framework.lazy.cloud.network.heartbeat.common.advanced.payload.NettyChannelContext;
import org.framework.lazy.cloud.network.heartbeat.common.advanced.payload.NettyProxyMsg;
import org.framework.lazy.cloud.network.heartbeat.common.advanced.proxy.socks.client.AbstractHandleSocksDistributeServerProxyClientRequestTypeAdvanced;
import org.framework.lazy.cloud.network.heartbeat.common.utils.ChannelAttributeKeyUtils;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Role;
import org.wu.framework.core.utils.ObjectUtils;
/**
* @see NettySocksServerProxyClientRealHandler
*/
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
@Slf4j
public class ClientHandleSocksDistributeServerProxyClientRequestTypeAdvanced extends
AbstractHandleSocksDistributeServerProxyClientRequestTypeAdvanced<NettyProxyMsg> {
/**
* 处理当前数据
*
* @param nettyChannelContext 当前通道
* @param nettyProxyMsg 通道数据
*/
@Override
protected void doHandler(NettyChannelContext nettyChannelContext, NettyProxyMsg nettyProxyMsg) {
Channel channel = nettyChannelContext.channel();
Channel nextChannel = ChannelAttributeKeyUtils.getNextChannel(channel);
if(ObjectUtils.isNotEmpty(nextChannel)&&nextChannel.isActive()){
ByteBuf buf = nextChannel.config().getAllocator().buffer(nettyProxyMsg.getData().length);
buf.writeBytes(nettyProxyMsg.getData());
nextChannel.writeAndFlush(buf);
}else {
log.error("客户端代理服务端socks本地通道已关闭");
}
}
}

View File

@ -0,0 +1,34 @@
package org.framework.lazy.cloud.network.heartbeat.client.netty.proxy.socks.advanced;
import io.netty.channel.Channel;
import lombok.extern.slf4j.Slf4j;
import org.framework.lazy.cloud.network.heartbeat.common.advanced.payload.NettyChannelContext;
import org.framework.lazy.cloud.network.heartbeat.common.advanced.payload.NettyProxyMsg;
import org.framework.lazy.cloud.network.heartbeat.common.advanced.proxy.socks.client.AbstractHandleSocksDistributeServerProxyClientRequestTypeAdvanced;
import org.framework.lazy.cloud.network.heartbeat.common.advanced.proxy.socks.client.AbstractHandleSocksDistributeServerProxyClientTransferCloseAdvanced;
import org.framework.lazy.cloud.network.heartbeat.common.utils.ChannelAttributeKeyUtils;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Role;
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
@Slf4j
public class ClientHandleSocksDistributeServerProxyClientTransferCloseAdvanced extends
AbstractHandleSocksDistributeServerProxyClientTransferCloseAdvanced<NettyProxyMsg> {
/**
* 处理当前数据
*
* @param nettyChannelContext 当前通道
* @param nettyProxyMsg 通道数据
*/
@Override
protected void doHandler(NettyChannelContext nettyChannelContext, NettyProxyMsg nettyProxyMsg) {
//
Channel channel = nettyChannelContext.channel();
Channel nextChannel = ChannelAttributeKeyUtils.getNextChannel(channel);
channel.close();
nextChannel.close();
}
}

View File

@ -0,0 +1,28 @@
package org.framework.lazy.cloud.network.heartbeat.client.netty.proxy.socks.filter;
import io.netty.channel.Channel;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import org.framework.lazy.cloud.network.heartbeat.client.netty.proxy.socks.handler.NettySocksClientProxyClientRealHandler;
import org.framework.lazy.cloud.network.heartbeat.client.netty.proxy.socks.handler.NettySocksServerProxyClientRealHandler;
import org.framework.lazy.cloud.network.heartbeat.common.decoder.TransferDecoder;
import org.framework.lazy.cloud.network.heartbeat.common.encoder.TransferEncoder;
import org.framework.lazy.cloud.network.heartbeat.common.filter.DebugChannelInitializer;
public class NettySocksServerProxyClientRealFilter extends DebugChannelInitializer<SocketChannel> {
/**
* 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.
*/
@Override
protected void initChannel0(SocketChannel ch) {
ChannelPipeline pipeline = ch.pipeline();
// 解码、编码
pipeline.addLast(new TransferDecoder(Integer.MAX_VALUE, 1024 * 1024*10));
pipeline.addLast(new TransferEncoder());
pipeline.addLast(new NettySocksServerProxyClientRealHandler());
}
}

View File

@ -0,0 +1,44 @@
package org.framework.lazy.cloud.network.heartbeat.client.netty.proxy.socks.filter;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.timeout.IdleStateHandler;
import org.framework.lazy.cloud.network.heartbeat.client.netty.proxy.socks.handler.NettySocksServerProxyClientTransferHandler;
import org.framework.lazy.cloud.network.heartbeat.common.adapter.ChannelTypeAdapter;
import org.framework.lazy.cloud.network.heartbeat.common.decoder.NettyProxyMsgDecoder;
import org.framework.lazy.cloud.network.heartbeat.common.encoder.NettyProxyMsgEncoder;
import org.framework.lazy.cloud.network.heartbeat.common.filter.DebugChannelInitializer;
/**
* netty 客户端连接真实服服务端访客拦截器
*/
public class NettySocksServerProxyClientTransferFilter extends DebugChannelInitializer<SocketChannel> {
private final ChannelTypeAdapter channelTypeAdapter;
public NettySocksServerProxyClientTransferFilter(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 connectionClose
* the {@link Channel}.
*/
@Override
protected void initChannel0(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
// // 解码、编码
pipeline.addLast(new IdleStateHandler(0, 4, 0));
pipeline.addLast(new NettyProxyMsgDecoder(Integer.MAX_VALUE, 0, 4, -4, 0));
pipeline.addLast(new NettyProxyMsgEncoder());
pipeline.addLast(new NettySocksServerProxyClientTransferHandler(channelTypeAdapter));
}
}

View File

@ -0,0 +1,72 @@
package org.framework.lazy.cloud.network.heartbeat.client.netty.proxy.socks.handler;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.ReferenceCountUtil;
import lombok.extern.slf4j.Slf4j;
import org.framework.lazy.cloud.network.heartbeat.common.NettyByteBuf;
import org.framework.lazy.cloud.network.heartbeat.common.advanced.payload.NettyProxyMsg;
import org.framework.lazy.cloud.network.heartbeat.common.constant.ProxyMessageType;
import org.framework.lazy.cloud.network.heartbeat.common.utils.ChannelAttributeKeyUtils;
@Slf4j
public class NettyServerProxyClientVisitorInboundHandler extends SimpleChannelInboundHandler<NettyByteBuf> {
@Override
public void channelActive(ChannelHandlerContext ctx) {
ctx.writeAndFlush(Unpooled.EMPTY_BUFFER);
}
@Override
public void channelRead0(ChannelHandlerContext ctx, NettyByteBuf nettyByteBuf) throws Exception {
log.info("【socks】转发客户端的请求到代理服务器");
// 结果下发
Channel channel = ctx.channel();
byte[] bytes = nettyByteBuf.getData();
log.debug("bytes.length:{}",bytes.length);
log.debug("客户端代理服务端,socks本地接收请求数据:{}", new String(bytes));
Channel nextChannel = ChannelAttributeKeyUtils.getNextChannel(channel);
if (nextChannel.isActive()) {
// 上报数据到服务端
NettyProxyMsg nettyProxyMsg = new NettyProxyMsg();
nettyProxyMsg.setType(ProxyMessageType.SOCKS_DISTRIBUTE_SERVER_PROXY_CLIENT_TRANSFER_REQUEST_);
nettyProxyMsg.setData(nettyByteBuf.getData());
nextChannel.writeAndFlush(nettyProxyMsg);
} else {
log.info("释放内存");
ReferenceCountUtil.release(nettyByteBuf);
}
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
log.info("【socks】客户端与代理服务器的连接已经断开即将断开代理服务器和目标服务器的连接");
Channel channel = ctx.channel();
Channel nextChannel = ChannelAttributeKeyUtils.getNextChannel(channel);
if (nextChannel.isActive()) {
// 下发断开链接
NettyProxyMsg nettyProxyMsgTransferClose = new NettyProxyMsg();
nettyProxyMsgTransferClose.setType(ProxyMessageType.SOCKS_DISTRIBUTE_SERVER_PROXY_CLIENT_TRANSFER_CLOSE_);
nextChannel.writeAndFlush(nettyProxyMsgTransferClose);
if (ctx.channel().isActive()) {
ctx.channel().writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
}
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
log.error("【socks】NettyServerProxyClientVisitorInboundHandler exception", cause);
ctx.close();
}
}

View File

@ -53,7 +53,7 @@ public class NettySocksClientProxyClientRealHandler extends SimpleChannelInbound
if (nextChannel != null) {
// 上报关闭这个客户端的访客通道
NettyProxyMsg closeVisitorMsg = new NettyProxyMsg();
closeVisitorMsg.setType(TcpMessageType.TCP_REPORT_CLIENT_PERMEATE_CLIENT_TRANSFER_CLOSE);
closeVisitorMsg.setType(ProxyMessageType.SOCKS_REPORT_CLIENT_PROXY_CLIENT_TRANSFER_CLOSE_);
closeVisitorMsg.setVisitorId(visitorId);
nextChannel.writeAndFlush(closeVisitorMsg);
}

View File

@ -0,0 +1,82 @@
package org.framework.lazy.cloud.network.heartbeat.client.netty.proxy.socks.handler;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.extern.slf4j.Slf4j;
import org.framework.lazy.cloud.network.heartbeat.common.NettyByteBuf;
import org.framework.lazy.cloud.network.heartbeat.common.advanced.payload.NettyProxyMsg;
import org.framework.lazy.cloud.network.heartbeat.common.constant.ProxyMessageType;
import org.framework.lazy.cloud.network.heartbeat.common.constant.TcpMessageType;
import org.framework.lazy.cloud.network.heartbeat.common.utils.ChannelAttributeKeyUtils;
/**
* 来自客户端 真实服务器返回的数据请求
*/
@Slf4j
public class NettySocksServerProxyClientRealHandler extends SimpleChannelInboundHandler<NettyByteBuf> {
@Override
public void channelRead0(ChannelHandlerContext ctx,NettyByteBuf nettyByteBuf) {
byte[] bytes = nettyByteBuf.getData();
log.debug("bytes.length:{}",bytes.length);
log.debug("接收客户端真实服务数据:{}", new String(bytes));
String visitorId = ChannelAttributeKeyUtils.getVisitorId(ctx.channel());
Integer visitorPort = ChannelAttributeKeyUtils.getVisitorPort(ctx.channel());
String clientId = ChannelAttributeKeyUtils.getClientId(ctx.channel());
// 访客通信通道 上报服务端代理完成
Channel nextChannel = ChannelAttributeKeyUtils.getNextChannel(ctx.channel());
NettyProxyMsg returnMessage = new NettyProxyMsg();
returnMessage.setType(ProxyMessageType.SOCKS_REPORT_SERVER_PROXY_CLIENT_TRANSFER_RESPONSE_);
returnMessage.setVisitorId(visitorId);
returnMessage.setClientId(clientId);
returnMessage.setVisitorPort(visitorPort);
returnMessage.setData(bytes);
nextChannel.writeAndFlush(returnMessage);
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
super.channelActive(ctx);
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
String visitorId = ChannelAttributeKeyUtils.getVisitorId(ctx.channel());
// 客户端真实通信通道
Channel nextChannel = ChannelAttributeKeyUtils.getNextChannel(ctx.channel());
if (nextChannel != null) {
// 上报关闭这个客户端的访客通道
NettyProxyMsg closeVisitorMsg = new NettyProxyMsg();
closeVisitorMsg.setType(ProxyMessageType.SOCKS_REPORT_SERVER_PROXY_CLIENT_TRANSFER_CLOSE_);
closeVisitorMsg.setVisitorId(visitorId);
nextChannel.writeAndFlush(closeVisitorMsg);
}
super.channelInactive(ctx);
}
@Override
public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception {
// 获取访客的传输通道
if (ctx.channel().isWritable()) {
log.debug("Channel is writable again");
// 恢复之前暂停的操作,如写入数据
} else {
log.debug("Channel is not writable");
// 暂停写入操作,等待可写状态
}
log.info("channelWritabilityChanged!");
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
super.exceptionCaught(ctx, cause);
}
}

View File

@ -0,0 +1,70 @@
package org.framework.lazy.cloud.network.heartbeat.client.netty.proxy.socks.handler;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.extern.slf4j.Slf4j;
import org.framework.lazy.cloud.network.heartbeat.common.adapter.ChannelTypeAdapter;
import org.framework.lazy.cloud.network.heartbeat.common.advanced.payload.NettyProxyMsg;
import org.framework.lazy.cloud.network.heartbeat.common.constant.ProxyMessageType;
import org.framework.lazy.cloud.network.heartbeat.common.utils.ChannelAttributeKeyUtils;
@Slf4j
public class NettySocksServerProxyClientTransferHandler extends SimpleChannelInboundHandler<NettyProxyMsg> {
private final ChannelTypeAdapter channelTypeAdapter;
public NettySocksServerProxyClientTransferHandler(ChannelTypeAdapter channelTypeAdapter) {
this.channelTypeAdapter = channelTypeAdapter;
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
super.channelActive(ctx);
}
@Override
public void channelRead0(ChannelHandlerContext ctx, NettyProxyMsg nettyProxyMsg) throws Exception {
channelTypeAdapter.handler(ctx, nettyProxyMsg);
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
String clientId = ChannelAttributeKeyUtils.getClientId(ctx.channel());
String visitorId = ChannelAttributeKeyUtils.getVisitorId(ctx.channel());
Channel nextChannel = ChannelAttributeKeyUtils.getNextChannel(ctx.channel());
log.warn("close client permeate client transfer real clientId:{} visitorId:{}", clientId, visitorId);
// 关闭访客
if (nextChannel != null) {
// 上报关闭这个客户端的访客通道
NettyProxyMsg closeVisitorMsg = new NettyProxyMsg();
closeVisitorMsg.setType(ProxyMessageType.SOCKS_REPORT_SERVER_PROXY_CLIENT_TRANSFER_CLOSE_);
closeVisitorMsg.setVisitorId(visitorId);
nextChannel.writeAndFlush(closeVisitorMsg);
}
super.channelInactive(ctx);
}
@Override
public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception {
// 处理客户端本地真实通道问题
if (ctx.channel().isWritable()) {
log.debug("Channel is writable again");
// 恢复之前暂停的操作,如写入数据
} else {
log.debug("Channel is not writable");
// 暂停写入操作,等待可写状态
}
log.info("channelWritabilityChanged!");
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
super.exceptionCaught(ctx, cause);
}
}

View File

@ -0,0 +1,166 @@
package org.framework.lazy.cloud.network.heartbeat.client.netty.proxy.socks.socket;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.socket.nio.NioSocketChannel;
import lombok.extern.slf4j.Slf4j;
import org.framework.lazy.cloud.network.heartbeat.client.config.NettyClientProperties;
import org.framework.lazy.cloud.network.heartbeat.client.netty.proxy.socks.filter.NettySocksClientProxyClientRealFilter;
import org.framework.lazy.cloud.network.heartbeat.client.netty.proxy.socks.filter.NettySocksClientProxyClientTransferFilter;
import org.framework.lazy.cloud.network.heartbeat.client.netty.proxy.socks.filter.NettySocksServerProxyClientRealFilter;
import org.framework.lazy.cloud.network.heartbeat.client.netty.proxy.socks.filter.NettySocksServerProxyClientTransferFilter;
import org.framework.lazy.cloud.network.heartbeat.common.NettyRealIdContext;
import org.framework.lazy.cloud.network.heartbeat.common.adapter.ChannelTypeAdapter;
import org.framework.lazy.cloud.network.heartbeat.common.advanced.HandleChannelTypeAdvanced;
import org.framework.lazy.cloud.network.heartbeat.common.advanced.payload.NettyProxyMsg;
import org.framework.lazy.cloud.network.heartbeat.common.constant.ProxyMessageType;
import org.framework.lazy.cloud.network.heartbeat.common.factory.EventLoopGroupFactory;
import org.framework.lazy.cloud.network.heartbeat.common.utils.ChannelAttributeKeyUtils;
import java.util.List;
import java.util.concurrent.TimeUnit;
@Slf4j
public class NettySocksServerProxyClientRealSocket {
public static void buildRealServer(String clientId,
String targetIp,
Integer targetPort,
String visitorId,
NettyClientProperties nettyClientProperties,
List<HandleChannelTypeAdvanced> handleChannelTypeAdvancedList) {
try {
EventLoopGroup eventLoopGroup = EventLoopGroupFactory.createClientWorkGroup();
Bootstrap bootstrap = new Bootstrap();
bootstrap
.group(eventLoopGroup)
.channel(NioSocketChannel.class)
.option(ChannelOption.TCP_NODELAY, true)
// 设置读缓冲区为2M
.option(ChannelOption.SO_RCVBUF, 2048 * 1024)
// 设置写缓冲区为1M
.option(ChannelOption.SO_SNDBUF, 1024 * 1024)
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 1000 * 60)//连接超时时间设置为 60 秒
.option(ChannelOption.WRITE_BUFFER_WATER_MARK, new WriteBufferWaterMark(1024 * 1024, 1024 * 1024 * 2))
.handler(new NettySocksServerProxyClientRealFilter())
;
bootstrap.connect(targetIp, targetPort).addListener((ChannelFutureListener) future -> {
if (future.isSuccess()) {
// 客户端链接真实服务成功 设置自动读写false 等待访客连接成功后设置成true
Channel realChannel = future.channel();
realChannel.config().setOption(ChannelOption.AUTO_READ, false);
log.info("访客通过 客户端:【{}】,visitorId:{},绑定本地服务,IP:{},端口:{} 新建通道成功", clientId, visitorId, targetIp, targetPort);
// 客户端真实通道
NettyRealIdContext.pushReal(realChannel, visitorId);
// 绑定访客ID到当前真实通道属性
ChannelAttributeKeyUtils.buildVisitorId(realChannel, visitorId);
ChannelAttributeKeyUtils.buildClientId(realChannel, clientId);
// 连接服务端 然后绑定通道
// 新建一个通道处理
newVisitorConnect2Server(
clientId,
targetIp,
targetPort,
visitorId,
realChannel,
nettyClientProperties,
handleChannelTypeAdvancedList
);
} else {
log.error("客户:【{}】,无法连接当前网络内的目标IP【{}】,目标端口:【{}】", clientId, targetIp, targetPort);
// DefaultSocks5CommandResponse commandResponse = new DefaultSocks5CommandResponse(Socks5CommandStatus.FAILURE, socks5AddressType);
// transferChannel.writeAndFlush(commandResponse);
// realChannel.close();
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 创建访客连接服务端
*
* @param nettyClientProperties 服务端配置信息
* @param handleChannelTypeAdvancedList 处理器适配器
* @throws InterruptedException 异常
*/
protected static void newVisitorConnect2Server(String clientId,
String targetIp,
Integer targetPort,
String visitorId,
Channel realChannel,
NettyClientProperties nettyClientProperties,
List<HandleChannelTypeAdvanced> handleChannelTypeAdvancedList) throws InterruptedException {
EventLoopGroup eventLoopGroup = EventLoopGroupFactory.createClientWorkGroup();
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(eventLoopGroup)
.channel(NioSocketChannel.class)
.option(ChannelOption.SO_KEEPALIVE, true)
// 设置读缓冲区为2M
.option(ChannelOption.SO_RCVBUF, 2048 * 1024)
// 设置写缓冲区为1M
.option(ChannelOption.SO_SNDBUF, 1024 * 1024)
// .option(ChannelOption.TCP_NODELAY, false)
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 1000 * 60)//连接超时时间设置为 60 秒
.option(ChannelOption.WRITE_BUFFER_WATER_MARK, new WriteBufferWaterMark(1024 * 1024, 1024 * 1024 * 2))
.handler(new NettySocksServerProxyClientTransferFilter(new ChannelTypeAdapter(handleChannelTypeAdvancedList)))
;
String inetHost = nettyClientProperties.getInetHost();
int inetPort = nettyClientProperties.getInetPort();
// local client id
// 客户端新建访客通道 连接服务端IP:{},连接服务端端口:{}
log.info("client creates a new visitor channel to connect to server IP: {}, connecting to server port: {} with visitorId:{} & clientId:{}", inetHost, inetPort, visitorId, clientId);
ChannelFuture future = bootstrap.connect(inetHost, inetPort);
future.addListener((ChannelFutureListener) futureListener -> {
Channel transferChannel = futureListener.channel();
if (futureListener.isSuccess()) {
realChannel.config().setOption(ChannelOption.AUTO_READ, true);
// 通知服务端访客连接成功
NettyProxyMsg nettyProxyMsg = new NettyProxyMsg();
nettyProxyMsg.setVisitorId(visitorId);
nettyProxyMsg.setClientId(clientId);
nettyProxyMsg.setClientTargetIp(targetIp);
nettyProxyMsg.setClientTargetPort(targetPort);
nettyProxyMsg.setType(ProxyMessageType.SOCKS_REPORT_SERVER_PROXY_CLIENT_CONNECTION_SUCCESS_);
transferChannel.writeAndFlush(nettyProxyMsg);
ChannelAttributeKeyUtils.buildNextChannel(transferChannel, realChannel);
ChannelAttributeKeyUtils.buildNextChannel(realChannel, transferChannel);
// 绑定客户端真实通信通道
ChannelAttributeKeyUtils.buildVisitorId(transferChannel, visitorId);
ChannelAttributeKeyUtils.buildClientId(transferChannel, clientId);
} else {
log.info("无法连接到服务端....");
eventLoopGroup.schedule(() -> {
try {
newVisitorConnect2Server(clientId,
targetIp,
targetPort,
visitorId, realChannel, nettyClientProperties, handleChannelTypeAdvancedList);
} catch (Exception e) {
e.printStackTrace();
}
}, 2, TimeUnit.SECONDS);
}
});
}
}