Generated
BIN
Binary file not shown.
|
Before Width: | Height: | Size: 12 KiB |
@@ -0,0 +1,16 @@
|
||||
FROM openjdk:21-jdk-oracle
|
||||
#同步时间
|
||||
#RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && \
|
||||
# apk update && apk add wget unzip vim && apk add -U tzdata && \
|
||||
# ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone
|
||||
# 设置时区为北京时间
|
||||
ENV TZ=Asia/Shanghai
|
||||
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
|
||||
RUN mkdir -p /root/neutrino-proxy/config
|
||||
WORKDIR /root/neutrino-proxy
|
||||
COPY ./target/neutrino-proxy-client.jar /root/neutrino-proxy/neutrino-proxy-client.jar
|
||||
COPY ./src/main/resources/app-copy.yml /root/neutrino-proxy/config/app.yml
|
||||
#VOLUME ["/root/neutrino-proxy"]
|
||||
ENTRYPOINT ["java","-jar","neutrino-proxy-client.jar","config=./config/app.yml"]
|
||||
|
||||
#docker run -it -d --restart=always --name np_client -e SERVER_IP=127.0.0.1
|
||||
@@ -0,0 +1,62 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>neutrino-proxy</artifactId>
|
||||
<groupId>org.dromara.neutrino-proxy</groupId>
|
||||
<version>${revision}</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<artifactId>neutrino-proxy-client-sdk</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.dromara.neutrino-proxy</groupId>
|
||||
<artifactId>neutrino-proxy-core</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.noear</groupId>
|
||||
<artifactId>solon-lib</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.jsqlparser</groupId>
|
||||
<artifactId>jsqlparser</artifactId>
|
||||
<version>4.5</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>${project.artifactId}</finalName>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
<includes>
|
||||
<include>*.yml</include>
|
||||
</includes>
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>${project.basedir}/src/main/resources</directory>
|
||||
<filtering>false</filtering>
|
||||
|
||||
<excludes>
|
||||
<exclude>app-dev.yml</exclude>
|
||||
</excludes>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<!-- 配置打包插件(并打包成胖包) -->
|
||||
<plugin>
|
||||
<groupId>org.noear</groupId>
|
||||
<artifactId>solon-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package org.dromara.neutrinoproxy.client.sdk.config;
|
||||
|
||||
import org.dromara.neutrinoproxy.core.dispatcher.Dispatcher;
|
||||
|
||||
public interface IBeanHandler {
|
||||
Dispatcher getDispatcher();
|
||||
ProxyConfig getProxyConfig();
|
||||
}
|
||||
+187
@@ -0,0 +1,187 @@
|
||||
package org.dromara.neutrinoproxy.client.sdk.config;
|
||||
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
import io.netty.channel.socket.nio.NioDatagramChannel;
|
||||
import io.netty.channel.socket.nio.NioSocketChannel;
|
||||
import io.netty.handler.logging.LoggingHandler;
|
||||
import io.netty.handler.timeout.IdleStateHandler;
|
||||
import org.dromara.neutrinoproxy.client.sdk.core.*;
|
||||
import org.dromara.neutrinoproxy.client.sdk.util.ProxyUtil;
|
||||
import org.dromara.neutrinoproxy.core.ProxyMessageDecoder;
|
||||
import org.dromara.neutrinoproxy.core.ProxyMessageEncoder;
|
||||
import org.dromara.neutrinoproxy.core.aot.NeutrinoCoreRuntimeNativeRegistrar;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
/**
|
||||
* 代理配置
|
||||
* @author: aoshiguchen
|
||||
* @date: 2022/10/8
|
||||
*/
|
||||
|
||||
public abstract class IProxyConfiguration {
|
||||
|
||||
public abstract IBeanHandler getBeanHandler();
|
||||
|
||||
public NioEventLoopGroup tunnelWorkGroup(ProxyConfig proxyConfig) {
|
||||
return new NioEventLoopGroup(proxyConfig.getTunnel().getThreadCount());
|
||||
}
|
||||
|
||||
public NioEventLoopGroup tcpRealServerWorkGroup(ProxyConfig proxyConfig) {
|
||||
// 暂时先公用此配置
|
||||
return new NioEventLoopGroup(proxyConfig.getTunnel().getThreadCount());
|
||||
}
|
||||
|
||||
public NioEventLoopGroup udpServerGroup(ProxyConfig proxyConfig) {
|
||||
// 暂时先公用此配置
|
||||
return new NioEventLoopGroup(proxyConfig.getClient().getUdp().getBossThreadCount());
|
||||
}
|
||||
|
||||
public NioEventLoopGroup udpWorkGroup(ProxyConfig proxyConfig) {
|
||||
// 暂时先公用此配置
|
||||
return new NioEventLoopGroup(proxyConfig.getClient().getUdp().getWorkThreadCount());
|
||||
}
|
||||
|
||||
public Bootstrap cmdTunnelBootstrap(ProxyConfig proxyConfig,
|
||||
NioEventLoopGroup tunnelWorkGroup) {
|
||||
Bootstrap bootstrap = new Bootstrap();
|
||||
bootstrap.group(tunnelWorkGroup);
|
||||
bootstrap.channel(NioSocketChannel.class);
|
||||
// bootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 3000);
|
||||
// bootstrap.option(ChannelOption.SO_KEEPALIVE, true);
|
||||
// /**
|
||||
// * TCP/IP协议中,无论发送多少数据,总是要在数据前面加上协议头,同时,对方接收到数据,也需要发送ACK表示确认。为了尽可能的利用网络带宽,TCP总是希望尽可能的发送足够大的数据。(一个连接会设置MSS参数,因此,TCP/IP希望每次都能够以MSS尺寸的数据块来发送数据)。
|
||||
// * Nagle算法就是为了尽可能发送大块数据,避免网络中充斥着许多小数据块。
|
||||
// */
|
||||
// bootstrap.option(ChannelOption.TCP_NODELAY, true);
|
||||
bootstrap.remoteAddress(InetSocketAddress.createUnresolved(proxyConfig.getTunnel().getServerIp(), proxyConfig.getTunnel().getServerPort()));
|
||||
|
||||
bootstrap.handler(new ChannelInitializer<SocketChannel>() {
|
||||
|
||||
@Override
|
||||
public void initChannel(SocketChannel ch) throws Exception {
|
||||
if (proxyConfig.getTunnel().getSslEnable()) {
|
||||
ch.pipeline().addLast(ProxyUtil.createSslHandler(proxyConfig));
|
||||
}
|
||||
if (null != proxyConfig.getTunnel().getTransferLogEnable() && proxyConfig.getTunnel().getTransferLogEnable()) {
|
||||
ch.pipeline().addFirst(new LoggingHandler(CmdChannelHandler.class));
|
||||
}
|
||||
ch.pipeline().addLast(new ProxyMessageDecoder(proxyConfig.getProtocol().getMaxFrameLength(),
|
||||
proxyConfig.getProtocol().getLengthFieldOffset(), proxyConfig.getProtocol().getLengthFieldLength(),
|
||||
proxyConfig.getProtocol().getLengthAdjustment(), proxyConfig.getProtocol().getInitialBytesToStrip()));
|
||||
ch.pipeline().addLast(new ProxyMessageEncoder());
|
||||
ch.pipeline().addLast(new IdleStateHandler(proxyConfig.getProtocol().getReadIdleTime(), proxyConfig.getProtocol().getWriteIdleTime(), proxyConfig.getProtocol().getAllIdleTimeSeconds()));
|
||||
ch.pipeline().addLast(new CmdChannelHandler(getBeanHandler()));
|
||||
}
|
||||
});
|
||||
return bootstrap;
|
||||
}
|
||||
|
||||
public Bootstrap tcpProxyTunnelBootstrap(ProxyConfig proxyConfig,
|
||||
NioEventLoopGroup tunnelWorkGroup) {
|
||||
Bootstrap bootstrap = new Bootstrap();
|
||||
bootstrap.group(tunnelWorkGroup);
|
||||
bootstrap.channel(NioSocketChannel.class);
|
||||
bootstrap.remoteAddress(InetSocketAddress.createUnresolved(proxyConfig.getTunnel().getServerIp(), proxyConfig.getTunnel().getServerPort()));
|
||||
bootstrap.handler(new ChannelInitializer<SocketChannel>() {
|
||||
|
||||
@Override
|
||||
public void initChannel(SocketChannel ch) throws Exception {
|
||||
if (proxyConfig.getTunnel().getSslEnable()) {
|
||||
ch.pipeline().addLast(ProxyUtil.createSslHandler(proxyConfig));
|
||||
}
|
||||
if (null != proxyConfig.getTunnel().getTransferLogEnable() && proxyConfig.getTunnel().getTransferLogEnable()) {
|
||||
ch.pipeline().addFirst(new LoggingHandler(TcpProxyChannelHandler.class));
|
||||
}
|
||||
ch.pipeline().addLast(new ProxyMessageDecoder(proxyConfig.getProtocol().getMaxFrameLength(),
|
||||
proxyConfig.getProtocol().getLengthFieldOffset(), proxyConfig.getProtocol().getLengthFieldLength(),
|
||||
proxyConfig.getProtocol().getLengthAdjustment(), proxyConfig.getProtocol().getInitialBytesToStrip()));
|
||||
ch.pipeline().addLast(new ProxyMessageEncoder());
|
||||
ch.pipeline().addLast(new IdleStateHandler(proxyConfig.getProtocol().getReadIdleTime(), proxyConfig.getProtocol().getWriteIdleTime(), proxyConfig.getProtocol().getAllIdleTimeSeconds()));
|
||||
ch.pipeline().addLast(new TcpProxyChannelHandler(getBeanHandler()));
|
||||
}
|
||||
});
|
||||
return bootstrap;
|
||||
}
|
||||
public Bootstrap udpProxyTunnelBootstrap(ProxyConfig proxyConfig,
|
||||
NioEventLoopGroup tunnelWorkGroup) {
|
||||
Bootstrap bootstrap = new Bootstrap();
|
||||
bootstrap.group(tunnelWorkGroup);
|
||||
bootstrap.channel(NioSocketChannel.class);
|
||||
bootstrap.remoteAddress(InetSocketAddress.createUnresolved(proxyConfig.getTunnel().getServerIp(), proxyConfig.getTunnel().getServerPort()));
|
||||
bootstrap.handler(new ChannelInitializer<SocketChannel>() {
|
||||
|
||||
@Override
|
||||
public void initChannel(SocketChannel ch) throws Exception {
|
||||
if (proxyConfig.getTunnel().getSslEnable()) {
|
||||
ch.pipeline().addLast(ProxyUtil.createSslHandler(proxyConfig));
|
||||
}
|
||||
if (null != proxyConfig.getTunnel().getTransferLogEnable() && proxyConfig.getTunnel().getTransferLogEnable()) {
|
||||
ch.pipeline().addFirst(new LoggingHandler(TcpProxyChannelHandler.class));
|
||||
}
|
||||
ch.pipeline().addLast(new ProxyMessageDecoder(proxyConfig.getProtocol().getMaxFrameLength(),
|
||||
proxyConfig.getProtocol().getLengthFieldOffset(), proxyConfig.getProtocol().getLengthFieldLength(),
|
||||
proxyConfig.getProtocol().getLengthAdjustment(), proxyConfig.getProtocol().getInitialBytesToStrip()));
|
||||
ch.pipeline().addLast(new ProxyMessageEncoder());
|
||||
ch.pipeline().addLast(new IdleStateHandler(proxyConfig.getProtocol().getReadIdleTime(), proxyConfig.getProtocol().getWriteIdleTime(), proxyConfig.getProtocol().getAllIdleTimeSeconds()));
|
||||
ch.pipeline().addLast(new UdpProxyChannelHandler(getBeanHandler()));
|
||||
}
|
||||
});
|
||||
return bootstrap;
|
||||
}
|
||||
|
||||
public Bootstrap realServerBootstrap(ProxyConfig proxyConfig,
|
||||
NioEventLoopGroup tcpRealServerWorkGroup
|
||||
) {
|
||||
Bootstrap bootstrap = new Bootstrap();
|
||||
bootstrap.group(tcpRealServerWorkGroup);
|
||||
bootstrap.channel(NioSocketChannel.class);
|
||||
bootstrap.handler(new ChannelInitializer<SocketChannel>() {
|
||||
|
||||
@Override
|
||||
public void initChannel(SocketChannel ch) throws Exception {
|
||||
if (null != proxyConfig.getTunnel().getTransferLogEnable() && proxyConfig.getTunnel().getTransferLogEnable()) {
|
||||
ch.pipeline().addFirst(new LoggingHandler(RealServerChannelHandler.class));
|
||||
}
|
||||
ch.pipeline().addLast(new RealServerChannelHandler());
|
||||
}
|
||||
});
|
||||
return bootstrap;
|
||||
}
|
||||
|
||||
public Bootstrap udpServerBootstrap(ProxyConfig proxyConfig,
|
||||
NioEventLoopGroup udpServerGroup,
|
||||
NioEventLoopGroup udpWorkGroup) {
|
||||
Bootstrap bootstrap = new Bootstrap();
|
||||
bootstrap.group(udpServerGroup)
|
||||
// 主线程处理
|
||||
.channel(NioDatagramChannel.class)
|
||||
// 广播
|
||||
.option(ChannelOption.SO_BROADCAST, true)
|
||||
// 设置读缓冲区为2M
|
||||
.option(ChannelOption.SO_RCVBUF, 2048 * 1024)
|
||||
// 设置写缓冲区为1M
|
||||
.option(ChannelOption.SO_SNDBUF, 1024 * 1024)
|
||||
.handler(new ChannelInitializer<NioDatagramChannel>() {
|
||||
@Override
|
||||
protected void initChannel(NioDatagramChannel ch) {
|
||||
ChannelPipeline pipeline = ch.pipeline();
|
||||
if (null != proxyConfig.getClient().getUdp().getTransferLogEnable() && proxyConfig.getClient().getUdp().getTransferLogEnable()) {
|
||||
ch.pipeline().addFirst(new LoggingHandler(UdpRealServerHandler.class));
|
||||
}
|
||||
pipeline.addLast(udpWorkGroup, new UdpRealServerHandler());
|
||||
}
|
||||
});
|
||||
return bootstrap;
|
||||
}
|
||||
|
||||
public NeutrinoCoreRuntimeNativeRegistrar neutrinoCoreRuntimeNativeRegistrar() {
|
||||
return new NeutrinoCoreRuntimeNativeRegistrar();
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package org.dromara.neutrinoproxy.client.config;
|
||||
package org.dromara.neutrinoproxy.client.sdk.config;
|
||||
|
||||
import org.noear.solon.annotation.Component;
|
||||
import org.noear.solon.aot.RuntimeNativeMetadata;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package org.dromara.neutrinoproxy.client.config;
|
||||
package org.dromara.neutrinoproxy.client.sdk.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.noear.solon.annotation.Component;
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
package org.dromara.neutrinoproxy.client.constant;
|
||||
package org.dromara.neutrinoproxy.client.sdk.constant;
|
||||
|
||||
import io.netty.util.AttributeKey;
|
||||
import org.dromara.neutrinoproxy.client.util.UdpChannelBindInfo;
|
||||
import org.dromara.neutrinoproxy.client.sdk.util.UdpChannelBindInfo;
|
||||
|
||||
/**
|
||||
* @author: aoshiguchen
|
||||
+13
-11
@@ -1,17 +1,16 @@
|
||||
package org.dromara.neutrinoproxy.client.core;
|
||||
package org.dromara.neutrinoproxy.client.sdk.core;
|
||||
|
||||
import org.dromara.neutrinoproxy.client.config.ProxyConfig;
|
||||
import org.dromara.neutrinoproxy.client.util.ProxyUtil;
|
||||
import org.dromara.neutrinoproxy.core.Constants;
|
||||
import org.dromara.neutrinoproxy.core.ProxyMessage;
|
||||
import org.dromara.neutrinoproxy.core.dispatcher.Dispatcher;
|
||||
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 lombok.extern.slf4j.Slf4j;
|
||||
import org.noear.solon.Solon;
|
||||
import org.dromara.neutrinoproxy.client.sdk.config.IBeanHandler;
|
||||
import org.dromara.neutrinoproxy.client.sdk.config.ProxyConfig;
|
||||
import org.dromara.neutrinoproxy.client.sdk.util.ProxyUtil;
|
||||
import org.dromara.neutrinoproxy.core.Constants;
|
||||
import org.dromara.neutrinoproxy.core.ProxyMessage;
|
||||
|
||||
/**
|
||||
* 处理与服务端之间的数据传输
|
||||
@@ -19,11 +18,13 @@ import org.noear.solon.Solon;
|
||||
* @date: 2022/6/16
|
||||
*/
|
||||
@Slf4j
|
||||
public class CmdChannelHandler extends SimpleChannelInboundHandler<ProxyMessage> {
|
||||
public class CmdChannelHandler extends SimpleChannelInboundHandler<ProxyMessage>{
|
||||
private static volatile Boolean transferLogEnable = Boolean.FALSE;
|
||||
private IBeanHandler beanHandler;
|
||||
|
||||
public CmdChannelHandler() {
|
||||
ProxyConfig proxyConfig = Solon.context().getBean(ProxyConfig.class);
|
||||
public CmdChannelHandler(IBeanHandler beanHandler) {
|
||||
this.beanHandler = beanHandler;
|
||||
ProxyConfig proxyConfig = beanHandler.getProxyConfig();
|
||||
if (null != proxyConfig.getClient() && null != proxyConfig.getTunnel().getHeartbeatLogEnable()) {
|
||||
transferLogEnable = proxyConfig.getTunnel().getHeartbeatLogEnable();
|
||||
}
|
||||
@@ -34,7 +35,7 @@ public class CmdChannelHandler extends SimpleChannelInboundHandler<ProxyMessage>
|
||||
if (ProxyMessage.TYPE_HEARTBEAT != proxyMessage.getType() || transferLogEnable) {
|
||||
log.debug("[CMD Channel]Client CmdChannel recieved proxy message, type is {}", proxyMessage.getType());
|
||||
}
|
||||
Solon.context().getBean(Dispatcher.class).dispatch(ctx, proxyMessage);
|
||||
beanHandler.getDispatcher().dispatch(ctx, proxyMessage);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -82,4 +83,5 @@ public class CmdChannelHandler extends SimpleChannelInboundHandler<ProxyMessage>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -19,7 +19,7 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
package org.dromara.neutrinoproxy.client.core;
|
||||
package org.dromara.neutrinoproxy.client.sdk.core;
|
||||
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
package org.dromara.neutrinoproxy.client.sdk.core;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelFutureListener;
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.neutrinoproxy.client.sdk.config.ProxyConfig;
|
||||
import org.dromara.neutrinoproxy.client.sdk.util.ProxyUtil;
|
||||
import org.dromara.neutrinoproxy.client.sdk.util.UdpServerUtil;
|
||||
import org.dromara.neutrinoproxy.core.ProxyMessage;
|
||||
import org.noear.solon.Solon;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
|
||||
/**
|
||||
* 代理客户端服务
|
||||
* @author: aoshiguchen
|
||||
* @date: 2022/6/16
|
||||
*/
|
||||
@Slf4j
|
||||
@Data
|
||||
public class IAbProxyClientService {
|
||||
|
||||
public ProxyConfig proxyConfig;
|
||||
|
||||
public Bootstrap cmdTunnelBootstrap;
|
||||
|
||||
public Bootstrap udpServerBootstrap;
|
||||
|
||||
private volatile Channel channel;
|
||||
/**
|
||||
* 重连次数
|
||||
*/
|
||||
private volatile int reconnectCount = 0;
|
||||
|
||||
/**
|
||||
* 重连服务执行器
|
||||
*/
|
||||
public static final ScheduledExecutorService reconnectExecutor = Executors.newSingleThreadScheduledExecutor(new CustomThreadFactory("ClientReconnect"));
|
||||
|
||||
public void init(){
|
||||
reconnectExecutor.scheduleWithFixedDelay(this::reconnect, 10, proxyConfig.getTunnel().getReconnection().getIntervalSeconds(), TimeUnit.SECONDS);
|
||||
try {
|
||||
this.start();
|
||||
UdpServerUtil.initCache(proxyConfig, udpServerBootstrap);
|
||||
} catch (Exception e) {
|
||||
// 启动连不上也做一下重连,因此先catch异常
|
||||
log.error("[CmdChannel] start error", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void start() {
|
||||
if (StrUtil.isEmpty(proxyConfig.getTunnel().getServerIp())) {
|
||||
log.error("not found server-ip config.");
|
||||
Solon.stop();
|
||||
return;
|
||||
}
|
||||
if (null == proxyConfig.getTunnel().getServerPort()) {
|
||||
log.error("not found server-port config.");
|
||||
Solon.stop();
|
||||
return;
|
||||
}
|
||||
if (null != proxyConfig.getTunnel().getSslEnable() && proxyConfig.getTunnel().getSslEnable()
|
||||
&& StrUtil.isEmpty(proxyConfig.getTunnel().getJksPath())) {
|
||||
log.error("not found jks-path config.");
|
||||
Solon.stop();
|
||||
return;
|
||||
}
|
||||
if (StrUtil.isEmpty(proxyConfig.getTunnel().getLicenseKey())) {
|
||||
log.error("not found license-key config.");
|
||||
Solon.stop();
|
||||
return;
|
||||
}
|
||||
if (null == channel || !channel.isActive()) {
|
||||
try {
|
||||
connectProxyServer();
|
||||
} catch (Exception e) {
|
||||
log.error("client start error", e);
|
||||
}
|
||||
} else {
|
||||
channel.writeAndFlush(ProxyMessage.buildAuthMessage(proxyConfig.getTunnel().getLicenseKey(), ProxyUtil.getClientId()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 连接代理服务器
|
||||
*/
|
||||
private void connectProxyServer() throws InterruptedException {
|
||||
cmdTunnelBootstrap.connect()
|
||||
.addListener(new ChannelFutureListener() {
|
||||
|
||||
@Override
|
||||
public void operationComplete(ChannelFuture future) throws Exception {
|
||||
if (future.isSuccess()) {
|
||||
channel = future.channel();
|
||||
// 连接成功,向服务器发送客户端认证信息(licenseKey)
|
||||
ProxyUtil.setCmdChannel(future.channel());
|
||||
future.channel().writeAndFlush(ProxyMessage.buildAuthMessage(proxyConfig.getTunnel().getLicenseKey(), ProxyUtil.getClientId()));
|
||||
log.info("[CmdChannel] connect proxy server success. channelId:{}", future.channel().id().asLongText());
|
||||
|
||||
// reconnectServiceEnable = true;
|
||||
reconnectCount = 0;
|
||||
} else {
|
||||
log.info("[CmdChannel] connect proxy server failed!");
|
||||
}
|
||||
}
|
||||
}).sync();
|
||||
}
|
||||
|
||||
protected synchronized void reconnect() {
|
||||
if (null != channel) {
|
||||
if (channel.isActive()) {
|
||||
return;
|
||||
}
|
||||
channel.close();
|
||||
}
|
||||
|
||||
log.info("[CmdChannel] client reconnect seq:{}", ++reconnectCount);
|
||||
try {
|
||||
connectProxyServer();
|
||||
} catch (Exception e) {
|
||||
log.error("[CmdChannel] reconnect error", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -20,7 +20,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package org.dromara.neutrinoproxy.client.core;
|
||||
package org.dromara.neutrinoproxy.client.sdk.core;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
|
||||
+2
-2
@@ -20,10 +20,10 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package org.dromara.neutrinoproxy.client.core;
|
||||
package org.dromara.neutrinoproxy.client.sdk.core;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.neutrinoproxy.client.util.ProxyUtil;
|
||||
import org.dromara.neutrinoproxy.client.sdk.util.ProxyUtil;
|
||||
import org.dromara.neutrinoproxy.core.Constants;
|
||||
import org.dromara.neutrinoproxy.core.ProxyMessage;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
+9
-4
@@ -1,4 +1,4 @@
|
||||
package org.dromara.neutrinoproxy.client.core;
|
||||
package org.dromara.neutrinoproxy.client.sdk.core;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
@@ -6,7 +6,9 @@ import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
import io.netty.handler.timeout.IdleStateEvent;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.neutrinoproxy.client.util.ProxyUtil;
|
||||
import org.dromara.neutrinoproxy.client.sdk.config.IBeanHandler;
|
||||
import org.dromara.neutrinoproxy.client.sdk.config.ProxyConfig;
|
||||
import org.dromara.neutrinoproxy.client.sdk.util.ProxyUtil;
|
||||
import org.dromara.neutrinoproxy.core.Constants;
|
||||
import org.dromara.neutrinoproxy.core.ProxyMessage;
|
||||
import org.dromara.neutrinoproxy.core.dispatcher.Dispatcher;
|
||||
@@ -20,13 +22,16 @@ import org.noear.solon.Solon;
|
||||
@Slf4j
|
||||
public class TcpProxyChannelHandler extends SimpleChannelInboundHandler<ProxyMessage> {
|
||||
|
||||
|
||||
private IBeanHandler beanHandler;
|
||||
public TcpProxyChannelHandler(IBeanHandler beanHandler) {
|
||||
this.beanHandler = beanHandler;
|
||||
}
|
||||
@Override
|
||||
protected void channelRead0(ChannelHandlerContext ctx, ProxyMessage proxyMessage) throws Exception {
|
||||
if (ProxyMessage.TYPE_HEARTBEAT != proxyMessage.getType()) {
|
||||
log.debug("[TCP Proxy Channel]Client ProxyChannel recieved proxy message, type is {}", proxyMessage.getType());
|
||||
}
|
||||
Solon.context().getBean(Dispatcher.class).dispatch(ctx, proxyMessage);
|
||||
beanHandler.getDispatcher().dispatch(ctx, proxyMessage);
|
||||
}
|
||||
|
||||
@Override
|
||||
+8
-4
@@ -1,4 +1,4 @@
|
||||
package org.dromara.neutrinoproxy.client.core;
|
||||
package org.dromara.neutrinoproxy.client.sdk.core;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
@@ -6,7 +6,8 @@ import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
import io.netty.handler.timeout.IdleStateEvent;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.neutrinoproxy.client.util.ProxyUtil;
|
||||
import org.dromara.neutrinoproxy.client.sdk.config.IBeanHandler;
|
||||
import org.dromara.neutrinoproxy.client.sdk.util.ProxyUtil;
|
||||
import org.dromara.neutrinoproxy.core.Constants;
|
||||
import org.dromara.neutrinoproxy.core.ProxyMessage;
|
||||
import org.dromara.neutrinoproxy.core.dispatcher.Dispatcher;
|
||||
@@ -20,13 +21,16 @@ import org.noear.solon.Solon;
|
||||
@Slf4j
|
||||
public class UdpProxyChannelHandler extends SimpleChannelInboundHandler<ProxyMessage> {
|
||||
|
||||
|
||||
private IBeanHandler beanHandler;
|
||||
public UdpProxyChannelHandler(IBeanHandler beanHandler) {
|
||||
this.beanHandler = beanHandler;
|
||||
}
|
||||
@Override
|
||||
protected void channelRead0(ChannelHandlerContext ctx, ProxyMessage proxyMessage) throws Exception {
|
||||
if (ProxyMessage.TYPE_HEARTBEAT != proxyMessage.getType()) {
|
||||
log.debug("[UDP Proxy Channel]Client ProxyChannel recieved proxy message, type is {}", proxyMessage.getType());
|
||||
}
|
||||
Solon.context().getBean(Dispatcher.class).dispatch(ctx, proxyMessage);
|
||||
beanHandler.getDispatcher().dispatch(ctx, proxyMessage);
|
||||
}
|
||||
|
||||
@Override
|
||||
+3
-3
@@ -1,11 +1,11 @@
|
||||
package org.dromara.neutrinoproxy.client.core;
|
||||
package org.dromara.neutrinoproxy.client.sdk.core;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
import io.netty.channel.socket.DatagramPacket;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.neutrinoproxy.client.constant.Constants;
|
||||
import org.dromara.neutrinoproxy.client.util.UdpChannelBindInfo;
|
||||
import org.dromara.neutrinoproxy.client.sdk.constant.Constants;
|
||||
import org.dromara.neutrinoproxy.client.sdk.util.UdpChannelBindInfo;
|
||||
import org.dromara.neutrinoproxy.core.ProxyMessage;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
+6
-6
@@ -1,8 +1,8 @@
|
||||
package org.dromara.neutrinoproxy.client.handler;
|
||||
package org.dromara.neutrinoproxy.client.sdk.handler;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.neutrinoproxy.client.config.ProxyConfig;
|
||||
import org.dromara.neutrinoproxy.client.sdk.config.ProxyConfig;
|
||||
import org.dromara.neutrinoproxy.core.Constants;
|
||||
import org.dromara.neutrinoproxy.core.ExceptionEnum;
|
||||
import org.dromara.neutrinoproxy.core.ProxyMessage;
|
||||
@@ -10,8 +10,6 @@ import org.dromara.neutrinoproxy.core.ProxyMessageHandler;
|
||||
import org.dromara.neutrinoproxy.core.dispatcher.Match;
|
||||
import org.noear.snack.ONode;
|
||||
import org.noear.solon.Solon;
|
||||
import org.noear.solon.annotation.Component;
|
||||
import org.noear.solon.annotation.Inject;
|
||||
|
||||
/**
|
||||
* 认证信息处理器
|
||||
@@ -20,10 +18,12 @@ import org.noear.solon.annotation.Inject;
|
||||
*/
|
||||
@Slf4j
|
||||
@Match(type = Constants.ProxyDataTypeName.AUTH)
|
||||
@Component
|
||||
public class ProxyMessageAuthHandler implements ProxyMessageHandler {
|
||||
@Inject
|
||||
private ProxyConfig proxyConfig;
|
||||
|
||||
public ProxyMessageAuthHandler(ProxyConfig proxyConfig){
|
||||
this.proxyConfig=proxyConfig;
|
||||
}
|
||||
@Override
|
||||
public void handle(ChannelHandlerContext context, ProxyMessage proxyMessage) {
|
||||
String info = proxyMessage.getInfo();
|
||||
+16
-12
@@ -1,33 +1,36 @@
|
||||
package org.dromara.neutrinoproxy.client.handler;
|
||||
package org.dromara.neutrinoproxy.client.sdk.handler;
|
||||
|
||||
import org.dromara.neutrinoproxy.client.config.ProxyConfig;
|
||||
import org.dromara.neutrinoproxy.client.core.ProxyChannelBorrowListener;
|
||||
import org.dromara.neutrinoproxy.client.util.ProxyUtil;
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.channel.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.neutrinoproxy.client.sdk.config.ProxyConfig;
|
||||
import org.dromara.neutrinoproxy.client.sdk.core.ProxyChannelBorrowListener;
|
||||
import org.dromara.neutrinoproxy.client.sdk.util.ProxyUtil;
|
||||
import org.dromara.neutrinoproxy.core.Constants;
|
||||
import org.dromara.neutrinoproxy.core.ProxyDataTypeEnum;
|
||||
import org.dromara.neutrinoproxy.core.ProxyMessage;
|
||||
import org.dromara.neutrinoproxy.core.ProxyMessageHandler;
|
||||
import org.dromara.neutrinoproxy.core.dispatcher.Match;
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.channel.*;
|
||||
import org.noear.solon.annotation.Component;
|
||||
import org.noear.solon.annotation.Inject;
|
||||
|
||||
/**
|
||||
* 连接信息处理器
|
||||
* @author: aoshiguchen
|
||||
* @date: 2022/6/16
|
||||
*/
|
||||
@Slf4j
|
||||
@Match(type = Constants.ProxyDataTypeName.CONNECT)
|
||||
@Component
|
||||
public class ProxyMessageConnectHandler implements ProxyMessageHandler {
|
||||
@Inject("tcpProxyTunnelBootstrap")
|
||||
|
||||
private Bootstrap tcpProxyTunnelBootstrap;
|
||||
@Inject("realServerBootstrap")
|
||||
private Bootstrap realServerBootstrap;
|
||||
@Inject
|
||||
private ProxyConfig proxyConfig;
|
||||
|
||||
public ProxyMessageConnectHandler(Bootstrap tcpProxyTunnelBootstrap,Bootstrap realServerBootstrap,ProxyConfig proxyConfig){
|
||||
this.proxyConfig=proxyConfig;
|
||||
this.realServerBootstrap=realServerBootstrap;
|
||||
this.tcpProxyTunnelBootstrap=tcpProxyTunnelBootstrap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(ChannelHandlerContext ctx, ProxyMessage proxyMessage) {
|
||||
final Channel cmdChannel = ctx.channel();
|
||||
@@ -84,4 +87,5 @@ public class ProxyMessageConnectHandler implements ProxyMessageHandler {
|
||||
public String name() {
|
||||
return ProxyDataTypeEnum.CONNECT.getDesc();
|
||||
}
|
||||
|
||||
}
|
||||
+8
-8
@@ -1,24 +1,24 @@
|
||||
package org.dromara.neutrinoproxy.client.handler;
|
||||
package org.dromara.neutrinoproxy.client.sdk.handler;
|
||||
|
||||
import org.dromara.neutrinoproxy.client.util.ProxyUtil;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFutureListener;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.neutrinoproxy.client.sdk.util.ProxyUtil;
|
||||
import org.dromara.neutrinoproxy.core.Constants;
|
||||
import org.dromara.neutrinoproxy.core.ProxyDataTypeEnum;
|
||||
import org.dromara.neutrinoproxy.core.ProxyMessage;
|
||||
import org.dromara.neutrinoproxy.core.ProxyMessageHandler;
|
||||
import org.dromara.neutrinoproxy.core.dispatcher.Match;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFutureListener;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import org.noear.solon.annotation.Component;
|
||||
|
||||
/**
|
||||
* 断开连接信息处理器
|
||||
* @author: aoshiguchen
|
||||
* @date: 2022/6/16
|
||||
*/
|
||||
@Slf4j
|
||||
@Match(type = Constants.ProxyDataTypeName.DISCONNECT)
|
||||
@Component
|
||||
public class ProxyMessageDisconnectHandler implements ProxyMessageHandler {
|
||||
|
||||
@Override
|
||||
+3
-8
@@ -1,15 +1,10 @@
|
||||
package org.dromara.neutrinoproxy.client.handler;
|
||||
package org.dromara.neutrinoproxy.client.sdk.handler;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.neutrinoproxy.core.Constants;
|
||||
import org.dromara.neutrinoproxy.core.ExceptionEnum;
|
||||
import org.dromara.neutrinoproxy.core.ProxyDataTypeEnum;
|
||||
import org.dromara.neutrinoproxy.core.ProxyMessage;
|
||||
import org.dromara.neutrinoproxy.core.ProxyMessageHandler;
|
||||
import org.dromara.neutrinoproxy.core.*;
|
||||
import org.dromara.neutrinoproxy.core.dispatcher.Match;
|
||||
import org.noear.snack.ONode;
|
||||
import org.noear.solon.annotation.Component;
|
||||
|
||||
/**
|
||||
* 异常信息处理器
|
||||
@@ -18,7 +13,6 @@ import org.noear.solon.annotation.Component;
|
||||
*/
|
||||
@Slf4j
|
||||
@Match(type = Constants.ProxyDataTypeName.ERROR)
|
||||
@Component
|
||||
public class ProxyMessageErrorHandler implements ProxyMessageHandler {
|
||||
|
||||
@Override
|
||||
@@ -35,4 +29,5 @@ public class ProxyMessageErrorHandler implements ProxyMessageHandler {
|
||||
public String name() {
|
||||
return ProxyDataTypeEnum.DISCONNECT.getDesc();
|
||||
}
|
||||
|
||||
}
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
package org.dromara.neutrinoproxy.client.sdk.handler;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import org.dromara.neutrinoproxy.client.sdk.config.IProxyConfiguration;
|
||||
import org.dromara.neutrinoproxy.client.sdk.config.ProxyConfig;
|
||||
import org.dromara.neutrinoproxy.client.sdk.core.IAbProxyClientService;
|
||||
import org.dromara.neutrinoproxy.core.ProxyDataTypeEnum;
|
||||
import org.dromara.neutrinoproxy.core.ProxyMessage;
|
||||
import org.dromara.neutrinoproxy.core.ProxyMessageHandler;
|
||||
import org.dromara.neutrinoproxy.core.aot.NeutrinoCoreRuntimeNativeRegistrar;
|
||||
import org.dromara.neutrinoproxy.core.dispatcher.DefaultDispatcher;
|
||||
import org.dromara.neutrinoproxy.core.dispatcher.Dispatcher;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author: gc.x
|
||||
* @date: 2024/1/21
|
||||
*/
|
||||
public abstract class ProxyMessageFactory extends IProxyConfiguration {
|
||||
|
||||
public abstract void beanInject(String beanName, Object t);
|
||||
public abstract Object getBean(String beanName);
|
||||
|
||||
public void start(ProxyConfig proxyConfig){
|
||||
init(proxyConfig);
|
||||
IAbProxyClientService clientService=new IAbProxyClientService();
|
||||
clientService.setProxyConfig(proxyConfig);
|
||||
clientService.setCmdTunnelBootstrap((Bootstrap) getBean("cmdTunnelBootstrap"));
|
||||
clientService.setUdpServerBootstrap((Bootstrap) getBean("udpServerBootstrap"));
|
||||
clientService.init();
|
||||
}
|
||||
|
||||
public void init(ProxyConfig proxyConfig){
|
||||
NioEventLoopGroup tunnelWorkGroup = super.tunnelWorkGroup(proxyConfig);
|
||||
beanInject("tunnelWorkGroup",tunnelWorkGroup);
|
||||
NioEventLoopGroup tcpRealServerWorkGroup = super.tcpRealServerWorkGroup(proxyConfig);
|
||||
beanInject("tcpRealServerWorkGroup",tcpRealServerWorkGroup);
|
||||
NioEventLoopGroup udpServerGroup = super.udpServerGroup(proxyConfig);
|
||||
beanInject("udpServerGroup",udpServerGroup);
|
||||
NioEventLoopGroup udpWorkGroup = super.udpWorkGroup(proxyConfig);
|
||||
beanInject("udpWorkGroup",udpWorkGroup);
|
||||
Bootstrap cmdTunnelBootstrap = super.cmdTunnelBootstrap(proxyConfig, tunnelWorkGroup);
|
||||
beanInject("cmdTunnelBootstrap",cmdTunnelBootstrap);
|
||||
Bootstrap tcpProxyTunnelBootstrap = super.tcpProxyTunnelBootstrap(proxyConfig, tunnelWorkGroup);
|
||||
beanInject("tcpProxyTunnelBootstrap",tcpProxyTunnelBootstrap);
|
||||
Bootstrap udpProxyTunnelBootstrap = super.udpProxyTunnelBootstrap(proxyConfig, tunnelWorkGroup);
|
||||
beanInject("udpProxyTunnelBootstrap",udpProxyTunnelBootstrap);
|
||||
Bootstrap realServerBootstrap = super.realServerBootstrap(proxyConfig, tcpRealServerWorkGroup);
|
||||
beanInject("realServerBootstrap",realServerBootstrap);
|
||||
Bootstrap udpServerBootstrap = super.udpServerBootstrap(proxyConfig, udpServerGroup, udpWorkGroup);
|
||||
beanInject("udpServerBootstrap",udpServerBootstrap);
|
||||
NeutrinoCoreRuntimeNativeRegistrar neutrinoCoreRuntimeNativeRegistrar = super.neutrinoCoreRuntimeNativeRegistrar();
|
||||
beanInject("neutrinoCoreRuntimeNativeRegistrar",neutrinoCoreRuntimeNativeRegistrar);
|
||||
dispatcher(proxyConfig, tcpProxyTunnelBootstrap, realServerBootstrap);
|
||||
}
|
||||
public void dispatcher(ProxyConfig proxyConfig, Bootstrap tcpProxyTunnelBootstrap, Bootstrap realServerBootstrap) {
|
||||
List<ProxyMessageHandler> list = Lists.newArrayList(
|
||||
new ProxyMessageAuthHandler(proxyConfig),
|
||||
new ProxyMessageConnectHandler(tcpProxyTunnelBootstrap,realServerBootstrap,proxyConfig),
|
||||
new ProxyMessageDisconnectHandler(),
|
||||
new ProxyMessageErrorHandler(),
|
||||
new ProxyMessageTransferHandler(),
|
||||
new UdpProxyMessageConnectHandler(proxyConfig,tcpProxyTunnelBootstrap),
|
||||
new UdpProxyMessageTransferHandler()
|
||||
);
|
||||
Dispatcher<ChannelHandlerContext, ProxyMessage> dispatcher = new DefaultDispatcher<>("MessageDispatcher", list,
|
||||
proxyMessage -> ProxyDataTypeEnum.of((int)proxyMessage.getType()) == null ?
|
||||
null : ProxyDataTypeEnum.of((int)proxyMessage.getType()).getName());
|
||||
beanInject("dispatcher",dispatcher);
|
||||
}
|
||||
}
|
||||
+6
-6
@@ -1,14 +1,14 @@
|
||||
package org.dromara.neutrinoproxy.client.handler;
|
||||
package org.dromara.neutrinoproxy.client.sdk.handler;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.neutrinoproxy.core.Constants;
|
||||
import org.dromara.neutrinoproxy.core.ProxyDataTypeEnum;
|
||||
import org.dromara.neutrinoproxy.core.ProxyMessage;
|
||||
import org.dromara.neutrinoproxy.core.ProxyMessageHandler;
|
||||
import org.dromara.neutrinoproxy.core.dispatcher.Match;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import org.noear.solon.annotation.Component;
|
||||
|
||||
/**
|
||||
* 传输信息处理器
|
||||
@@ -16,7 +16,7 @@ import org.noear.solon.annotation.Component;
|
||||
* @date: 2022/6/16
|
||||
*/
|
||||
@Match(type = Constants.ProxyDataTypeName.TRANSFER)
|
||||
@Component
|
||||
@Slf4j
|
||||
public class ProxyMessageTransferHandler implements ProxyMessageHandler {
|
||||
|
||||
@Override
|
||||
+11
-9
@@ -1,20 +1,18 @@
|
||||
package org.dromara.neutrinoproxy.client.handler;
|
||||
package org.dromara.neutrinoproxy.client.sdk.handler;
|
||||
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.neutrinoproxy.client.config.ProxyConfig;
|
||||
import org.dromara.neutrinoproxy.client.core.ProxyChannelBorrowListener;
|
||||
import org.dromara.neutrinoproxy.client.util.ProxyUtil;
|
||||
import org.dromara.neutrinoproxy.client.sdk.config.ProxyConfig;
|
||||
import org.dromara.neutrinoproxy.client.sdk.core.ProxyChannelBorrowListener;
|
||||
import org.dromara.neutrinoproxy.client.sdk.util.ProxyUtil;
|
||||
import org.dromara.neutrinoproxy.core.Constants;
|
||||
import org.dromara.neutrinoproxy.core.ProxyDataTypeEnum;
|
||||
import org.dromara.neutrinoproxy.core.ProxyMessage;
|
||||
import org.dromara.neutrinoproxy.core.ProxyMessageHandler;
|
||||
import org.dromara.neutrinoproxy.core.dispatcher.Match;
|
||||
import org.noear.snack.ONode;
|
||||
import org.noear.solon.annotation.Component;
|
||||
import org.noear.solon.annotation.Inject;
|
||||
|
||||
/**
|
||||
* @author: aoshiguchen
|
||||
@@ -22,13 +20,16 @@ import org.noear.solon.annotation.Inject;
|
||||
*/
|
||||
@Slf4j
|
||||
@Match(type = Constants.ProxyDataTypeName.UDP_CONNECT)
|
||||
@Component
|
||||
public class UdpProxyMessageConnectHandler implements ProxyMessageHandler {
|
||||
@Inject
|
||||
|
||||
private ProxyConfig proxyConfig;
|
||||
@Inject("udpProxyTunnelBootstrap")
|
||||
private Bootstrap udpProxyTunnelBootstrap;
|
||||
|
||||
public UdpProxyMessageConnectHandler(ProxyConfig proxyConfig,Bootstrap udpProxyTunnelBootstrap){
|
||||
this.proxyConfig=proxyConfig;
|
||||
this.udpProxyTunnelBootstrap=udpProxyTunnelBootstrap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(ChannelHandlerContext ctx, ProxyMessage proxyMessage) {
|
||||
final Channel cmdChannel = ctx.channel();
|
||||
@@ -61,4 +62,5 @@ public class UdpProxyMessageConnectHandler implements ProxyMessageHandler {
|
||||
public String name() {
|
||||
return ProxyDataTypeEnum.UDP_CONNECT.getDesc();
|
||||
}
|
||||
|
||||
}
|
||||
+3
-4
@@ -1,4 +1,4 @@
|
||||
package org.dromara.neutrinoproxy.client.handler;
|
||||
package org.dromara.neutrinoproxy.client.sdk.handler;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
@@ -6,14 +6,13 @@ import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.socket.DatagramPacket;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.neutrinoproxy.client.util.UdpServerUtil;
|
||||
import org.dromara.neutrinoproxy.client.sdk.util.UdpServerUtil;
|
||||
import org.dromara.neutrinoproxy.core.Constants;
|
||||
import org.dromara.neutrinoproxy.core.ProxyDataTypeEnum;
|
||||
import org.dromara.neutrinoproxy.core.ProxyMessage;
|
||||
import org.dromara.neutrinoproxy.core.ProxyMessageHandler;
|
||||
import org.dromara.neutrinoproxy.core.dispatcher.Match;
|
||||
import org.noear.snack.ONode;
|
||||
import org.noear.solon.annotation.Component;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
@@ -23,7 +22,6 @@ import java.net.InetSocketAddress;
|
||||
*/
|
||||
@Slf4j
|
||||
@Match(type = Constants.ProxyDataTypeName.UDP_TRANSFER)
|
||||
@Component
|
||||
public class UdpProxyMessageTransferHandler implements ProxyMessageHandler {
|
||||
|
||||
@Override
|
||||
@@ -45,4 +43,5 @@ public class UdpProxyMessageTransferHandler implements ProxyMessageHandler {
|
||||
public String name() {
|
||||
return ProxyDataTypeEnum.UDP_TRANSFER.getDesc();
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package org.dromara.neutrinoproxy.client.util;
|
||||
package org.dromara.neutrinoproxy.client.sdk.util;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import lombok.Data;
|
||||
+3
-3
@@ -19,14 +19,14 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
package org.dromara.neutrinoproxy.client.util;
|
||||
package org.dromara.neutrinoproxy.client.sdk.util;
|
||||
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.handler.ssl.SslHandler;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.dromara.neutrinoproxy.client.config.ProxyConfig;
|
||||
import org.dromara.neutrinoproxy.client.core.ProxyChannelBorrowListener;
|
||||
import org.dromara.neutrinoproxy.client.sdk.config.ProxyConfig;
|
||||
import org.dromara.neutrinoproxy.client.sdk.core.ProxyChannelBorrowListener;
|
||||
import org.dromara.neutrinoproxy.core.Constants;
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.buffer.Unpooled;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package org.dromara.neutrinoproxy.client.util;
|
||||
package org.dromara.neutrinoproxy.client.sdk.util;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import lombok.Data;
|
||||
+4
-4
@@ -1,4 +1,4 @@
|
||||
package org.dromara.neutrinoproxy.client.util;
|
||||
package org.dromara.neutrinoproxy.client.sdk.util;
|
||||
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.buffer.Unpooled;
|
||||
@@ -7,9 +7,9 @@ import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelFutureListener;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.dromara.neutrinoproxy.client.config.ProxyConfig;
|
||||
import org.dromara.neutrinoproxy.client.constant.Constants;
|
||||
import org.dromara.neutrinoproxy.client.core.CustomThreadFactory;
|
||||
import org.dromara.neutrinoproxy.client.sdk.config.ProxyConfig;
|
||||
import org.dromara.neutrinoproxy.client.sdk.constant.Constants;
|
||||
import org.dromara.neutrinoproxy.client.sdk.core.CustomThreadFactory;
|
||||
import org.dromara.neutrinoproxy.core.ProxyMessage;
|
||||
import org.noear.solon.core.runtime.NativeDetector;
|
||||
|
||||
@@ -16,13 +16,9 @@
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.dromara.neutrino-proxy</groupId>
|
||||
<artifactId>neutrino-proxy-core</artifactId>
|
||||
<artifactId>neutrino-proxy-client-sdk</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.noear</groupId>
|
||||
<artifactId>solon-lib</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
+17
-194
@@ -1,30 +1,11 @@
|
||||
package org.dromara.neutrinoproxy.client.config;
|
||||
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
import io.netty.channel.socket.nio.NioDatagramChannel;
|
||||
import io.netty.channel.socket.nio.NioSocketChannel;
|
||||
import io.netty.handler.logging.LoggingHandler;
|
||||
import io.netty.handler.timeout.IdleStateHandler;
|
||||
import org.dromara.neutrinoproxy.client.core.*;
|
||||
import org.dromara.neutrinoproxy.client.util.ProxyUtil;
|
||||
import org.dromara.neutrinoproxy.core.*;
|
||||
import org.dromara.neutrinoproxy.core.aot.NeutrinoCoreRuntimeNativeRegistrar;
|
||||
import org.dromara.neutrinoproxy.core.dispatcher.DefaultDispatcher;
|
||||
import org.dromara.neutrinoproxy.core.dispatcher.Dispatcher;
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import org.dromara.neutrinoproxy.client.handler.BeanHandler;
|
||||
import org.dromara.neutrinoproxy.client.sdk.config.IBeanHandler;
|
||||
import org.dromara.neutrinoproxy.client.sdk.handler.ProxyMessageFactory;
|
||||
import org.noear.solon.Solon;
|
||||
import org.noear.solon.annotation.Bean;
|
||||
import org.noear.solon.annotation.Configuration;
|
||||
import org.noear.solon.annotation.Inject;
|
||||
import org.noear.solon.core.bean.LifecycleBean;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.List;
|
||||
import org.noear.solon.core.BeanWrap;
|
||||
|
||||
/**
|
||||
* 代理配置
|
||||
@@ -32,182 +13,24 @@ import java.util.List;
|
||||
* @date: 2022/10/8
|
||||
*/
|
||||
@Configuration
|
||||
public class ProxyConfiguration implements LifecycleBean {
|
||||
public class ProxyConfiguration extends ProxyMessageFactory {
|
||||
|
||||
|
||||
@Override
|
||||
public void start() throws Throwable {
|
||||
List<ProxyMessageHandler> list = Solon.context().getBeansOfType(ProxyMessageHandler.class);
|
||||
Dispatcher<ChannelHandlerContext, ProxyMessage> dispatcher = new DefaultDispatcher<>("MessageDispatcher", list,
|
||||
proxyMessage -> ProxyDataTypeEnum.of((int)proxyMessage.getType()) == null ?
|
||||
null : ProxyDataTypeEnum.of((int)proxyMessage.getType()).getName());
|
||||
Solon.context().wrapAndPut(Dispatcher.class, dispatcher);
|
||||
public IBeanHandler getBeanHandler() {
|
||||
return new BeanHandler();
|
||||
}
|
||||
|
||||
@Bean("tunnelWorkGroup")
|
||||
public NioEventLoopGroup tunnelWorkGroup(@Inject ProxyConfig proxyConfig) {
|
||||
return new NioEventLoopGroup(proxyConfig.getTunnel().getThreadCount());
|
||||
@Override
|
||||
public void beanInject(String beanName, Object bean) {
|
||||
//包装Bean(指定名字的)
|
||||
BeanWrap beanWrap = Solon.context().wrap(beanName, bean);
|
||||
//以名字注册
|
||||
Solon.context().putWrap(beanName, beanWrap);
|
||||
}
|
||||
|
||||
@Bean("tcpRealServerWorkGroup")
|
||||
public NioEventLoopGroup tcpRealServerWorkGroup(@Inject ProxyConfig proxyConfig) {
|
||||
// 暂时先公用此配置
|
||||
return new NioEventLoopGroup(proxyConfig.getTunnel().getThreadCount());
|
||||
@Override
|
||||
public Object getBean(String beanName) {
|
||||
return Solon.context().getBean(beanName);
|
||||
}
|
||||
|
||||
@Bean("udpServerGroup")
|
||||
public NioEventLoopGroup udpServerGroup(@Inject ProxyConfig proxyConfig) {
|
||||
// 暂时先公用此配置
|
||||
return new NioEventLoopGroup(proxyConfig.getClient().getUdp().getBossThreadCount());
|
||||
}
|
||||
|
||||
@Bean("udpWorkGroup")
|
||||
public NioEventLoopGroup udpWorkGroup(@Inject ProxyConfig proxyConfig) {
|
||||
// 暂时先公用此配置
|
||||
return new NioEventLoopGroup(proxyConfig.getClient().getUdp().getWorkThreadCount());
|
||||
}
|
||||
|
||||
@Bean("cmdTunnelBootstrap")
|
||||
public Bootstrap cmdTunnelBootstrap(@Inject ProxyConfig proxyConfig,
|
||||
@Inject("tunnelWorkGroup") NioEventLoopGroup tunnelWorkGroup) {
|
||||
Bootstrap bootstrap = new Bootstrap();
|
||||
bootstrap.group(tunnelWorkGroup);
|
||||
bootstrap.channel(NioSocketChannel.class);
|
||||
// bootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 3000);
|
||||
// bootstrap.option(ChannelOption.SO_KEEPALIVE, true);
|
||||
// /**
|
||||
// * TCP/IP协议中,无论发送多少数据,总是要在数据前面加上协议头,同时,对方接收到数据,也需要发送ACK表示确认。为了尽可能的利用网络带宽,TCP总是希望尽可能的发送足够大的数据。(一个连接会设置MSS参数,因此,TCP/IP希望每次都能够以MSS尺寸的数据块来发送数据)。
|
||||
// * Nagle算法就是为了尽可能发送大块数据,避免网络中充斥着许多小数据块。
|
||||
// */
|
||||
// bootstrap.option(ChannelOption.TCP_NODELAY, true);
|
||||
bootstrap.remoteAddress(InetSocketAddress.createUnresolved(proxyConfig.getTunnel().getServerIp(), proxyConfig.getTunnel().getServerPort()));
|
||||
|
||||
bootstrap.handler(new ChannelInitializer<SocketChannel>() {
|
||||
|
||||
@Override
|
||||
public void initChannel(SocketChannel ch) throws Exception {
|
||||
if (proxyConfig.getTunnel().getSslEnable()) {
|
||||
ch.pipeline().addLast(ProxyUtil.createSslHandler(proxyConfig));
|
||||
}
|
||||
if (null != proxyConfig.getTunnel().getTransferLogEnable() && proxyConfig.getTunnel().getTransferLogEnable()) {
|
||||
ch.pipeline().addFirst(new LoggingHandler(CmdChannelHandler.class));
|
||||
}
|
||||
ch.pipeline().addLast(new ProxyMessageDecoder(proxyConfig.getProtocol().getMaxFrameLength(),
|
||||
proxyConfig.getProtocol().getLengthFieldOffset(), proxyConfig.getProtocol().getLengthFieldLength(),
|
||||
proxyConfig.getProtocol().getLengthAdjustment(), proxyConfig.getProtocol().getInitialBytesToStrip()));
|
||||
ch.pipeline().addLast(new ProxyMessageEncoder());
|
||||
ch.pipeline().addLast(new IdleStateHandler(proxyConfig.getProtocol().getReadIdleTime(), proxyConfig.getProtocol().getWriteIdleTime(), proxyConfig.getProtocol().getAllIdleTimeSeconds()));
|
||||
ch.pipeline().addLast(new CmdChannelHandler());
|
||||
}
|
||||
});
|
||||
return bootstrap;
|
||||
}
|
||||
|
||||
@Bean("tcpProxyTunnelBootstrap")
|
||||
public Bootstrap tcpProxyTunnelBootstrap(@Inject ProxyConfig proxyConfig,
|
||||
@Inject("tunnelWorkGroup") NioEventLoopGroup tunnelWorkGroup) {
|
||||
Bootstrap bootstrap = new Bootstrap();
|
||||
bootstrap.group(tunnelWorkGroup);
|
||||
bootstrap.channel(NioSocketChannel.class);
|
||||
bootstrap.remoteAddress(InetSocketAddress.createUnresolved(proxyConfig.getTunnel().getServerIp(), proxyConfig.getTunnel().getServerPort()));
|
||||
bootstrap.handler(new ChannelInitializer<SocketChannel>() {
|
||||
|
||||
@Override
|
||||
public void initChannel(SocketChannel ch) throws Exception {
|
||||
if (proxyConfig.getTunnel().getSslEnable()) {
|
||||
ch.pipeline().addLast(ProxyUtil.createSslHandler(proxyConfig));
|
||||
}
|
||||
if (null != proxyConfig.getTunnel().getTransferLogEnable() && proxyConfig.getTunnel().getTransferLogEnable()) {
|
||||
ch.pipeline().addFirst(new LoggingHandler(TcpProxyChannelHandler.class));
|
||||
}
|
||||
ch.pipeline().addLast(new ProxyMessageDecoder(proxyConfig.getProtocol().getMaxFrameLength(),
|
||||
proxyConfig.getProtocol().getLengthFieldOffset(), proxyConfig.getProtocol().getLengthFieldLength(),
|
||||
proxyConfig.getProtocol().getLengthAdjustment(), proxyConfig.getProtocol().getInitialBytesToStrip()));
|
||||
ch.pipeline().addLast(new ProxyMessageEncoder());
|
||||
ch.pipeline().addLast(new IdleStateHandler(proxyConfig.getProtocol().getReadIdleTime(), proxyConfig.getProtocol().getWriteIdleTime(), proxyConfig.getProtocol().getAllIdleTimeSeconds()));
|
||||
ch.pipeline().addLast(new TcpProxyChannelHandler());
|
||||
}
|
||||
});
|
||||
return bootstrap;
|
||||
}
|
||||
|
||||
@Bean("udpProxyTunnelBootstrap")
|
||||
public Bootstrap udpProxyTunnelBootstrap(@Inject ProxyConfig proxyConfig,
|
||||
@Inject("tunnelWorkGroup") NioEventLoopGroup tunnelWorkGroup) {
|
||||
Bootstrap bootstrap = new Bootstrap();
|
||||
bootstrap.group(tunnelWorkGroup);
|
||||
bootstrap.channel(NioSocketChannel.class);
|
||||
bootstrap.remoteAddress(InetSocketAddress.createUnresolved(proxyConfig.getTunnel().getServerIp(), proxyConfig.getTunnel().getServerPort()));
|
||||
bootstrap.handler(new ChannelInitializer<SocketChannel>() {
|
||||
|
||||
@Override
|
||||
public void initChannel(SocketChannel ch) throws Exception {
|
||||
if (proxyConfig.getTunnel().getSslEnable()) {
|
||||
ch.pipeline().addLast(ProxyUtil.createSslHandler(proxyConfig));
|
||||
}
|
||||
if (null != proxyConfig.getTunnel().getTransferLogEnable() && proxyConfig.getTunnel().getTransferLogEnable()) {
|
||||
ch.pipeline().addFirst(new LoggingHandler(TcpProxyChannelHandler.class));
|
||||
}
|
||||
ch.pipeline().addLast(new ProxyMessageDecoder(proxyConfig.getProtocol().getMaxFrameLength(),
|
||||
proxyConfig.getProtocol().getLengthFieldOffset(), proxyConfig.getProtocol().getLengthFieldLength(),
|
||||
proxyConfig.getProtocol().getLengthAdjustment(), proxyConfig.getProtocol().getInitialBytesToStrip()));
|
||||
ch.pipeline().addLast(new ProxyMessageEncoder());
|
||||
ch.pipeline().addLast(new IdleStateHandler(proxyConfig.getProtocol().getReadIdleTime(), proxyConfig.getProtocol().getWriteIdleTime(), proxyConfig.getProtocol().getAllIdleTimeSeconds()));
|
||||
ch.pipeline().addLast(new UdpProxyChannelHandler());
|
||||
}
|
||||
});
|
||||
return bootstrap;
|
||||
}
|
||||
|
||||
@Bean("realServerBootstrap")
|
||||
public Bootstrap realServerBootstrap(@Inject ProxyConfig proxyConfig,
|
||||
@Inject("tcpRealServerWorkGroup") NioEventLoopGroup tcpRealServerWorkGroup
|
||||
) {
|
||||
Bootstrap bootstrap = new Bootstrap();
|
||||
bootstrap.group(tcpRealServerWorkGroup);
|
||||
bootstrap.channel(NioSocketChannel.class);
|
||||
bootstrap.handler(new ChannelInitializer<SocketChannel>() {
|
||||
|
||||
@Override
|
||||
public void initChannel(SocketChannel ch) throws Exception {
|
||||
if (null != proxyConfig.getTunnel().getTransferLogEnable() && proxyConfig.getTunnel().getTransferLogEnable()) {
|
||||
ch.pipeline().addFirst(new LoggingHandler(RealServerChannelHandler.class));
|
||||
}
|
||||
ch.pipeline().addLast(new RealServerChannelHandler());
|
||||
}
|
||||
});
|
||||
return bootstrap;
|
||||
}
|
||||
|
||||
@Bean("udpServerBootstrap")
|
||||
public Bootstrap udpServerBootstrap(@Inject ProxyConfig proxyConfig,
|
||||
@Inject("udpServerGroup") NioEventLoopGroup udpServerGroup,
|
||||
@Inject("udpWorkGroup") NioEventLoopGroup udpWorkGroup) {
|
||||
Bootstrap bootstrap = new Bootstrap();
|
||||
bootstrap.group(udpServerGroup)
|
||||
// 主线程处理
|
||||
.channel(NioDatagramChannel.class)
|
||||
// 广播
|
||||
.option(ChannelOption.SO_BROADCAST, true)
|
||||
// 设置读缓冲区为2M
|
||||
.option(ChannelOption.SO_RCVBUF, 2048 * 1024)
|
||||
// 设置写缓冲区为1M
|
||||
.option(ChannelOption.SO_SNDBUF, 1024 * 1024)
|
||||
.handler(new ChannelInitializer<NioDatagramChannel>() {
|
||||
@Override
|
||||
protected void initChannel(NioDatagramChannel ch) {
|
||||
ChannelPipeline pipeline = ch.pipeline();
|
||||
if (null != proxyConfig.getClient().getUdp().getTransferLogEnable() && proxyConfig.getClient().getUdp().getTransferLogEnable()) {
|
||||
ch.pipeline().addFirst(new LoggingHandler(UdpRealServerHandler.class));
|
||||
}
|
||||
pipeline.addLast(udpWorkGroup, new UdpRealServerHandler());
|
||||
}
|
||||
});
|
||||
return bootstrap;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public NeutrinoCoreRuntimeNativeRegistrar neutrinoCoreRuntimeNativeRegistrar() {
|
||||
return new NeutrinoCoreRuntimeNativeRegistrar();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+10
-112
@@ -1,22 +1,12 @@
|
||||
package org.dromara.neutrinoproxy.client.core;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import org.dromara.neutrinoproxy.client.config.ProxyConfig;
|
||||
import org.dromara.neutrinoproxy.client.util.ProxyUtil;
|
||||
import org.dromara.neutrinoproxy.client.util.UdpServerUtil;
|
||||
import org.dromara.neutrinoproxy.core.ProxyMessage;
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.channel.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.noear.solon.Solon;
|
||||
import org.dromara.neutrinoproxy.client.config.ProxyConfiguration;
|
||||
import org.dromara.neutrinoproxy.client.sdk.config.ProxyConfig;
|
||||
import org.noear.solon.annotation.Component;
|
||||
import org.noear.solon.annotation.Init;
|
||||
import org.noear.solon.annotation.Inject;
|
||||
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 代理客户端服务
|
||||
* @author: aoshiguchen
|
||||
@@ -24,107 +14,15 @@ import java.util.concurrent.TimeUnit;
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class ProxyClientService {
|
||||
@Inject
|
||||
private ProxyConfig proxyConfig;
|
||||
@Inject("cmdTunnelBootstrap")
|
||||
private Bootstrap cmdTunnelBootstrap;
|
||||
@Inject("udpServerBootstrap")
|
||||
private Bootstrap udpServerBootstrap;
|
||||
private volatile Channel channel;
|
||||
/**
|
||||
* 重连次数
|
||||
*/
|
||||
private volatile int reconnectCount = 0;
|
||||
/**
|
||||
* 重连服务执行器
|
||||
*/
|
||||
private static final ScheduledExecutorService reconnectExecutor = Executors.newSingleThreadScheduledExecutor(new CustomThreadFactory("ClientReconnect"));
|
||||
|
||||
public class ProxyClientService{
|
||||
@Inject
|
||||
private ProxyConfiguration proxyConfiguration;
|
||||
@Inject
|
||||
private ProxyConfig proxyConfig;
|
||||
@Init
|
||||
public void init() {
|
||||
this.reconnectExecutor.scheduleWithFixedDelay(this::reconnect, 10, proxyConfig.getTunnel().getReconnection().getIntervalSeconds(), TimeUnit.SECONDS);
|
||||
|
||||
try {
|
||||
this.start();
|
||||
UdpServerUtil.initCache(proxyConfig, udpServerBootstrap);
|
||||
} catch (Exception e) {
|
||||
// 启动连不上也做一下重连,因此先catch异常
|
||||
log.error("[CmdChannel] start error", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void start() {
|
||||
if (StrUtil.isEmpty(proxyConfig.getTunnel().getServerIp())) {
|
||||
log.error("not found server-ip config.");
|
||||
Solon.stop();
|
||||
return;
|
||||
}
|
||||
if (null == proxyConfig.getTunnel().getServerPort()) {
|
||||
log.error("not found server-port config.");
|
||||
Solon.stop();
|
||||
return;
|
||||
}
|
||||
if (null != proxyConfig.getTunnel().getSslEnable() && proxyConfig.getTunnel().getSslEnable()
|
||||
&& StrUtil.isEmpty(proxyConfig.getTunnel().getJksPath())) {
|
||||
log.error("not found jks-path config.");
|
||||
Solon.stop();
|
||||
return;
|
||||
}
|
||||
if (StrUtil.isEmpty(proxyConfig.getTunnel().getLicenseKey())) {
|
||||
log.error("not found license-key config.");
|
||||
Solon.stop();
|
||||
return;
|
||||
}
|
||||
if (null == channel || !channel.isActive()) {
|
||||
try {
|
||||
connectProxyServer();
|
||||
} catch (Exception e) {
|
||||
log.error("client start error", e);
|
||||
}
|
||||
} else {
|
||||
channel.writeAndFlush(ProxyMessage.buildAuthMessage(proxyConfig.getTunnel().getLicenseKey(), ProxyUtil.getClientId()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 连接代理服务器
|
||||
*/
|
||||
private void connectProxyServer() throws InterruptedException {
|
||||
cmdTunnelBootstrap.connect()
|
||||
.addListener(new ChannelFutureListener() {
|
||||
|
||||
@Override
|
||||
public void operationComplete(ChannelFuture future) throws Exception {
|
||||
if (future.isSuccess()) {
|
||||
channel = future.channel();
|
||||
// 连接成功,向服务器发送客户端认证信息(licenseKey)
|
||||
ProxyUtil.setCmdChannel(future.channel());
|
||||
future.channel().writeAndFlush(ProxyMessage.buildAuthMessage(proxyConfig.getTunnel().getLicenseKey(), ProxyUtil.getClientId()));
|
||||
log.info("[CmdChannel] connect proxy server success. channelId:{}", future.channel().id().asLongText());
|
||||
|
||||
// reconnectServiceEnable = true;
|
||||
reconnectCount = 0;
|
||||
} else {
|
||||
log.info("[CmdChannel] connect proxy server failed!");
|
||||
}
|
||||
}
|
||||
}).sync();
|
||||
}
|
||||
|
||||
protected synchronized void reconnect() {
|
||||
if (null != channel) {
|
||||
if (channel.isActive()) {
|
||||
return;
|
||||
}
|
||||
channel.close();
|
||||
}
|
||||
|
||||
log.info("[CmdChannel] client reconnect seq:{}", ++reconnectCount);
|
||||
try {
|
||||
connectProxyServer();
|
||||
} catch (Exception e) {
|
||||
log.error("[CmdChannel] reconnect error", e);
|
||||
}
|
||||
log.info("启动中....");
|
||||
proxyConfiguration.start(proxyConfig);
|
||||
log.info("启动成功....");
|
||||
}
|
||||
}
|
||||
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package org.dromara.neutrinoproxy.client.handler;
|
||||
|
||||
import org.dromara.neutrinoproxy.client.sdk.config.IBeanHandler;
|
||||
import org.dromara.neutrinoproxy.client.sdk.config.ProxyConfig;
|
||||
import org.dromara.neutrinoproxy.core.dispatcher.Dispatcher;
|
||||
import org.noear.solon.Solon;
|
||||
|
||||
|
||||
public class BeanHandler implements IBeanHandler {
|
||||
|
||||
@Override
|
||||
public Dispatcher getDispatcher(){
|
||||
return Solon.context().getBean("dispatcher");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProxyConfig getProxyConfig() {
|
||||
return Solon.context().getBean(ProxyConfig.class);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user