client端solon化改造

This commit is contained in:
aoshiguchen
2023-03-12 20:32:32 +08:00
parent 534dd4ed9c
commit 21ee60de10
18 changed files with 377 additions and 579 deletions
+5 -5
View File
@@ -14,11 +14,11 @@
<artifactId>neutrino-proxy-client</artifactId>
<dependencies>
<dependency>
<groupId>fun.asgc.neutrino</groupId>
<artifactId>neutrino-core</artifactId>
<version>${revision}</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>fun.asgc.neutrino</groupId>-->
<!-- <artifactId>neutrino-core</artifactId>-->
<!-- <version>${revision}</version>-->
<!-- </dependency>-->
<dependency>
<groupId>fun.asgc.neutrino</groupId>
<artifactId>neutrino-proxy-core</artifactId>
@@ -1,12 +1,14 @@
package fun.asgc.neutrino.proxy.client;
import org.noear.solon.Solon;
import org.noear.solon.annotation.SolonMain;
/**
*
* @author: aoshiguchen
* @date: 2022/6/16
*/
@SolonMain
public class ProxyClient {
public static void main(String[] args) {
@@ -1,31 +1,8 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.proxy.client.config;
import fun.asgc.neutrino.core.annotation.Configuration;
import fun.asgc.neutrino.core.annotation.Init;
import fun.asgc.neutrino.core.annotation.Value;
import lombok.Data;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
/**
*
@@ -33,53 +10,33 @@ import lombok.Data;
* @date: 2022/6/16
*/
@Data
@Configuration(prefix = "neutrino.proxy")
@Component
public class ProxyConfig {
public static ProxyConfig instance;
@Inject("${neutrino.proxy.protocol}")
private Protocol protocol;
@Inject("${neutrino.proxy.client}")
private Client client;
private String licenseKey;
private CustomConfig customConfig;
public static volatile boolean authSuccess;
@Data
public static class Protocol {
@Value("max-frame-length")
private Integer maxFrameLength;
@Value("length-field-offset")
private Integer lengthFieldOffset;
@Value("length-field-length")
private Integer lengthFieldLength;
@Value("initial-bytes-to-strip")
private Integer initialBytesToStrip;
@Value("length-adjustment")
private Integer lengthAdjustment;
@Value("read-idle-time")
private Integer readIdleTime;
@Value("write-idle-time")
private Integer writeIdleTime;
@Value("all-idle-time-seconds")
private Integer allIdleTimeSeconds;
}
@Data
public static class Client {
@Value("key-store-password")
private String keyStorePassword;
@Value("jks-path")
private String jksPath;
@Value("server-ip")
private String serverIp;
@Value("server-port")
private Integer serverPort;
@Value("ssl-enable")
private Boolean sslEnable;
@Value("obtain-license-interval")
private Integer obtainLicenseInterval;
}
@Init
public void init() {
instance = this;
private String licenseKey;
}
}
@@ -1,51 +1,45 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.proxy.client.config;
import fun.asgc.neutrino.core.annotation.Bean;
import fun.asgc.neutrino.core.annotation.Component;
import fun.asgc.neutrino.core.annotation.Order;
import fun.asgc.neutrino.core.base.Ordered;
import fun.asgc.neutrino.core.util.BeanManager;
import fun.asgc.neutrino.proxy.core.ProxyDataTypeEnum;
import fun.asgc.neutrino.proxy.core.ProxyMessage;
import fun.asgc.neutrino.proxy.core.ProxyMessageHandler;
import fun.asgc.neutrino.proxy.core.dispatcher.DefaultDispatcher;
import fun.asgc.neutrino.proxy.core.dispatcher.Dispatcher;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.nio.NioEventLoopGroup;
import org.noear.solon.Solon;
import org.noear.solon.annotation.Bean;
import org.noear.solon.annotation.Configuration;
import org.noear.solon.core.bean.LifecycleBean;
import java.util.List;
/**
* 代理配置
* @author: aoshiguchen
* @date: 2022/10/8
*/
@Order(Ordered.HIGHEST_PRECEDENCE)
@Component
public class ProxyConfiguration {
@Configuration
public class ProxyConfiguration implements LifecycleBean {
@Bean
public Dispatcher<ChannelHandlerContext, ProxyMessage> dispatcher() {
return new DefaultDispatcher<>("消息调度器",
BeanManager.getBeanListBySuperClass(ProxyMessageHandler.class),
proxyMessage -> ProxyDataTypeEnum.of((int)proxyMessage.getType()) == null ? null : ProxyDataTypeEnum.of((int)proxyMessage.getType()).getName());
@Override
public void start() throws Throwable {
List<ProxyMessageHandler> list = Solon.context().getBeansOfType(ProxyMessageHandler.class);
Dispatcher<ChannelHandlerContext, ProxyMessage> dispatcher = new DefaultDispatcher<>("消息调度器", list,
proxyMessage -> ProxyDataTypeEnum.of((int)proxyMessage.getType()) == null ?
null : ProxyDataTypeEnum.of((int)proxyMessage.getType()).getName());
Solon.context().wrapAndPut(Dispatcher.class, dispatcher);
}
@Bean("bootstrap")
public Bootstrap bootstrap() {
return new Bootstrap();
}
@Bean("realServerBootstrap")
public Bootstrap realServerBootstrap() {
return new Bootstrap();
}
}
@@ -1,55 +1,55 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.proxy.client.core;
import fun.asgc.neutrino.core.annotation.Autowired;
import fun.asgc.neutrino.core.annotation.Component;
import fun.asgc.neutrino.core.annotation.NonIntercept;
import fun.asgc.neutrino.core.annotation.Subscribe;
import fun.asgc.neutrino.core.base.event.ApplicationEvent;
import fun.asgc.neutrino.core.base.event.ApplicationEventReceiver;
import fun.asgc.neutrino.core.constant.AppLifeCycleStatusEnum;
import fun.asgc.neutrino.core.constant.MetaDataConstant;
import lombok.extern.slf4j.Slf4j;
/**
* 应用生命周期事件监听器
* @author: aoshiguchen
* @date: 2022/10/10
*/
@Slf4j
@NonIntercept
@Component
@Subscribe(topic = MetaDataConstant.TOPIC_APP_LIFE_CYCLE)
public class ApplicationLifeCycleListener extends ApplicationEventReceiver<AppLifeCycleStatusEnum> {
@Autowired
private LicenseObtainService licenseObtainService;
@Override
public void receive(ApplicationEvent<AppLifeCycleStatusEnum> msg) {
log.debug("ApplicationLifeCycleListener:{}", msg.data().getDesc());
if (msg.data() == AppLifeCycleStatusEnum.APP_STARTUP) {
licenseObtainService.start();
}
}
}
///**
// * Copyright (c) 2022 aoshiguchen
// *
// * Permission is hereby granted, free of charge, to any person obtaining a copy
// * of this software and associated documentation files (the "Software"), to deal
// * in the Software without restriction, including without limitation the rights
// * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// * copies of the Software, and to permit persons to whom the Software is
// * furnished to do so, subject to the following conditions:
// *
// * The above copyright notice and this permission notice shall be included in all
// * copies or substantial portions of the Software.
// *
// * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// * SOFTWARE.
// */
//package fun.asgc.neutrino.proxy.client.core;
//
//import fun.asgc.neutrino.core.annotation.Autowired;
//import fun.asgc.neutrino.core.annotation.Component;
//import fun.asgc.neutrino.core.annotation.NonIntercept;
//import fun.asgc.neutrino.core.annotation.Subscribe;
//import fun.asgc.neutrino.core.base.event.ApplicationEvent;
//import fun.asgc.neutrino.core.base.event.ApplicationEventReceiver;
//import fun.asgc.neutrino.core.constant.AppLifeCycleStatusEnum;
//import fun.asgc.neutrino.core.constant.MetaDataConstant;
//import lombok.extern.slf4j.Slf4j;
//
///**
// * 应用生命周期事件监听器
// * @author: aoshiguchen
// * @date: 2022/10/10
// */
//@Slf4j
//@NonIntercept
//@Component
//@Subscribe(topic = MetaDataConstant.TOPIC_APP_LIFE_CYCLE)
//public class ApplicationLifeCycleListener extends ApplicationEventReceiver<AppLifeCycleStatusEnum> {
// @Autowired
// private LicenseObtainService licenseObtainService;
//
// @Override
// public void receive(ApplicationEvent<AppLifeCycleStatusEnum> msg) {
// log.debug("ApplicationLifeCycleListener:{}", msg.data().getDesc());
// if (msg.data() == AppLifeCycleStatusEnum.APP_STARTUP) {
// licenseObtainService.start();
// }
// }
//
//}
@@ -1,28 +1,5 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.proxy.client.core;
import fun.asgc.neutrino.core.util.BeanManager;
import fun.asgc.neutrino.proxy.client.util.ProxyUtil;
import fun.asgc.neutrino.proxy.core.Constants;
import fun.asgc.neutrino.proxy.core.ProxyMessage;
@@ -33,6 +10,7 @@ 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;
/**
* 处理与服务端之间的数据传输
@@ -42,19 +20,13 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j
public class ClientChannelHandler extends SimpleChannelInboundHandler<ProxyMessage> {
private static volatile Dispatcher<ChannelHandlerContext, ProxyMessage> dispatcher;
public ClientChannelHandler() {
dispatcher = BeanManager.getBean(Dispatcher.class);
}
@Override
protected void channelRead0(ChannelHandlerContext ctx, ProxyMessage proxyMessage) throws Exception {
if (ProxyMessage.TYPE_HEARTBEAT != proxyMessage.getType()) {
log.info("recieved proxy message, type is {}", proxyMessage.getType());
}
dispatcher.dispatch(ctx, proxyMessage);
Solon.context().getBean(Dispatcher.class).dispatch(ctx, proxyMessage);
}
@Override
@@ -0,0 +1,55 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.proxy.client.core;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;
/**
*
* @author: aoshiguchen
* @date: 2022/9/4
*/
public class CustomThreadFactory implements ThreadFactory {
private final ThreadGroup group;
private final AtomicInteger threadNumber = new AtomicInteger(1);
private final String namePrefix;
public CustomThreadFactory(String prefix) {
SecurityManager s = System.getSecurityManager();
group = (s != null) ? s.getThreadGroup() :
Thread.currentThread().getThreadGroup();
namePrefix = prefix + "-thread-";
}
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0);
if (t.isDaemon()) {
t.setDaemon(false);
}
if (t.getPriority() != Thread.NORM_PRIORITY) {
t.setPriority(Thread.NORM_PRIORITY);
}
return t;
}
}
@@ -1,175 +1,166 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.proxy.client.core;
import com.alibaba.fastjson.JSONObject;
import fun.asgc.neutrino.core.annotation.Autowired;
import fun.asgc.neutrino.core.annotation.Component;
import fun.asgc.neutrino.core.annotation.NonIntercept;
import fun.asgc.neutrino.core.base.CustomThreadFactory;
import fun.asgc.neutrino.core.context.Environment;
import fun.asgc.neutrino.core.util.ArrayUtil;
import fun.asgc.neutrino.core.util.FileUtil;
import fun.asgc.neutrino.core.util.StringUtil;
import fun.asgc.neutrino.proxy.client.config.CustomConfig;
import fun.asgc.neutrino.proxy.client.config.ProxyConfig;
import lombok.extern.slf4j.Slf4j;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
/**
* license获取服务
* @author: aoshiguchen
* @date: 2022/9/4
*/
@Slf4j
@NonIntercept
@Component
public class LicenseObtainService {
@Autowired
private ProxyConfig proxyConfig;
/**
* 调度器
*/
private static final ScheduledExecutorService scheduledExecutor = Executors.newSingleThreadScheduledExecutor(new CustomThreadFactory("LicenseObtain"));
@Autowired
private ProxyClientService proxyClientService;
private ReentrantLock runLock = new ReentrantLock();
private Scanner scanner = new Scanner(System.in);
@Autowired
private Environment environment;
public void start() {
scheduledExecutor.scheduleWithFixedDelay(() -> {
boolean lock = runLock.tryLock();
try {
if (lock) {
this.process(this.environment.getMainArgs());
}
} finally {
if (runLock.isHeldByCurrentThread()){
runLock.unlock();
}
}
}, 0, proxyConfig.getClient().getObtainLicenseInterval(), TimeUnit.SECONDS);
}
public void stop() {
scheduledExecutor.shutdown();
log.info("licenseKey获取任务停止");
}
public void process(String[] args) {
CustomConfig customConfig = getCustomConfigByCliParams(args);
proxyConfig.getClient().setJksPath(customConfig.getJksPath());
proxyConfig.getClient().setServerIp(customConfig.getServerIp());
proxyConfig.getClient().setServerPort(customConfig.getServerPort());
proxyConfig.getClient().setSslEnable(customConfig.getSslEnable());
proxyConfig.setLicenseKey(customConfig.getLicenseKey());
proxyConfig.setCustomConfig(customConfig);
proxyClientService.start();
}
private CustomConfig getCustomConfigByCliParams(String[] args) {
CustomConfig customConfig = new CustomConfig();
// 默认无需输入
customConfig.setJksPath(environment.getMainArgsForString("jksPath", proxyConfig.getClient().getJksPath()));
customConfig.setServerIp(environment.getMainArgsForString("serverIp", proxyConfig.getClient().getServerIp()));
customConfig.setServerPort(environment.getMainArgsForInteger("serverPort", proxyConfig.getClient().getServerPort()));
customConfig.setSslEnable(environment.getMainArgsForBoolean("sslEnable", proxyConfig.getClient().getSslEnable()));
customConfig.setLicenseKey(environment.getMainArgsForString("licenseKey"));
// 启动参数指定了license,则无需后续处理
if (StringUtil.notEmpty(customConfig.getLicenseKey())) {
// FileUtil.write("./.neutrino-proxy-client.json", JSONObject.toJSONString(customConfig, SerializerFeature.PrettyFormat));
return customConfig;
}
// 启动参数未指定license,则优先读取外部配置
String config = FileUtil.readContentAsString("./.neutrino-proxy-client.json");
if (StringUtil.notEmpty(config)) {
try {
CustomConfig tmp = JSONObject.parseObject(config, CustomConfig.class);
if (!StringUtil.isEmpty(tmp.getJksPath())) {
customConfig.setJksPath(tmp.getJksPath());
}
if (!StringUtil.isEmpty(tmp.getServerIp())) {
customConfig.setServerIp(tmp.getServerIp());
}
if (null != tmp.getServerPort()) {
customConfig.setServerPort(tmp.getServerPort());
}
if (null != tmp.getSslEnable()) {
customConfig.setSslEnable(tmp.getSslEnable());
}
if (!StringUtil.isEmpty(tmp.getLicenseKey())) {
customConfig.setLicenseKey(tmp.getLicenseKey());
}
} catch (Exception e) {
log.error("file '.neutrino-proxy-client.json' config exception!", e);
}
if (StringUtil.notEmpty(customConfig.getLicenseKey())) {
// FileUtil.write("./.neutrino-proxy-client.json", JSONObject.toJSONString(customConfig, SerializerFeature.PrettyFormat));
return customConfig;
}
}
String license = "";
while (StringUtil.isEmpty(license)) {
System.out.print("Please input license:");
license = scanner.next();
}
customConfig.setLicenseKey(license);
// FileUtil.write("./.neutrino-proxy-client.json", JSONObject.toJSONString(customConfig, SerializerFeature.PrettyFormat));
return customConfig;
}
/**
* 获取命令行参数
* @param args
* @return
*/
private Map<String, String> getCliParams(String[] args) {
Map<String, String> res = new HashMap<>();
if (ArrayUtil.notEmpty(args)) {
for (String item : args) {
if (StringUtil.isEmpty(item) || !item.contains("=")) {
continue;
}
int index = item.indexOf("=");
if (index <= 0 || index == item.length() - 1) {
continue;
}
res.put(item.substring(0, index), item.substring(index + 1));
}
}
return res;
}
}
///**
// * Copyright (c) 2022 aoshiguchen
// *
// * Permission is hereby granted, free of charge, to any person obtaining a copy
// * of this software and associated documentation files (the "Software"), to deal
// * in the Software without restriction, including without limitation the rights
// * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// * copies of the Software, and to permit persons to whom the Software is
// * furnished to do so, subject to the following conditions:
// *
// * The above copyright notice and this permission notice shall be included in all
// * copies or substantial portions of the Software.
// *
// * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// * SOFTWARE.
// */
//package fun.asgc.neutrino.proxy.client.core;
//
//import com.alibaba.fastjson.JSONObject;
//import fun.asgc.neutrino.core.base.CustomThreadFactory;
//import fun.asgc.neutrino.core.util.ArrayUtil;
//import fun.asgc.neutrino.core.util.FileUtil;
//import fun.asgc.neutrino.core.util.StringUtil;
//import fun.asgc.neutrino.proxy.client.config.CustomConfig;
//import fun.asgc.neutrino.proxy.client.config.ProxyConfig;
//import lombok.extern.slf4j.Slf4j;
//import org.noear.solon.annotation.Component;
//import org.noear.solon.annotation.Inject;
//
//import java.util.HashMap;
//import java.util.Map;
//import java.util.Scanner;
//import java.util.concurrent.Executors;
//import java.util.concurrent.ScheduledExecutorService;
//import java.util.concurrent.TimeUnit;
//import java.util.concurrent.locks.ReentrantLock;
//
///**
// * license获取服务
// * @author: aoshiguchen
// * @date: 2022/9/4
// */
//@Slf4j
//@Component
//public class LicenseObtainService {
// /**
// * 调度器
// */
// private static final ScheduledExecutorService scheduledExecutor = Executors.newSingleThreadScheduledExecutor(new CustomThreadFactory("LicenseObtain"));
// private ReentrantLock runLock = new ReentrantLock();
// private Scanner scanner = new Scanner(System.in);
// @Inject
// private ProxyConfig proxyConfig;
// @Inject
// private ProxyClientService proxyClientService;
//
// public void start() {
// scheduledExecutor.scheduleWithFixedDelay(() -> {
// boolean lock = runLock.tryLock();
// try {
// if (lock) {
// this.process();
// }
// } finally {
// if (runLock.isHeldByCurrentThread()){
// runLock.unlock();
// }
// }
// }, 0, proxyConfig.getClient().getObtainLicenseInterval(), TimeUnit.SECONDS);
// }
//
// public void stop() {
// scheduledExecutor.shutdown();
// log.info("licenseKey获取任务停止");
// }
//
// public void process() {
//
//
// proxyClientService.start();
// }
//
// private String
//
// private CustomConfig getCustomConfigByCliParams() {
// CustomConfig customConfig = new CustomConfig();
// // 默认无需输入
// customConfig.setJksPath(environment.getMainArgsForString("jksPath", proxyConfig.getClient().getJksPath()));
// customConfig.setServerIp(environment.getMainArgsForString("serverIp", proxyConfig.getClient().getServerIp()));
// customConfig.setServerPort(environment.getMainArgsForInteger("serverPort", proxyConfig.getClient().getServerPort()));
// customConfig.setSslEnable(environment.getMainArgsForBoolean("sslEnable", proxyConfig.getClient().getSslEnable()));
// customConfig.setLicenseKey(environment.getMainArgsForString("licenseKey"));
// // 启动参数指定了license,则无需后续处理
// if (StringUtil.notEmpty(customConfig.getLicenseKey())) {
//// FileUtil.write("./.neutrino-proxy-client.json", JSONObject.toJSONString(customConfig, SerializerFeature.PrettyFormat));
// return customConfig;
// }
//
// // 启动参数未指定license,则优先读取外部配置
// String config = FileUtil.readContentAsString("./.neutrino-proxy-client.json");
// if (StringUtil.notEmpty(config)) {
// try {
// CustomConfig tmp = JSONObject.parseObject(config, CustomConfig.class);
// if (!StringUtil.isEmpty(tmp.getJksPath())) {
// customConfig.setJksPath(tmp.getJksPath());
// }
// if (!StringUtil.isEmpty(tmp.getServerIp())) {
// customConfig.setServerIp(tmp.getServerIp());
// }
// if (null != tmp.getServerPort()) {
// customConfig.setServerPort(tmp.getServerPort());
// }
// if (null != tmp.getSslEnable()) {
// customConfig.setSslEnable(tmp.getSslEnable());
// }
// if (!StringUtil.isEmpty(tmp.getLicenseKey())) {
// customConfig.setLicenseKey(tmp.getLicenseKey());
// }
// } catch (Exception e) {
// log.error("file '.neutrino-proxy-client.json' config exception!", e);
// }
// if (StringUtil.notEmpty(customConfig.getLicenseKey())) {
//// FileUtil.write("./.neutrino-proxy-client.json", JSONObject.toJSONString(customConfig, SerializerFeature.PrettyFormat));
// return customConfig;
// }
// }
//
// String license = "";
// while (StringUtil.isEmpty(license)) {
// System.out.print("Please input license:");
// license = scanner.next();
// }
// customConfig.setLicenseKey(license);
//// FileUtil.write("./.neutrino-proxy-client.json", JSONObject.toJSONString(customConfig, SerializerFeature.PrettyFormat));
//
// return customConfig;
// }
//
// /**
// * 获取命令行参数
// * @param args
// * @return
// */
// private Map<String, String> getCliParams(String[] args) {
// Map<String, String> res = new HashMap<>();
// if (ArrayUtil.notEmpty(args)) {
// for (String item : args) {
// if (StringUtil.isEmpty(item) || !item.contains("=")) {
// continue;
// }
// int index = item.indexOf("=");
// if (index <= 0 || index == item.length() - 1) {
// continue;
// }
// res.put(item.substring(0, index), item.substring(index + 1));
// }
// }
//
// return res;
// }
//}
@@ -1,37 +1,12 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.proxy.client.core;
import fun.asgc.neutrino.core.annotation.*;
import fun.asgc.neutrino.core.base.CustomThreadFactory;
import fun.asgc.neutrino.core.context.Environment;
import fun.asgc.neutrino.core.util.FileUtil;
import fun.asgc.neutrino.core.util.StringUtil;
import cn.hutool.core.util.StrUtil;
import fun.asgc.neutrino.proxy.client.config.ProxyConfig;
import fun.asgc.neutrino.proxy.client.util.ProxyUtil;
import fun.asgc.neutrino.proxy.core.ProxyMessage;
import fun.asgc.neutrino.proxy.core.ProxyMessageDecoder;
import fun.asgc.neutrino.proxy.core.ProxyMessageEncoder;
import fun.asgc.neutrino.proxy.core.util.FileUtil;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
@@ -40,6 +15,10 @@ import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.ssl.SslHandler;
import io.netty.handler.timeout.IdleStateHandler;
import lombok.extern.slf4j.Slf4j;
import org.noear.solon.Solon;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Init;
import org.noear.solon.annotation.Inject;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
@@ -57,18 +36,14 @@ import java.util.concurrent.TimeUnit;
* @date: 2022/6/16
*/
@Slf4j
@NonIntercept
@Component
public class ProxyClientService {
@Autowired
@Inject
private ProxyConfig proxyConfig;
@Autowired("bootstrap")
private static Bootstrap bootstrap;
@Autowired("realServerBootstrap")
private static Bootstrap realServerBootstrap;
private static NioEventLoopGroup workerGroup;
@Autowired
private Environment environment;
@Inject("bootstrap")
private Bootstrap bootstrap;
@Inject("realServerBootstrap")
private Bootstrap realServerBootstrap;
private volatile Channel channel;
/**
* 重连间隔(秒)
@@ -91,7 +66,7 @@ public class ProxyClientService {
public void init() {
this.reconnectExecutor.scheduleWithFixedDelay(this::reconnect, 0, RECONNECT_INTERVAL_SECONDS, TimeUnit.SECONDS);
workerGroup = new NioEventLoopGroup();
NioEventLoopGroup workerGroup = new NioEventLoopGroup();
realServerBootstrap.group(workerGroup);
realServerBootstrap.channel(NioSocketChannel.class);
realServerBootstrap.handler(new ChannelInitializer<SocketChannel>() {
@@ -120,20 +95,39 @@ public class ProxyClientService {
ch.pipeline().addLast(new ClientChannelHandler());
}
});
this.start();
}
public void start() {
if (StringUtil.isEmpty(proxyConfig.getLicenseKey())) {
if (StrUtil.isEmpty(proxyConfig.getClient().getServerIp())) {
log.error("not found server-ip config.");
Solon.stop();
return;
}
if (null == proxyConfig.getClient().getServerPort()) {
log.error("not found server-port config.");
Solon.stop();
return;
}
if (null != proxyConfig.getClient().getSslEnable() && proxyConfig.getClient().getSslEnable()
&& StrUtil.isEmpty(proxyConfig.getClient().getJksPath())) {
log.error("not found jks-path config.");
Solon.stop();
return;
}
if (StrUtil.isEmpty(proxyConfig.getClient().getLicenseKey())) {
log.error("not found license-key config.");
Solon.stop();
return;
}
if (null == channel || !channel.isActive()) {
try {
connectProxyServer();
} catch (Exception e) {
log.error("启动异常", e);
log.error("client start error", e);
}
} else {
channel.writeAndFlush(ProxyMessage.buildAuthMessage(proxyConfig.getLicenseKey()));
channel.writeAndFlush(ProxyMessage.buildAuthMessage(proxyConfig.getClient().getLicenseKey()));
}
}
@@ -150,7 +144,7 @@ public class ProxyClientService {
channel = future.channel();
// 连接成功,向服务器发送客户端认证信息(licenseKey)
ProxyUtil.setCmdChannel(future.channel());
future.channel().writeAndFlush(ProxyMessage.buildAuthMessage(proxyConfig.getLicenseKey()));
future.channel().writeAndFlush(ProxyMessage.buildAuthMessage(proxyConfig.getClient().getLicenseKey()));
log.info("连接代理服务成功. channelId:{}", future.channel().id().asLongText());
reconnectServiceEnable = true;
@@ -199,14 +193,4 @@ public class ProxyClientService {
log.error("重连异常", e);
}
}
@Bean
public Bootstrap bootstrap() {
return new Bootstrap();
}
@Bean
public Bootstrap realServerBootstrap() {
return new Bootstrap();
}
}
@@ -1,41 +1,13 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.proxy.client.handler;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import fun.asgc.neutrino.core.annotation.Autowired;
import fun.asgc.neutrino.core.annotation.Component;
import fun.asgc.neutrino.core.annotation.NonIntercept;
import fun.asgc.neutrino.core.util.FileUtil;
import fun.asgc.neutrino.proxy.client.config.ProxyConfig;
import fun.asgc.neutrino.proxy.client.core.LicenseObtainService;
import fun.asgc.neutrino.proxy.core.Constants;
import fun.asgc.neutrino.proxy.core.ExceptionEnum;
import fun.asgc.neutrino.proxy.core.ProxyMessage;
import fun.asgc.neutrino.proxy.core.ProxyMessageHandler;
import fun.asgc.neutrino.proxy.core.dispatcher.Match;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
import org.noear.solon.annotation.Component;
/**
* 认证信息处理器
@@ -43,25 +15,14 @@ import lombok.extern.slf4j.Slf4j;
* @date: 2022/9/4
*/
@Slf4j
@NonIntercept
@Match(type = Constants.ProxyDataTypeName.AUTH)
@Component
public class ProxyMessageAuthHandler implements ProxyMessageHandler {
@Autowired
private LicenseObtainService licenseObtainService;
@Autowired
private ProxyConfig proxyConfig;
@Override
public void handle(ChannelHandlerContext context, ProxyMessage proxyMessage) {
String info = proxyMessage.getInfo();
JSONObject data = JSONObject.parseObject(info);
Integer code = data.getInteger("code");
log.info("认证结果:{}", info);
if (ExceptionEnum.SUCCESS.getCode().equals(code)) {
ProxyConfig.authSuccess = true;
FileUtil.write("./.neutrino-proxy-client.json", JSONObject.toJSONString(proxyConfig.getCustomConfig(), SerializerFeature.PrettyFormat));
licenseObtainService.stop();
}
}
}
@@ -1,30 +1,5 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.proxy.client.handler;
import fun.asgc.neutrino.core.annotation.Autowired;
import fun.asgc.neutrino.core.annotation.Component;
import fun.asgc.neutrino.core.annotation.NonIntercept;
import fun.asgc.neutrino.proxy.client.config.ProxyConfig;
import fun.asgc.neutrino.proxy.client.core.ProxyChannelBorrowListener;
import fun.asgc.neutrino.proxy.client.util.ProxyUtil;
@@ -35,20 +10,23 @@ import fun.asgc.neutrino.proxy.core.ProxyMessageHandler;
import fun.asgc.neutrino.proxy.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
*/
@NonIntercept
@Match(type = Constants.ProxyDataTypeName.CONNECT)
@Component
public class ProxyMessageConnectHandler implements ProxyMessageHandler {
@Autowired("bootstrap")
@Inject("bootstrap")
private Bootstrap bootstrap;
@Autowired("realServerBootstrap")
@Inject("realServerBootstrap")
private Bootstrap realServerBootstrap;
@Inject
private ProxyConfig proxyConfig;
@Override
public void handle(ChannelHandlerContext ctx, ProxyMessage proxyMessage) {
@@ -79,7 +57,7 @@ public class ProxyMessageConnectHandler implements ProxyMessageHandler {
realServerChannel.attr(Constants.NEXT_CHANNEL).set(channel);
// 远程绑定
channel.writeAndFlush(ProxyMessage.buildConnectMessage(visitorId + "@" + ProxyConfig.instance.getLicenseKey()));
channel.writeAndFlush(ProxyMessage.buildConnectMessage(visitorId + "@" + proxyConfig.getClient().getLicenseKey()));
realServerChannel.config().setOption(ChannelOption.AUTO_READ, true);
ProxyUtil.addRealServerChannel(visitorId, realServerChannel);
@@ -1,29 +1,5 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.proxy.client.handler;
import fun.asgc.neutrino.core.annotation.Component;
import fun.asgc.neutrino.core.annotation.NonIntercept;
import fun.asgc.neutrino.proxy.client.util.ProxyUtil;
import fun.asgc.neutrino.proxy.core.Constants;
import fun.asgc.neutrino.proxy.core.ProxyDataTypeEnum;
@@ -34,13 +10,13 @@ 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
*/
@NonIntercept
@Match(type = Constants.ProxyDataTypeName.DISCONNECT)
@Component
public class ProxyMessageDisconnectHandler implements ProxyMessageHandler {
@@ -1,34 +1,11 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.proxy.client.handler;
import com.alibaba.fastjson.JSONObject;
import fun.asgc.neutrino.core.annotation.Component;
import fun.asgc.neutrino.core.annotation.NonIntercept;
import fun.asgc.neutrino.proxy.core.*;
import fun.asgc.neutrino.proxy.core.dispatcher.Match;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
import org.noear.solon.annotation.Component;
/**
* 异常信息处理器
@@ -36,7 +13,6 @@ import lombok.extern.slf4j.Slf4j;
* @date: 2022/6/16
*/
@Slf4j
@NonIntercept
@Match(type = Constants.ProxyDataTypeName.ERROR)
@Component
public class ProxyMessageErrorHandler implements ProxyMessageHandler {
@@ -1,29 +1,5 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.proxy.client.handler;
import fun.asgc.neutrino.core.annotation.Component;
import fun.asgc.neutrino.core.annotation.NonIntercept;
import fun.asgc.neutrino.proxy.core.Constants;
import fun.asgc.neutrino.proxy.core.ProxyDataTypeEnum;
import fun.asgc.neutrino.proxy.core.ProxyMessage;
@@ -32,13 +8,13 @@ import fun.asgc.neutrino.proxy.core.dispatcher.Match;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import org.noear.solon.annotation.Component;
/**
* 传输信息处理器
* @author: aoshiguchen
* @date: 2022/6/16
*/
@NonIntercept
@Match(type = Constants.ProxyDataTypeName.TRANSFER)
@Component
public class ProxyMessageTransferHandler implements ProxyMessageHandler {
@@ -31,6 +31,7 @@ import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelOption;
import io.netty.util.AttributeKey;
import org.noear.solon.Solon;
import java.util.Iterator;
import java.util.Map;
@@ -62,15 +63,13 @@ public class ProxyUtil {
return;
}
bootstrap.connect(ProxyConfig.instance.getClient().getServerIp(), ProxyConfig.instance.getClient().getServerPort()).addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
if (future.isSuccess()) {
borrowListener.success(future.channel());
} else {
borrowListener.error(future.cause());
}
String serverIp = Solon.cfg().get("neutrino.proxy.client.server-ip");
Integer serverPort = Solon.cfg().getInt("neutrino.proxy.client.server-port", 9000);
bootstrap.connect(serverIp, serverPort).addListener((ChannelFutureListener) future -> {
if (future.isSuccess()) {
borrowListener.success(future.channel());
} else {
borrowListener.error(future.cause());
}
});
}
@@ -19,3 +19,4 @@ neutrino:
server-port: 9002
ssl-enable: true
obtain-license-interval: 5
license-key:
@@ -1,25 +1,3 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.proxy.core;
import fun.asgc.neutrino.proxy.core.dispatcher.Handler;
@@ -7,6 +7,7 @@ import fun.asgc.neutrino.proxy.core.dispatcher.DefaultDispatcher;
import fun.asgc.neutrino.proxy.core.dispatcher.Dispatcher;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.nio.NioEventLoopGroup;
import org.noear.solon.Solon;
import org.noear.solon.annotation.Bean;
import org.noear.solon.annotation.Configuration;
import org.noear.solon.annotation.Inject;
@@ -22,18 +23,15 @@ import java.util.List;
*/
@Configuration
public class ProxyConfiguration implements LifecycleBean {
@Inject
AopContext aopContext;
@Override
public void start() throws Throwable {
List<ProxyMessageHandler> list = aopContext.getBeansOfType(ProxyMessageHandler.class);
List<ProxyMessageHandler> list = Solon.context().getBeansOfType(ProxyMessageHandler.class);
Dispatcher<ChannelHandlerContext, ProxyMessage> dispatcher = new DefaultDispatcher<>("消息调度器", list,
proxyMessage -> ProxyDataTypeEnum.of((int)proxyMessage.getType()) == null ?
null : ProxyDataTypeEnum.of((int)proxyMessage.getType()).getName());
aopContext.wrapAndPut(Dispatcher.class, dispatcher);
Solon.context().wrapAndPut(Dispatcher.class, dispatcher);
}
@Bean("serverBossGroup")