Merge remote-tracking branch 'origin/feature/1.6.2' into feature/1.6.2
This commit is contained in:
+9
@@ -24,6 +24,11 @@ package fun.asgc.neutrino.proxy.server.constant;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* 启用状态枚举
|
||||
* @author: aoshiguchen
|
||||
@@ -34,7 +39,11 @@ import lombok.Getter;
|
||||
public enum EnableStatusEnum {
|
||||
ENABLE(1, "启用"),
|
||||
DISABLE(2, "禁用");
|
||||
private static Map<Integer, EnableStatusEnum> CACHE = Stream.of(EnableStatusEnum.values()).collect(Collectors.toMap(EnableStatusEnum::getStatus, Function.identity()));
|
||||
|
||||
private Integer status;
|
||||
private String desc;
|
||||
public static EnableStatusEnum of(Integer status) {
|
||||
return CACHE.get(status);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -50,7 +50,7 @@ public enum ExceptionConstant {
|
||||
LOGIN_PASSWORD_NO_CHANGE_MODIFY_FAIL(12004, "密码没有变化,修改失败"),
|
||||
// 端口池管理(13000)
|
||||
PORT_CANNOT_REPEAT(13000,"端口不能重复"),
|
||||
PORT_NOT_EXIST(13001, "该端口在端口池中不存在,不允许映射"),
|
||||
PORT_NOT_EXIST(13001, "该端口在端口池中不存在"),
|
||||
// 端口映射管理(14000)
|
||||
PORT_MAPPING_NOT_EXIST(14000, "端口映射记录不存在"),
|
||||
PORT_CANNOT_REPEAT_MAPPING(14001, "服务端口[{}]不能重复映射"),
|
||||
|
||||
+3
@@ -62,6 +62,9 @@ public interface LicenseMapper extends SqlMapper {
|
||||
@Select("select * from license")
|
||||
List<LicenseDO> listAll();
|
||||
|
||||
@Select("select * from license where user_id := userId")
|
||||
List<LicenseDO> listByUserId(@Param("userId") Integer userId);
|
||||
|
||||
/**
|
||||
* 新增license
|
||||
* @param license
|
||||
|
||||
+8
@@ -74,6 +74,14 @@ public interface PortMappingMapper extends SqlMapper {
|
||||
@Select("select * from port_mapping where license_id = ? and enable = 1")
|
||||
List<PortMappingDO> findEnableListByLicenseId(Integer licenseId);
|
||||
|
||||
@ResultType(PortMappingDO.class)
|
||||
@Select("select * from port_mapping where server_port = :serverPort")
|
||||
List<PortMappingDO> findListByServerPort(@Param("serverPort") Integer serverPort);
|
||||
|
||||
@ResultType(PortMappingDO.class)
|
||||
@Select("select * from port_mapping where license_id = ?")
|
||||
List<PortMappingDO> findListByLicenseId(Integer licenseId);
|
||||
|
||||
@Update("update `port_mapping` set is_online = :isOnline,update_time = :updateTime where license_id = :licenseId and server_port = :serverPort")
|
||||
void updateOnlineStatus(@Param("licenseId") Integer licenseId, @Param("serverPort") Integer serverPort, @Param("isOnline") Integer isOnline, @Param("updateTime") Date updateTime);
|
||||
|
||||
|
||||
+3
@@ -62,4 +62,7 @@ public interface PortPoolMapper extends SqlMapper {
|
||||
|
||||
@Select("select * from port_pool where port = ? limit 0,1")
|
||||
PortPoolDO findByPort(Integer port);
|
||||
|
||||
@Select("select * from port_pool where id = ?")
|
||||
PortPoolDO findById(Integer id);
|
||||
}
|
||||
|
||||
+14
-8
@@ -23,6 +23,7 @@
|
||||
package fun.asgc.neutrino.proxy.server.proxy.core;
|
||||
|
||||
import fun.asgc.neutrino.core.util.BeanManager;
|
||||
import fun.asgc.neutrino.core.util.StringUtil;
|
||||
import fun.asgc.neutrino.proxy.core.Constants;
|
||||
import fun.asgc.neutrino.proxy.core.ProxyMessage;
|
||||
import fun.asgc.neutrino.proxy.server.proxy.domain.VisitorChannelAttachInfo;
|
||||
@@ -87,10 +88,15 @@ public class VisitorChannelHandler extends SimpleChannelInboundHandler<ByteBuf>
|
||||
} else {
|
||||
String visitorId = newVisitorId();
|
||||
String lanInfo = ProxyUtil.getClientLanInfoByServerPort(sa.getPort());
|
||||
// 用户连接到代理服务器时,设置用户连接不可读,等待代理后端服务器连接成功后再改变为可读状态
|
||||
visitorChannel.config().setOption(ChannelOption.AUTO_READ, false);
|
||||
ProxyUtil.addVisitorChannelToCmdChannel(cmdChannel, visitorId, visitorChannel);
|
||||
cmdChannel.writeAndFlush(ProxyMessage.buildConnectMessage(visitorId).setData(lanInfo.getBytes()));
|
||||
if (StringUtil.isEmpty(lanInfo)) {
|
||||
ctx.channel().close();
|
||||
} else {
|
||||
// 用户连接到代理服务器时,设置用户连接不可读,等待代理后端服务器连接成功后再改变为可读状态
|
||||
visitorChannel.config().setOption(ChannelOption.AUTO_READ, false);
|
||||
|
||||
ProxyUtil.addVisitorChannelToCmdChannel(cmdChannel, visitorId, visitorChannel, sa.getPort());
|
||||
cmdChannel.writeAndFlush(ProxyMessage.buildConnectMessage(visitorId).setData(lanInfo.getBytes()));
|
||||
}
|
||||
}
|
||||
|
||||
super.channelActive(ctx);
|
||||
@@ -133,17 +139,17 @@ public class VisitorChannelHandler extends SimpleChannelInboundHandler<ByteBuf>
|
||||
public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception {
|
||||
|
||||
// 通知代理客户端
|
||||
Channel userChannel = ctx.channel();
|
||||
InetSocketAddress sa = (InetSocketAddress) userChannel.localAddress();
|
||||
Channel visitorChannel = ctx.channel();
|
||||
InetSocketAddress sa = (InetSocketAddress) visitorChannel.localAddress();
|
||||
Channel cmdChannel = ProxyUtil.getCmdChannelByServerPort(sa.getPort());
|
||||
|
||||
if (cmdChannel == null) {
|
||||
// 该端口还没有代理客户端
|
||||
ctx.channel().close();
|
||||
} else {
|
||||
Channel proxyChannel = userChannel.attr(Constants.NEXT_CHANNEL).get();
|
||||
Channel proxyChannel = visitorChannel.attr(Constants.NEXT_CHANNEL).get();
|
||||
if (proxyChannel != null) {
|
||||
proxyChannel.config().setOption(ChannelOption.AUTO_READ, userChannel.isWritable());
|
||||
proxyChannel.config().setOption(ChannelOption.AUTO_READ, visitorChannel.isWritable());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+7
-3
@@ -52,11 +52,15 @@ public class ProxyMapping {
|
||||
return list;
|
||||
}
|
||||
for (PortMappingDO portMapping : portMappingList) {
|
||||
list.add(new ProxyMapping()
|
||||
.setServerPort(portMapping.getServerPort())
|
||||
.setLanInfo(String.format("%s:%s", portMapping.getClientIp(), portMapping.getClientPort())));
|
||||
list.add(build(portMapping));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public static ProxyMapping build(PortMappingDO portMappingDO) {
|
||||
return new ProxyMapping()
|
||||
.setServerPort(portMappingDO.getServerPort())
|
||||
.setLanInfo(String.format("%s:%s", portMappingDO.getClientIp(), portMappingDO.getClientPort()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
@@ -34,6 +34,7 @@ import lombok.experimental.Accessors;
|
||||
public class VisitorChannelAttachInfo {
|
||||
private String visitorId;
|
||||
private String lanInfo;
|
||||
private Integer serverPort;
|
||||
/**
|
||||
* licenseId
|
||||
*/
|
||||
|
||||
+6
-1
@@ -58,6 +58,8 @@ public class LicenseService {
|
||||
private LicenseMapper licenseMapper;
|
||||
@Autowired
|
||||
private UserMapper userMapper;
|
||||
@Autowired
|
||||
private VisitorChannelService visitorChannelService;
|
||||
|
||||
public Page<LicenseListRes> page(PageQuery pageQuery, LicenseListReq req) {
|
||||
Page<LicenseListRes> page = Page.create(pageQuery);
|
||||
@@ -159,7 +161,8 @@ public class LicenseService {
|
||||
*/
|
||||
public LicenseUpdateEnableStatusRes updateEnableStatus(LicenseUpdateEnableStatusReq req) {
|
||||
licenseMapper.updateEnableStatus(req.getId(), req.getEnable(), new Date());
|
||||
|
||||
// 更新VisitorChannel
|
||||
visitorChannelService.updateVisitorChannelByLicenseId(req.getId(), req.getEnable());
|
||||
return new LicenseUpdateEnableStatusRes();
|
||||
}
|
||||
|
||||
@@ -169,6 +172,8 @@ public class LicenseService {
|
||||
*/
|
||||
public void delete(Integer id) {
|
||||
licenseMapper.delete(id);
|
||||
// 更新VisitorChannel
|
||||
visitorChannelService.updateVisitorChannelByLicenseId(id, EnableStatusEnum.DISABLE.getStatus());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+22
@@ -68,6 +68,8 @@ public class PortMappingService {
|
||||
private UserMapper userMapper;
|
||||
@Autowired
|
||||
private PortPoolMapper portPoolMapper;
|
||||
@Autowired
|
||||
private VisitorChannelService visitorChannelService;
|
||||
|
||||
public Page<PortMappingListRes> page(PageQuery pageQuery, PortMappingListReq req) {
|
||||
Page<PortMappingListRes> page = Page.create(pageQuery);
|
||||
@@ -126,6 +128,8 @@ public class PortMappingService {
|
||||
portMappingDO.setCreateTime(now);
|
||||
portMappingDO.setUpdateTime(now);
|
||||
portMappingMapper.add(portMappingDO);
|
||||
// 更新VisitorChannel
|
||||
visitorChannelService.addVisitorChannelByPortMapping(portMappingDO);
|
||||
return new PortMappingCreateRes();
|
||||
}
|
||||
|
||||
@@ -140,6 +144,10 @@ public class PortMappingService {
|
||||
ParamCheckUtil.checkNotNull(portPoolDO, ExceptionConstant.PORT_NOT_EXIST);
|
||||
ParamCheckUtil.checkExpression(null == portMappingMapper.findByPort(req.getServerPort(), Sets.newHashSet(req.getId())), ExceptionConstant.PORT_CANNOT_REPEAT_MAPPING, req.getServerPort());
|
||||
|
||||
// 查询原端口映射
|
||||
PortMappingDO oldPortMappingDO = portMappingMapper.findById(req.getId());
|
||||
ParamCheckUtil.checkNotNull(oldPortMappingDO, ExceptionConstant.PORT_MAPPING_NOT_EXIST);
|
||||
|
||||
PortMappingDO portMappingDO = new PortMappingDO();
|
||||
portMappingDO.setId(req.getId());
|
||||
portMappingDO.setLicenseId(req.getLicenseId());
|
||||
@@ -147,7 +155,10 @@ public class PortMappingService {
|
||||
portMappingDO.setClientIp(req.getClientIp());
|
||||
portMappingDO.setClientPort(req.getClientPort());
|
||||
portMappingDO.setUpdateTime(new Date());
|
||||
portMappingDO.setEnable(EnableStatusEnum.ENABLE.getStatus());
|
||||
portMappingMapper.update(portMappingDO);
|
||||
// 更新VisitorChannel
|
||||
visitorChannelService.updateVisitorChannelByPortMapping(oldPortMappingDO, portMappingDO);
|
||||
return new PortMappingUpdateRes();
|
||||
}
|
||||
|
||||
@@ -193,6 +204,14 @@ public class PortMappingService {
|
||||
|
||||
portMappingMapper.updateEnableStatus(req.getId(), req.getEnable(), new Date());
|
||||
|
||||
// 更新VisitorChannel
|
||||
portMappingDO.setEnable(req.getEnable());
|
||||
if (EnableStatusEnum.ENABLE == EnableStatusEnum.of(req.getEnable())) {
|
||||
visitorChannelService.addVisitorChannelByPortMapping(portMappingDO);
|
||||
} else {
|
||||
visitorChannelService.removeVisitorChannelByPortMapping(portMappingDO);
|
||||
}
|
||||
|
||||
return new PortMappingUpdateEnableStatusRes();
|
||||
}
|
||||
|
||||
@@ -207,6 +226,9 @@ public class PortMappingService {
|
||||
}
|
||||
|
||||
portMappingMapper.delete(id);
|
||||
|
||||
// 更新VisitorChannel
|
||||
visitorChannelService.removeVisitorChannelByPortMapping(portMappingDO);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+15
-1
@@ -52,6 +52,8 @@ public class PortPoolService {
|
||||
|
||||
@Autowired
|
||||
private PortPoolMapper portPoolMapper;
|
||||
@Autowired
|
||||
private VisitorChannelService visitorChannelService;
|
||||
|
||||
public Page<PortPoolListRes> page(PageQuery pageQuery, PortPoolListReq req) {
|
||||
Page<PortPoolListRes> page = Page.create(pageQuery);
|
||||
@@ -75,19 +77,31 @@ public class PortPoolService {
|
||||
.setCreateTime(now)
|
||||
.setUpdateTime(now)
|
||||
);
|
||||
// 更新visitorChannel
|
||||
visitorChannelService.updateVisitorChannelByPortPool(req.getPort(), EnableStatusEnum.ENABLE.getStatus());
|
||||
|
||||
return new PortPoolCreateRes();
|
||||
}
|
||||
|
||||
public PortPoolUpdateEnableStatusRes updateEnableStatus(PortPoolUpdateEnableStatusReq req) {
|
||||
|
||||
PortPoolDO portPoolDO = portPoolMapper.findById(req.getId());
|
||||
ParamCheckUtil.checkNotNull(portPoolDO, ExceptionConstant.PORT_NOT_EXIST);
|
||||
portPoolMapper.updateEnableStatus(req.getId(), req.getEnable(), new Date());
|
||||
|
||||
// 更新visitorChannel
|
||||
visitorChannelService.updateVisitorChannelByPortPool(portPoolDO.getPort(), req.getEnable());
|
||||
|
||||
return new PortPoolUpdateEnableStatusRes();
|
||||
}
|
||||
|
||||
public void delete(Integer id) {
|
||||
PortPoolDO portPoolDO = portPoolMapper.findById(id);
|
||||
ParamCheckUtil.checkNotNull(portPoolDO, ExceptionConstant.PORT_NOT_EXIST);
|
||||
|
||||
portPoolMapper.delete(id);
|
||||
|
||||
// 更新visitorChannel
|
||||
visitorChannelService.updateVisitorChannelByPortPool(portPoolDO.getPort(), EnableStatusEnum.DISABLE.getStatus());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+6
-1
@@ -62,6 +62,8 @@ public class UserService {
|
||||
private UserTokenMapper userTokenMapper;
|
||||
@Autowired
|
||||
private UserLoginRecordMapper userLoginRecordMapper;
|
||||
@Autowired
|
||||
private VisitorChannelService visitorChannelService;
|
||||
|
||||
public LoginRes login(LoginReq req) {
|
||||
UserDO userDO = userMapper.findByLoginName(req.getLoginName());
|
||||
@@ -162,7 +164,8 @@ public class UserService {
|
||||
|
||||
public UserUpdateEnableStatusRes updateEnableStatus(UserUpdateEnableStatusReq req) {
|
||||
userMapper.updateEnableStatus(req.getId(), req.getEnable(), new Date());
|
||||
|
||||
// 更新VisitorChannel
|
||||
visitorChannelService.updateVisitorChannelByUserId(req.getId(), req.getEnable());
|
||||
return new UserUpdateEnableStatusRes();
|
||||
}
|
||||
|
||||
@@ -208,5 +211,7 @@ public class UserService {
|
||||
|
||||
public void delete(Integer id) {
|
||||
userMapper.delete(id);
|
||||
// 更新VisitorChannel
|
||||
visitorChannelService.updateVisitorChannelByUserId(id, EnableStatusEnum.DISABLE.getStatus());
|
||||
}
|
||||
}
|
||||
|
||||
+157
-5
@@ -21,11 +21,22 @@
|
||||
*/
|
||||
package fun.asgc.neutrino.proxy.server.service;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
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.CollectionUtil;
|
||||
import fun.asgc.neutrino.proxy.core.Constants;
|
||||
import fun.asgc.neutrino.proxy.server.constant.EnableStatusEnum;
|
||||
import fun.asgc.neutrino.proxy.server.dal.LicenseMapper;
|
||||
import fun.asgc.neutrino.proxy.server.dal.PortMappingMapper;
|
||||
import fun.asgc.neutrino.proxy.server.dal.PortPoolMapper;
|
||||
import fun.asgc.neutrino.proxy.server.dal.UserMapper;
|
||||
import fun.asgc.neutrino.proxy.server.dal.entity.LicenseDO;
|
||||
import fun.asgc.neutrino.proxy.server.dal.entity.PortMappingDO;
|
||||
import fun.asgc.neutrino.proxy.server.dal.entity.PortPoolDO;
|
||||
import fun.asgc.neutrino.proxy.server.dal.entity.UserDO;
|
||||
import fun.asgc.neutrino.proxy.server.proxy.core.BytesMetricsHandler;
|
||||
import fun.asgc.neutrino.proxy.server.proxy.core.VisitorChannelHandler;
|
||||
import fun.asgc.neutrino.proxy.server.proxy.domain.CmdChannelAttachInfo;
|
||||
@@ -57,16 +68,22 @@ public class VisitorChannelService {
|
||||
@Autowired("serverWorkerGroup")
|
||||
private NioEventLoopGroup serverWorkerGroup;
|
||||
@Autowired
|
||||
private PortMappingService portMappingService;
|
||||
@Autowired
|
||||
private ProxyMutualService proxyMutualService;
|
||||
@Autowired
|
||||
private UserMapper userMapper;
|
||||
@Autowired
|
||||
private LicenseMapper licenseMapper;
|
||||
@Autowired
|
||||
private PortMappingMapper portMappingMapper;
|
||||
@Autowired
|
||||
private PortPoolMapper portPoolMapper;
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
* @param licenseId
|
||||
*/
|
||||
public void initVisitorChannel(Integer licenseId, Channel cmdChannel) {
|
||||
List<PortMappingDO> portMappingList = portMappingService.findEnableListByLicenseId(licenseId);
|
||||
List<PortMappingDO> portMappingList = portMappingMapper.findEnableListByLicenseId(licenseId);
|
||||
// 没有端口映射仍然保持连接
|
||||
ProxyUtil.initProxyInfo(licenseId, ProxyMapping.buildList(portMappingList));
|
||||
|
||||
@@ -77,11 +94,146 @@ public class VisitorChannelService {
|
||||
|
||||
/**
|
||||
* 更新
|
||||
* 触发时机:新增端口映射、修改端口映射、删除端口映射、禁用端口映射、启用端口映射、禁用license、启用license、禁用用户、启用用户
|
||||
* 触发时机:删除端口池、禁用端口池、启用端口池
|
||||
* @param serverPort
|
||||
* @param enable
|
||||
*/
|
||||
public void updateVisitorChannelByPortPool(Integer serverPort, Integer enable) {
|
||||
if (null == serverPort) {
|
||||
return;
|
||||
}
|
||||
List<PortMappingDO> portMappingDOList = portMappingMapper.findListByServerPort(serverPort);
|
||||
if (CollectionUtil.isEmpty(portMappingDOList)) {
|
||||
return;
|
||||
}
|
||||
EnableStatusEnum enableStatusEnum = EnableStatusEnum.of(enable);
|
||||
for (PortMappingDO portMappingDO : portMappingDOList) {
|
||||
if (EnableStatusEnum.DISABLE == enableStatusEnum) {
|
||||
removeVisitorChannelByPortMapping(portMappingDO);
|
||||
} else if (EnableStatusEnum.ENABLE == EnableStatusEnum.of(portMappingDO.getEnable())) {
|
||||
addVisitorChannelByPortMapping(portMappingDO);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新
|
||||
* 触发时机:删除用户、禁用用户、启用用户 (新增、修改用户不涉及VisitorChannel的变更)
|
||||
* @param userId
|
||||
*/
|
||||
public void updateVisitorChannelByUserId(Integer userId, Integer enable) {
|
||||
if (null == userId) {
|
||||
return;
|
||||
}
|
||||
List<LicenseDO> licenseDOList = licenseMapper.listByUserId(userId);
|
||||
if (CollectionUtil.isEmpty(licenseDOList)) {
|
||||
return;
|
||||
}
|
||||
for (LicenseDO licenseDO : licenseDOList) {
|
||||
updateVisitorChannelByLicenseId(licenseDO.getId(), enable);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新
|
||||
* 触发时机:删除license、禁用license、启用license (新增、修改license不涉及VisitorChannel的变更)
|
||||
* 重置licenseKey,不会立即影响已经连接成功的license,如果想要立即影响,请先进行禁用
|
||||
* @param licenseId
|
||||
*/
|
||||
public void UpdateVisitorChannel(Integer licenseId) {
|
||||
public void updateVisitorChannelByLicenseId(Integer licenseId, Integer enable) {
|
||||
if (null == licenseId) {
|
||||
return;
|
||||
}
|
||||
Channel cmdChannel = ProxyUtil.getCmdChannelByLicenseId(licenseId);
|
||||
if (null == cmdChannel) {
|
||||
// 如果不存在有效的cmdChannel,则无需更新VisitorChannel
|
||||
return;
|
||||
}
|
||||
EnableStatusEnum enableStatusEnum = EnableStatusEnum.of(enable);
|
||||
List<PortMappingDO> portMappingDOList = portMappingMapper.findListByLicenseId(licenseId);
|
||||
if (!CollectionUtil.isEmpty(portMappingDOList)) {
|
||||
for (PortMappingDO portMappingDO : portMappingDOList) {
|
||||
if (EnableStatusEnum.DISABLE == enableStatusEnum) {
|
||||
removeVisitorChannelByPortMapping(portMappingDO);
|
||||
} else if (EnableStatusEnum.ENABLE == EnableStatusEnum.of(portMappingDO.getEnable())) {
|
||||
addVisitorChannelByPortMapping(portMappingDO);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新
|
||||
* 触发时机:修改端口映射
|
||||
* @param oldPortMappingDO
|
||||
* @param newPortMappingDO
|
||||
*/
|
||||
public void updateVisitorChannelByPortMapping(PortMappingDO oldPortMappingDO, PortMappingDO newPortMappingDO) {
|
||||
if (null == oldPortMappingDO || null == newPortMappingDO) {
|
||||
return;
|
||||
}
|
||||
removeVisitorChannelByPortMapping(oldPortMappingDO);
|
||||
addVisitorChannelByPortMapping(newPortMappingDO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增VisitorChannel
|
||||
* 触发时机:新增端口映射、启用端口映射
|
||||
* @param portMappingDO
|
||||
*/
|
||||
public void addVisitorChannelByPortMapping(PortMappingDO portMappingDO) {
|
||||
if (null == portMappingDO) {
|
||||
return;
|
||||
}
|
||||
Channel cmdChannel = ProxyUtil.getCmdChannelByLicenseId(portMappingDO.getLicenseId());
|
||||
if (null == cmdChannel) {
|
||||
// 如果不存在有效的cmdChannel,则无需更新VisitorChannel
|
||||
return;
|
||||
}
|
||||
// 判断端口映射是否启用
|
||||
if (EnableStatusEnum.DISABLE != EnableStatusEnum.of(portMappingDO.getEnable())) {
|
||||
LicenseDO licenseDO = licenseMapper.findById(portMappingDO.getLicenseId());
|
||||
// 判断license是否启用
|
||||
if (null != licenseDO && EnableStatusEnum.ENABLE == EnableStatusEnum.of(licenseDO.getEnable())) {
|
||||
UserDO userDO = userMapper.findById(licenseDO.getUserId());
|
||||
// 判断用户是否启用
|
||||
if (null != userDO && EnableStatusEnum.ENABLE == EnableStatusEnum.of(userDO.getEnable())) {
|
||||
PortPoolDO portPoolDO = portPoolMapper.findByPort(portMappingDO.getServerPort());
|
||||
// 判断端口池是否启用
|
||||
if (null != portPoolDO && EnableStatusEnum.ENABLE == EnableStatusEnum.of(portPoolDO.getEnable())) {
|
||||
// 未删除且未禁用,则开启代理
|
||||
ProxyUtil.addProxyInfo(portMappingDO.getLicenseId(), ProxyMapping.build(portMappingDO));
|
||||
ProxyUtil.addCmdChannel(portMappingDO.getLicenseId(), cmdChannel, Sets.newHashSet(portMappingDO.getServerPort()));
|
||||
startUserPortServer(ProxyUtil.getAttachInfo(cmdChannel), Lists.newArrayList(portMappingDO));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除VisitorChannel
|
||||
* 触发时机:删除端口映射、禁用端口映射
|
||||
* @param portMappingDO
|
||||
*/
|
||||
public void removeVisitorChannelByPortMapping(PortMappingDO portMappingDO) {
|
||||
if (null == portMappingDO) {
|
||||
return;
|
||||
}
|
||||
Channel cmdChannel = ProxyUtil.getCmdChannelByLicenseId(portMappingDO.getLicenseId());
|
||||
if (null == cmdChannel) {
|
||||
// 如果不存在有效的cmdChannel,则无需更新VisitorChannel
|
||||
return;
|
||||
}
|
||||
Channel visitorChannel = ProxyUtil.getVisitorChannelByServerPort(portMappingDO.getServerPort());
|
||||
if (null != visitorChannel) {
|
||||
Channel proxyChannel = visitorChannel.attr(Constants.NEXT_CHANNEL).get();
|
||||
if (null != proxyChannel) {
|
||||
proxyChannel.close();
|
||||
}
|
||||
visitorChannel.close();
|
||||
}
|
||||
ProxyUtil.removeProxyInfo(portMappingDO.getServerPort());
|
||||
}
|
||||
|
||||
private void startUserPortServer(CmdChannelAttachInfo cmdChannelAttachInfo, List<PortMappingDO> portMappingList) {
|
||||
|
||||
+47
-7
@@ -21,6 +21,7 @@
|
||||
*/
|
||||
package fun.asgc.neutrino.proxy.server.util;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import fun.asgc.neutrino.core.util.ChannelUtil;
|
||||
import fun.asgc.neutrino.core.util.CollectionUtil;
|
||||
import fun.asgc.neutrino.proxy.core.ChannelAttribute;
|
||||
@@ -50,7 +51,7 @@ public class ProxyUtil {
|
||||
/**
|
||||
* 代理信息映射
|
||||
*/
|
||||
private static final Map<Integer, String> proxyInfoMap = new HashMap<>();
|
||||
private static final Map<Integer, String> proxyInfoMap = new ConcurrentHashMap<>();
|
||||
/**
|
||||
* 服务端口 -> 指令通道映射
|
||||
*/
|
||||
@@ -59,6 +60,10 @@ public class ProxyUtil {
|
||||
* license -> 指令通道映射
|
||||
*/
|
||||
private static Map<Integer, Channel> licenseToCmdChannelMap = new ConcurrentHashMap<>();
|
||||
/**
|
||||
* 服务端口 -> 访问通道映射
|
||||
*/
|
||||
private static Map<Integer, Channel> serverPortToVisitorChannel = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* cmdChannelAttachInfo.getUserChannelMap() 读写锁
|
||||
@@ -72,6 +77,10 @@ public class ProxyUtil {
|
||||
*/
|
||||
public static void initProxyInfo(Integer licenseId, List<ProxyMapping> proxyMappingList) {
|
||||
licenseToServerPortMap.put(licenseId, new HashSet<>());
|
||||
addProxyInfo(licenseId, proxyMappingList);
|
||||
}
|
||||
|
||||
public static void addProxyInfo(Integer licenseId, List<ProxyMapping> proxyMappingList) {
|
||||
if (!CollectionUtil.isEmpty(proxyMappingList)) {
|
||||
for (ProxyMapping proxyMapping : proxyMappingList) {
|
||||
licenseToServerPortMap.get(licenseId).add(proxyMapping.getServerPort());
|
||||
@@ -80,6 +89,18 @@ public class ProxyUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static void addProxyInfo(Integer licenseId, ProxyMapping proxyMapping) {
|
||||
if (null == licenseId || null == proxyMapping) {
|
||||
return;
|
||||
}
|
||||
licenseToServerPortMap.get(licenseId).add(proxyMapping.getServerPort());
|
||||
proxyInfoMap.put(proxyMapping.getServerPort(), proxyMapping.getLanInfo());
|
||||
}
|
||||
|
||||
public static void removeProxyInfo(Integer serverPort) {
|
||||
proxyInfoMap.remove(serverPort);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据licenseId获取服务端端口集合
|
||||
* @param licenseId licenseId
|
||||
@@ -110,12 +131,20 @@ public class ProxyUtil {
|
||||
serverPortToCmdChannelMap.put(port, cmdChannel);
|
||||
}
|
||||
}
|
||||
CmdChannelAttachInfo cmdChannelAttachInfo = getAttachInfo(cmdChannel);
|
||||
if (null == cmdChannelAttachInfo) {
|
||||
cmdChannelAttachInfo = new CmdChannelAttachInfo()
|
||||
.setIp(ChannelUtil.getIP(cmdChannel))
|
||||
.setLicenseId(licenseId)
|
||||
.setVisitorChannelMap(new HashMap<>(16))
|
||||
.setServerPorts(Sets.newHashSet());
|
||||
setAttachInfo(cmdChannel, cmdChannelAttachInfo);
|
||||
}
|
||||
|
||||
if (!CollectionUtil.isEmpty(serverPorts)) {
|
||||
cmdChannelAttachInfo.getServerPorts().addAll(serverPorts);
|
||||
}
|
||||
|
||||
setAttachInfo(cmdChannel, new CmdChannelAttachInfo()
|
||||
.setIp(ChannelUtil.getIP(cmdChannel))
|
||||
.setServerPorts(serverPorts)
|
||||
.setLicenseId(licenseId)
|
||||
.setVisitorChannelMap(new HashMap<>(16)));
|
||||
licenseToCmdChannelMap.put(licenseId, cmdChannel);
|
||||
}
|
||||
|
||||
@@ -174,7 +203,7 @@ public class ProxyUtil {
|
||||
* @param visitorId
|
||||
* @param visitorChannel
|
||||
*/
|
||||
public static void addVisitorChannelToCmdChannel(Channel cmdChannel, String visitorId, Channel visitorChannel) {
|
||||
public static void addVisitorChannelToCmdChannel(Channel cmdChannel, String visitorId, Channel visitorChannel, Integer serverPort) {
|
||||
InetSocketAddress sa = (InetSocketAddress) visitorChannel.localAddress();
|
||||
String lanInfo = getClientLanInfoByServerPort(sa.getPort());
|
||||
CmdChannelAttachInfo cmdChannelAttachInfo = getAttachInfo(cmdChannel);
|
||||
@@ -182,6 +211,7 @@ public class ProxyUtil {
|
||||
setAttachInfo(visitorChannel, new VisitorChannelAttachInfo()
|
||||
.setVisitorId(visitorId)
|
||||
.setLanInfo(lanInfo)
|
||||
.setServerPort(serverPort)
|
||||
.setLicenseId(cmdChannelAttachInfo.getLicenseId())
|
||||
.setIp(ChannelUtil.getIP(visitorChannel))
|
||||
);
|
||||
@@ -191,6 +221,7 @@ public class ProxyUtil {
|
||||
} finally {
|
||||
userChannelMapLock.writeLock().unlock();
|
||||
}
|
||||
serverPortToVisitorChannel.put(serverPort, visitorChannel);
|
||||
}
|
||||
|
||||
public static Channel removeVisitorChannelFromCmdChannel(Channel cmdChannel, String visitorId) {
|
||||
@@ -219,6 +250,15 @@ public class ProxyUtil {
|
||||
return ((CmdChannelAttachInfo)getAttachInfo(cmdChannel)).getVisitorChannelMap().get(visitorId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据服务端口获取访问通道
|
||||
* @param serverPort
|
||||
* @return
|
||||
*/
|
||||
public static Channel getVisitorChannelByServerPort(Integer serverPort) {
|
||||
return serverPortToVisitorChannel.get(serverPort);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取访问者ID
|
||||
*
|
||||
|
||||
+25
-1
@@ -6,7 +6,31 @@
|
||||
- 弹框展示月度明细
|
||||
- 弹框展示今日流量明细
|
||||
- 首页图表📈
|
||||
|
||||
- 1、License在线数
|
||||
- 2、端口映射在线数
|
||||
- 3、今日流量(上行、下行)
|
||||
- 4、历史流量(上行、下行)
|
||||
- 点击1~4 切换列表
|
||||
- 在线License列表
|
||||
- 用户名
|
||||
- License名称
|
||||
- LicenseKey
|
||||
- 在线端口映射列表
|
||||
- 用户名
|
||||
- License名称
|
||||
- 服务端口
|
||||
- 代理客户端
|
||||
- 今日24小时流量列表(按小时到排序)
|
||||
- 用户名
|
||||
- License名称
|
||||
- 时间
|
||||
- 流量
|
||||
- 历史流量列表(取最近12个月按月到排序)
|
||||
- 用户名
|
||||
- License名称
|
||||
- 时间
|
||||
- 流量
|
||||
- 今日流量折线图(上行、下行、总流量,按分钟统计0~24小时)
|
||||
# Bug
|
||||
- windows环境下直接运行发布版的jar包,日志输出乱码
|
||||
- 部份用户windows环境下启动客户端,扫描类个数为0个
|
||||
|
||||
Reference in New Issue
Block a user