!17 优化客户端管理

Merge pull request !17 from Flever_fj/Develop_Branch
This commit is contained in:
seagull 2020-02-26 14:05:26 +08:00 committed by Gitee
commit a8afbe91bb
8 changed files with 65 additions and 42 deletions

View File

@ -39,15 +39,16 @@ public class NettyChannelMap {
if (entry.getValue()==socketChannel){
log.info("#############客户端下线##############");
log.info("下线主机名为:"+entry.getKey());
Client client=clientService.selectClientByClientName(entry.getKey().toString());
Client client=clientService.selectClientByClientIP(entry.getKey().toString());
if(client!=null)
{
client.setStatus(1);
clientMapper.updateClient(client);
//登陆失败删除心跳map中的数据
NettyServer.clientMap.remove(client.getClientName());
NettyServer.clientMap.remove(client.getClientIp());
}
map.remove(entry.getKey());
socketChannel.close();
}
}
}

View File

@ -13,8 +13,8 @@ import com.luckyframe.project.system.client.domain.Client;
import com.luckyframe.project.system.client.mapper.ClientMapper;
import com.luckyframe.project.system.client.service.IClientService;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
@ -22,38 +22,35 @@ import org.quartz.CronTrigger;
import org.quartz.Scheduler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.ReentrantLock;
@Component("ServerHandler")
@ChannelHandler.Sharable
public class ServerHandler extends ChannelInboundHandlerAdapter {
public class ServerHandler extends ChannelHandlerAdapter {
@Autowired
@Resource
private ClientMapper clientMapper;
@Autowired
@Resource
private LuckyFrameConfig lfConfig;
@Autowired
@Resource
private IClientService clientService;
@Autowired
private IJobService jobService;
@Autowired
@Resource
private NettyChannelMap nettyChannelMap;
@Autowired
@Resource
private JobMapper jobMapper;
@Autowired
@Resource
private Scheduler scheduler;
private ChannelHandlerContext ctx;
protected ChannelHandlerContext ctx;
private CountDownLatch latch;
@ -64,7 +61,7 @@ public class ServerHandler extends ChannelInboundHandlerAdapter {
/**
* 同步标志
*/
private int rec;
protected int rec;
/**
* 客户端返回的结果
*/
@ -79,7 +76,9 @@ public class ServerHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
JSONObject json= JSON.parseObject(msg.toString());
/* log.info("心跳发送成功!");*/
/*
* ClientUp客户端启动自动注册到服务端中
* */
if("clientUp".equals(json.get("method")))
{
ChannelMap.setChannel(json.get("hostName").toString(),ctx.channel());
@ -95,9 +94,8 @@ public class ServerHandler extends ChannelInboundHandlerAdapter {
log.info("#############客户端上线##############");
log.info("上线主机名为:"+json.get("hostName"));
String hostName=json.get("hostName").toString();
String clientIp=ctx.channel().remoteAddress().toString();
//检查客户端是否已经注册入库
Client client=clientService.selectClientByClientName(hostName);
Client client=clientService.selectClientByClientIP(hostName);
if(client==null)
{
client = new Client();
@ -109,7 +107,6 @@ public class ServerHandler extends ChannelInboundHandlerAdapter {
if(client.getClientId()==null)
{
//未注册则自动注册入库
int result = 0;
Job job=new Job();
job.setJobName(JobConstants.JOB_JOBNAME_FOR_CLIENTHEART);
job.setJobGroup(JobConstants.JOB_GROUPNAME_FOR_CLIENTHEART);
@ -120,7 +117,7 @@ public class ServerHandler extends ChannelInboundHandlerAdapter {
job.setStatus(JobConstants.JOB_STATUS_FOR_CLIENTHEART);
job.setRemark("");
/*在公共调度表中插入数据*/
result = jobMapper.insertJob(job);
int result = jobMapper.insertJob(job);
if(result<1){
//登录失败断开连接
ctx.close();
@ -147,20 +144,24 @@ public class ServerHandler extends ChannelInboundHandlerAdapter {
if(lfConfig.getVersion().equals(json.get("version"))){
//版本号一致
client.setClientIp(hostName);
client.setClientName(hostName);
client.setRemark("检测客户端状态成功");
client.setStatus(0);
clientMapper.updateClient(client);
if(client.getClientId()!=null)
clientMapper.updateClient(client);
else
clientMapper.insertClient(client);
//登录成功,把channel存到服务端的map中
nettyChannelMap.add(hostName,(SocketChannel)ctx.channel());
//登陆成功放入map中用于心跳
NettyServer.clientMap.put(hostName,"0");
}else{
client.setClientIp(hostName);
client.setClientName(hostName);
client.setRemark("客户端("+json.get("version")+")与服务器("+lfConfig.getVersion()+")版本不一致");
client.setStatus(1);
clientMapper.updateClient(client);
if(client.getClientId()!=null)
clientMapper.updateClient(client);
else
clientMapper.insertClient(client);
//登陆失败删除心跳map中的数据
NettyServer.clientMap.remove(hostName);
//登录失败断开连接
@ -169,6 +170,9 @@ public class ServerHandler extends ChannelInboundHandlerAdapter {
}
else if("return".equals(json.get("method")))
{
/*
* 向客户端请求后返回的数据
* */
Result re =JSONObject.parseObject(json.get("data").toString(),Result.class);
//校验返回的信息是否是同一个信息
if (unidId.equals(re.getUniId())){
@ -179,14 +183,16 @@ public class ServerHandler extends ChannelInboundHandlerAdapter {
}
else if("ping".equals(json.get("method")))
{
/*
* 客户端心跳检测
* */
String hostName=json.get("hostName").toString();
if(NettyServer.clientMap.get(hostName)==null||(!"0".equals(NettyServer.clientMap.get(hostName))))
{
//检查客户端是否已经注册入库
Client client=clientService.selectClientByClientName(hostName);
Client client=clientService.selectClientByClientIP(hostName);
//版本号一致
client.setClientIp(hostName);
client.setClientName(hostName);
client.setRemark("检测客户端状态成功");
client.setStatus(0);
clientMapper.updateClient(client);
@ -199,12 +205,12 @@ public class ServerHandler extends ChannelInboundHandlerAdapter {
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.printStackTrace();
ctx.close();
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
public void channelInactive(ChannelHandlerContext ctx) {
//channel失效从Map中移除
nettyChannelMap.remove((SocketChannel)ctx.channel());
}

View File

@ -100,8 +100,6 @@ public class ClientHeart {
}
} catch (RuntimeException | KeyManagementException | NoSuchAlgorithmException | NoHttpResponseException e) {
if (null==ClientHeart.getClientStatus(params) || ClientHeart.getClientStatus(params) != 1) {
if(params.contains("nettyClient-"))
return;
Client client = new Client();
client.setClientIp(params);
client.setRemark("检测客户端远程异常");

View File

@ -3,7 +3,10 @@ package com.luckyframe.project.system.client.controller;
import java.util.HashMap;
import java.util.List;
import com.luckyframe.common.netty.NettyChannelMap;
import com.luckyframe.common.netty.NettyServer;
import io.netty.channel.Channel;
import io.netty.channel.socket.SocketChannel;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@ -37,6 +40,8 @@ import com.luckyframe.project.system.client.domain.Client;
import com.luckyframe.project.system.client.service.IClientService;
import com.luckyframe.project.system.project.service.IProjectService;
import javax.annotation.Resource;
/**
* 客户端管理 信息操作处理
*
@ -57,6 +62,9 @@ public class ClientController extends BaseController
@Autowired
private IJobService jobService;
@Resource
private NettyChannelMap nettyChannelMap;
@RequiresPermissions("system:client:view")
@GetMapping()
@ -177,6 +185,14 @@ public class ClientController extends BaseController
@ResponseBody
public AjaxResult editSave(Client client)
{
/*不允许通过服务端修改netty方式的客户端IP
* */
Client oldClient=clientService.selectClientById(client.getClientId());
if(oldClient!=null&&oldClient.getClientIp().contains("netty"))
{
if(!oldClient.getClientIp().equals(client.getClientIp()))
return error("修改使用Netty方式的客户端请修改客户端配置");
}
for(Integer projectId:client.getProjectIds()){
if(!PermissionUtils.isProjectPermsPassByProjectId(projectId)){
return error("没有项目【"+projectService.selectProjectById(projectId).getProjectName()+"】修改客户端权限");
@ -194,7 +210,7 @@ public class ClientController extends BaseController
}
client.setRemark("修改客户端信息,重新初始化");
//更新数据删除心跳map中的数据
NettyServer.clientMap.remove(client.getClientName());
NettyServer.clientMap.remove(client.getClientIp());
return toAjax(clientService.updateClient(client));
}
@ -212,7 +228,9 @@ public class ClientController extends BaseController
String[] idList=ids.split(",");
for (String s : idList) {
Client client = clientService.selectClientById(Integer.valueOf(s));
NettyServer.clientMap.remove(client.getClientName());
NettyServer.clientMap.remove(client.getClientIp());
Channel channel=nettyChannelMap.get(client.getClientIp());
nettyChannelMap.remove((SocketChannel)channel);
}
return toAjax(clientService.deleteClientByIds(ids));
}

View File

@ -88,9 +88,9 @@ public interface ClientMapper
/**
* 根据客户端名称查找客户端
* @param clientName
* 根据客户端名称查找客户端(netty方式)
* @param clientIP
* @return
*/
public Client selectClientByClientName(String clientName);
public Client selectClientByClientIP(String clientIP);
}

View File

@ -273,8 +273,8 @@ public class ClientServiceImpl implements IClientService
}
@Override
public Client selectClientByClientName(String clientName) {
Client info = clientMapper.selectClientByClientName(clientName);
public Client selectClientByClientIP(String clientIP) {
Client info = clientMapper.selectClientByClientIP(clientIP);
return info;
}
}

View File

@ -99,9 +99,9 @@ public interface IClientService
/**
* 根据客户端名称查找客户端
* 根据客户端IP查找客户端(netty方式)
* @param clientName
* @return
*/
public Client selectClientByClientName(String clientName);
public Client selectClientByClientIP(String clientIp);
}

View File

@ -103,7 +103,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
select client_id, job_id, client_ip from sys_client where client_ip=#{client_ip}
</select>
<select id="selectClientByClientName" parameterType="String" resultMap="ClientResult">
select client_id, job_id, client_name,status from sys_client where client_name=#{clientName} limit 1
<select id="selectClientByClientIP" parameterType="String" resultMap="ClientResult">
select client_id, job_id, client_name,status from sys_client where client_ip=#{clientIP} limit 1
</select>
</mapper>