增加服务端和客户端通讯方式
This commit is contained in:
parent
b07d7d61ac
commit
f07c034b0e
6
pom.xml
6
pom.xml
|
@ -281,6 +281,12 @@
|
|||
<groupId>org.flywaydb</groupId>
|
||||
<artifactId>flyway-core</artifactId>
|
||||
</dependency>
|
||||
<!--netty-->
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-all</artifactId>
|
||||
<version>5.0.0.Alpha2</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
|
|
@ -1,11 +1,19 @@
|
|||
package com.luckyframe;
|
||||
|
||||
import com.luckyframe.common.netty.NettyServer;
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
/**
|
||||
* 启动LuckyFrameWeb程序
|
||||
* =================================================================
|
||||
|
@ -17,12 +25,34 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
|||
*/
|
||||
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class,FlywayAutoConfiguration.class })
|
||||
@MapperScan("com.luckyframe.project.*.*.mapper")
|
||||
public class LuckyFrameWebApplication
|
||||
public class LuckyFrameWebApplication implements CommandLineRunner
|
||||
{
|
||||
|
||||
@Value("${netty.port}")
|
||||
private int port;
|
||||
|
||||
@Value("${netty.url}")
|
||||
private String url;
|
||||
|
||||
@Autowired
|
||||
private NettyServer server;
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(LuckyFrameWebApplication.class);
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
System.setProperty("spring.devtools.restart.enabled", "false");
|
||||
SpringApplication.run(LuckyFrameWebApplication.class, args);
|
||||
System.out.println("LuckyFrameWeb启动成功......");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void run(String... args) throws Exception {
|
||||
InetSocketAddress address = new InetSocketAddress(url,port);
|
||||
System.out.println("服务端启动成功:"+url+":"+port);
|
||||
server.start(address);
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package com.luckyframe.common.netty;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
|
||||
public class ChannelMap {
|
||||
private static Map<String, Channel> channelMap = new ConcurrentHashMap<>();
|
||||
|
||||
private static Map<String, Lock> channelLockMap = new ConcurrentHashMap<>();
|
||||
|
||||
public static void setChannel(String key,Channel channel){
|
||||
channelMap.put(key,channel);
|
||||
}
|
||||
|
||||
public static Channel getChannel(String key){
|
||||
return channelMap.get(key);
|
||||
}
|
||||
|
||||
public static void setChannelLock(String key,Lock lock){
|
||||
channelLockMap.put(key,lock);
|
||||
}
|
||||
|
||||
public static Lock getChannelLock(String key){
|
||||
return channelLockMap.get(key);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package com.luckyframe.common.netty;
|
||||
|
||||
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.Channel;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@Component
|
||||
public class NettyChannelMap {
|
||||
//logger
|
||||
private static final Logger log = LoggerFactory.getLogger(NettyChannelMap.class);
|
||||
|
||||
private static Map<String, SocketChannel> map=new ConcurrentHashMap<String, SocketChannel>();
|
||||
|
||||
@Autowired
|
||||
private IClientService clientService;
|
||||
|
||||
@Autowired
|
||||
private ClientMapper clientMapper;
|
||||
|
||||
public void add(String clientId,SocketChannel socketChannel){
|
||||
map.put(clientId,socketChannel);
|
||||
}
|
||||
|
||||
public Channel get(String clientId){
|
||||
return map.get(clientId);
|
||||
}
|
||||
|
||||
public void remove(SocketChannel socketChannel){
|
||||
for (Map.Entry entry:map.entrySet()){
|
||||
if (entry.getValue()==socketChannel){
|
||||
log.info("#############客户端下线##############");
|
||||
log.info("下线主机名为:"+entry.getKey());
|
||||
Client client=clientService.selectClientByClientName(entry.getKey().toString());
|
||||
if(client!=null)
|
||||
{
|
||||
client.setStatus(1);
|
||||
clientMapper.updateClient(client);
|
||||
//登陆失败,删除心跳map中的数据
|
||||
NettyServer.clientMap.remove(client.getClientName());
|
||||
}
|
||||
map.remove(entry.getKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
package com.luckyframe.common.netty;
|
||||
|
||||
import io.netty.bootstrap.ServerBootstrap;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.HashMap;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
|
||||
@Component
|
||||
public class NettyServer {
|
||||
|
||||
@Autowired
|
||||
private ServerChannelInitializer serverChannelInitializer;
|
||||
|
||||
//logger
|
||||
private static final Logger log = LoggerFactory.getLogger(NettyServer.class);
|
||||
|
||||
public static final HashMap<String,String> clientMap=new HashMap<>();
|
||||
|
||||
|
||||
public void start(InetSocketAddress address){
|
||||
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
|
||||
EventLoopGroup workerGroup = new NioEventLoopGroup();
|
||||
try {
|
||||
ServerBootstrap bootstrap = new ServerBootstrap()
|
||||
.group(bossGroup,workerGroup)
|
||||
.channel(NioServerSocketChannel.class)
|
||||
.childOption(ChannelOption.SO_KEEPALIVE, true)
|
||||
.option(ChannelOption.SO_BACKLOG, 1024)
|
||||
.childHandler(serverChannelInitializer);
|
||||
// 绑定端口,开始接收进来的连接
|
||||
ChannelFuture future = bootstrap.bind(address).sync();
|
||||
log.info("服务端启动成功,监听端口 " + address.getPort());
|
||||
future.channel().closeFuture().sync();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
bossGroup.shutdownGracefully();
|
||||
workerGroup.shutdownGracefully();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static Result write(Object obj, String tenantId ,String uniId) throws Exception {
|
||||
// 获取锁
|
||||
Lock lock = ChannelMap.getChannelLock(tenantId);
|
||||
try {
|
||||
Channel channel = ChannelMap.getChannel(tenantId);
|
||||
if(channel != null){
|
||||
lock.lock();
|
||||
if(channel.isOpen()){
|
||||
// 设置同步
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
ServerHandler nettyServerHandler = (ServerHandler) channel.pipeline().get("handler");
|
||||
nettyServerHandler.resetSync(latch,1);
|
||||
nettyServerHandler.setUnidId(uniId);
|
||||
channel.writeAndFlush(obj).sync();
|
||||
//同步返回结果
|
||||
if (latch.await(60, TimeUnit.SECONDS)){
|
||||
// printerServerHandler.setTimeout(0);
|
||||
return nettyServerHandler.getResult();
|
||||
}
|
||||
//如果超时,将超时标志设置为1
|
||||
//printerServerHandler.setTimeout(1);
|
||||
log.error("netty请求超时60s");
|
||||
return new Result(2,"请求超时",null);
|
||||
}else{
|
||||
return new Result(0,"客户端已关闭!",null);
|
||||
}
|
||||
}
|
||||
|
||||
}catch (Exception e){
|
||||
e.printStackTrace();
|
||||
return new Result(0,"服务出错!",null);
|
||||
|
||||
}finally {
|
||||
if (lock != null){
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
return new Result(0,"客户端没有连接!",null);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package com.luckyframe.common.netty;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
public class Result implements Serializable {
|
||||
private int code;
|
||||
private Object message;
|
||||
private String uniId;
|
||||
|
||||
public Result(int code, Object message, String uniId) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
this.uniId = uniId;
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public Object getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(Object message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public String getUniId() {
|
||||
return uniId;
|
||||
}
|
||||
|
||||
public void setUniId(String uniId) {
|
||||
this.uniId = uniId;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package com.luckyframe.common.netty;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
|
||||
import io.netty.handler.codec.string.StringDecoder;
|
||||
import io.netty.handler.codec.string.StringEncoder;
|
||||
import io.netty.handler.timeout.IdleStateHandler;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Component
|
||||
public class ServerChannelInitializer extends ChannelInitializer<SocketChannel> {
|
||||
@Autowired
|
||||
private ServerHandler serverHandler;
|
||||
|
||||
@Override
|
||||
protected void initChannel(SocketChannel channel) throws Exception {
|
||||
ByteBuf delimiter = Unpooled.copiedBuffer("$_".getBytes());
|
||||
channel.pipeline().addLast(new DelimiterBasedFrameDecoder(Integer.MAX_VALUE, delimiter));
|
||||
channel.pipeline().addLast("decoder",new StringDecoder(Charset.forName("GBK")));
|
||||
channel.pipeline().addLast("encoder",new StringEncoder(Charset.forName("UTF-8")));
|
||||
channel.pipeline().addLast(new IdleStateHandler(30,0,0,TimeUnit.SECONDS));
|
||||
channel.pipeline().addLast("handler", serverHandler);
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,252 @@
|
|||
package com.luckyframe.common.netty;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.luckyframe.common.constant.JobConstants;
|
||||
import com.luckyframe.common.constant.ScheduleConstants;
|
||||
import com.luckyframe.framework.config.LuckyFrameConfig;
|
||||
import com.luckyframe.project.monitor.job.domain.Job;
|
||||
import com.luckyframe.project.monitor.job.mapper.JobMapper;
|
||||
import com.luckyframe.project.monitor.job.service.IJobService;
|
||||
import com.luckyframe.project.monitor.job.util.ScheduleUtils;
|
||||
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.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
import io.netty.handler.timeout.IdleState;
|
||||
import io.netty.handler.timeout.IdleStateEvent;
|
||||
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 java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
@Component("ServerHandler")
|
||||
@ChannelHandler.Sharable
|
||||
public class ServerHandler extends ChannelInboundHandlerAdapter {
|
||||
|
||||
@Autowired
|
||||
private ClientMapper clientMapper;
|
||||
|
||||
@Autowired
|
||||
private LuckyFrameConfig lfConfig;
|
||||
|
||||
@Autowired
|
||||
private IClientService clientService;
|
||||
|
||||
@Autowired
|
||||
private IJobService jobService;
|
||||
|
||||
@Autowired
|
||||
private NettyChannelMap nettyChannelMap;
|
||||
|
||||
@Autowired
|
||||
private JobMapper jobMapper;
|
||||
|
||||
@Autowired
|
||||
private Scheduler scheduler;
|
||||
|
||||
private ChannelHandlerContext ctx;
|
||||
|
||||
private CountDownLatch latch;
|
||||
|
||||
/**
|
||||
* 消息的唯一ID
|
||||
*/
|
||||
private String unidId = "";
|
||||
/**
|
||||
* 同步标志
|
||||
*/
|
||||
private int rec;
|
||||
/**
|
||||
* 客户端返回的结果
|
||||
*/
|
||||
private Result result;
|
||||
/**
|
||||
* 心跳丢失次数
|
||||
*/
|
||||
private int counter = 0;
|
||||
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(ServerHandler.class);
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
||||
JSONObject json= JSON.parseObject(msg.toString());
|
||||
/* log.info("心跳发送成功!");*/
|
||||
if("clientUp".equals(json.get("method")))
|
||||
{
|
||||
ChannelMap.setChannel(json.get("hostName").toString(),ctx.channel());
|
||||
ChannelMap.setChannelLock(json.get("hostName").toString(),new ReentrantLock());
|
||||
//返回接受成功消息
|
||||
JSONObject tmp=new JSONObject();
|
||||
tmp.put("method","return");
|
||||
tmp.put("message","收到消息");
|
||||
tmp.put("success","1");
|
||||
ctx.writeAndFlush(tmp.toString());
|
||||
|
||||
//接收到客户端上线消息
|
||||
log.info("#############客户端上线##############");
|
||||
log.info("上线主机名为:"+json.get("hostName"));
|
||||
String hostName=json.get("hostName").toString();
|
||||
String clientIp=ctx.channel().remoteAddress().toString();
|
||||
//检查客户端是否已经注册入库
|
||||
Client client=clientService.selectClientByClientName(hostName);
|
||||
if(client==null)
|
||||
{
|
||||
client = new Client();
|
||||
client.setClientIp(hostName);
|
||||
client.setClientName(hostName);
|
||||
client.setCheckinterval(30);
|
||||
client.setClientPath("/TestDriven");
|
||||
}
|
||||
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);
|
||||
job.setMethodName(JobConstants.JOB_METHODNAME_FOR_CLIENTHEART);
|
||||
job.setMethodParams(client.getClientIp());
|
||||
job.setCronExpression("0/"+client.getCheckinterval().toString()+" * * * * ? ");
|
||||
job.setMisfirePolicy(ScheduleConstants.MISFIRE_DO_NOTHING);
|
||||
job.setStatus(JobConstants.JOB_STATUS_FOR_CLIENTHEART);
|
||||
job.setRemark("");
|
||||
/*在公共调度表中插入数据*/
|
||||
result = jobMapper.insertJob(job);
|
||||
if(result<1){
|
||||
//登录失败,断开连接
|
||||
ctx.close();
|
||||
throw new Exception("新增客户端时无法插入任务调度表");
|
||||
}
|
||||
//更新jobLis
|
||||
CronTrigger cronTrigger = ScheduleUtils.getCronTrigger(scheduler, job.getJobId());
|
||||
// 如果不存在,则创建
|
||||
if (cronTrigger == null)
|
||||
{
|
||||
ScheduleUtils.createScheduleJob(scheduler, job);
|
||||
}
|
||||
else
|
||||
{
|
||||
ScheduleUtils.updateScheduleJob(scheduler, job, cronTrigger);
|
||||
}
|
||||
/*在调度预约表中插入数据*/
|
||||
client.setJobId(job.getJobId().intValue());
|
||||
client.setClientIp(hostName);
|
||||
client.setClientName(hostName);
|
||||
clientService.insertClient(client);
|
||||
log.info("主机名为:"+json.get("hostName")+"自动注册成功");
|
||||
}
|
||||
if(lfConfig.getVersion().equals(json.get("version"))){
|
||||
//版本号一致
|
||||
client.setClientIp(hostName);
|
||||
client.setClientName(hostName);
|
||||
client.setRemark("检测客户端状态成功");
|
||||
client.setStatus(0);
|
||||
clientMapper.updateClient(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);
|
||||
//登陆失败,删除心跳map中的数据
|
||||
NettyServer.clientMap.remove(hostName);
|
||||
//登录失败,断开连接
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
else if("return".equals(json.get("method")))
|
||||
{
|
||||
Result re =JSONObject.parseObject(json.get("data").toString(),Result.class);
|
||||
//校验返回的信息是否是同一个信息
|
||||
if (unidId.equals(re.getUniId())){
|
||||
latch.countDown();//消息返回完毕,释放同步锁,具体业务需要判断指令是否匹配
|
||||
rec = 0;
|
||||
result = re;
|
||||
}
|
||||
}
|
||||
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.setClientIp(hostName);
|
||||
client.setClientName(hostName);
|
||||
client.setRemark("检测客户端状态成功");
|
||||
client.setStatus(0);
|
||||
clientMapper.updateClient(client);
|
||||
//更新客户端状态成功
|
||||
NettyServer.clientMap.put(hostName,"0");
|
||||
}
|
||||
}
|
||||
//刷新缓存区
|
||||
ctx.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
||||
cause.printStackTrace();
|
||||
ctx.close();
|
||||
}
|
||||
@Override
|
||||
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
|
||||
//channel失效,从Map中移除
|
||||
nettyChannelMap.remove((SocketChannel)ctx.channel());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
|
||||
if (evt instanceof IdleStateEvent) {
|
||||
IdleStateEvent event = (IdleStateEvent) evt;
|
||||
if (event.state().equals(IdleState.READER_IDLE)){
|
||||
// 空闲40s之后触发 (心跳包丢失)
|
||||
if (counter >= 3) {
|
||||
// 连续丢失3个心跳包 (断开连接)
|
||||
ctx.channel().close().sync();
|
||||
log.error("已与"+ctx.channel().remoteAddress()+"断开连接");
|
||||
} else {
|
||||
counter++;
|
||||
log.debug(ctx.channel().remoteAddress() + "丢失了第 " + counter + " 个心跳包");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelActive(ChannelHandlerContext ctx) throws Exception {
|
||||
super.channelActive(ctx);
|
||||
this.ctx = ctx;
|
||||
}
|
||||
|
||||
public void resetSync(CountDownLatch latch, int rec) {
|
||||
this.latch = latch;
|
||||
this.rec = rec;
|
||||
}
|
||||
|
||||
public void setUnidId(String s){
|
||||
this.unidId = s;
|
||||
}
|
||||
|
||||
public Result getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -16,7 +16,11 @@ import java.security.KeyManagementException;
|
|||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.luckyframe.common.netty.NettyServer;
|
||||
import com.luckyframe.common.netty.Result;
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.NoHttpResponseException;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
|
@ -47,6 +51,38 @@ public class HttpRequest {
|
|||
* @date 2019年5月14日
|
||||
*/
|
||||
public static String httpClientPost(String urlParam,String jsonparams,Integer socketTimeout) throws NoSuchAlgorithmException, KeyManagementException, UnsupportedEncodingException, IOException{
|
||||
//测试netty同步等待
|
||||
if(urlParam.contains("netty"))
|
||||
{
|
||||
int firstIndex=urlParam.indexOf("netty");
|
||||
int lastIndex=urlParam.lastIndexOf(":");
|
||||
String clientId=urlParam.substring(firstIndex,lastIndex);
|
||||
JSONObject tmp=new JSONObject();
|
||||
String uuid= UUID.randomUUID().toString();
|
||||
//封装调度参数
|
||||
String tmpMethod=urlParam.substring(lastIndex+5);
|
||||
tmp.put("method","run");
|
||||
tmp.put("data",jsonparams);
|
||||
tmp.put("uuid",uuid);
|
||||
tmp.put("url",tmpMethod);
|
||||
tmp.put("getOrPost","post");
|
||||
tmp.put("socketTimeout",socketTimeout);
|
||||
Result re= null;
|
||||
try {
|
||||
re = NettyServer.write(tmp.toString(),clientId, uuid);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if(1==re.getCode())
|
||||
{
|
||||
//请求成功,返回结果
|
||||
return (String)re.getMessage();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
StringBuffer resultBuffer = null;
|
||||
CloseableHttpClient httpclient=HttpClients.createDefault();
|
||||
HttpPost httpPost = new HttpPost(urlParam);
|
||||
|
@ -106,6 +142,38 @@ public class HttpRequest {
|
|||
* @date 2019年5月14日
|
||||
*/
|
||||
public static String httpClientGet(String urlParam, Map<String, Object> params,Integer socketTimeout) throws NoSuchAlgorithmException, KeyManagementException,NoHttpResponseException {
|
||||
//测试netty同步等待
|
||||
if(urlParam.contains("netty"))
|
||||
{
|
||||
int firstIndex=urlParam.indexOf("netty");
|
||||
int lastIndex=urlParam.lastIndexOf(":");
|
||||
String clientId=urlParam.substring(firstIndex,lastIndex);
|
||||
JSONObject tmp=new JSONObject();
|
||||
String uuid= UUID.randomUUID().toString();
|
||||
//封装调度参数
|
||||
String tmpMethod=urlParam.substring(lastIndex+5);
|
||||
tmp.put("method","run");
|
||||
tmp.put("data",params);
|
||||
tmp.put("uuid",uuid);
|
||||
tmp.put("url",tmpMethod);
|
||||
tmp.put("getOrPost","get");
|
||||
tmp.put("socketTimeout",socketTimeout);
|
||||
Result re= null;
|
||||
try {
|
||||
re = NettyServer.write(tmp.toString(),clientId, uuid);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if(1==re.getCode())
|
||||
{
|
||||
//请求成功,返回结果
|
||||
return (String)re.getMessage();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
StringBuffer resultBuffer = null;
|
||||
CloseableHttpClient httpclient=HttpClients.createDefault();
|
||||
BufferedReader br = null;
|
||||
|
@ -170,6 +238,37 @@ public class HttpRequest {
|
|||
* @date 2019年3月15日
|
||||
*/
|
||||
public static String httpClientUploadFile(String urlParam, String loadpath, File file) throws NoSuchAlgorithmException, KeyManagementException, HttpHostConnectException {
|
||||
//测试netty同步等待
|
||||
if(urlParam.contains("netty"))
|
||||
{
|
||||
int firstIndex=urlParam.indexOf("netty");
|
||||
int lastIndex=urlParam.lastIndexOf(":");
|
||||
String clientId=urlParam.substring(firstIndex,lastIndex);
|
||||
JSONObject tmp=new JSONObject();
|
||||
String uuid= UUID.randomUUID().toString();
|
||||
//封装调度参数
|
||||
String tmpMethod=urlParam.substring(lastIndex+5);
|
||||
tmp.put("method","download");
|
||||
tmp.put("path",loadpath);
|
||||
tmp.put("fileName",file.getName());
|
||||
tmp.put("uuid",uuid);
|
||||
tmp.put("url",tmpMethod);
|
||||
Result re= null;
|
||||
try {
|
||||
re = NettyServer.write(tmp.toString(),clientId, uuid);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if(1==re.getCode())
|
||||
{
|
||||
//请求成功,返回结果
|
||||
return "上传成功";
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
StringBuffer resultBuffer = null;
|
||||
CloseableHttpClient httpclient=HttpClients.createDefault();
|
||||
HttpPost httpPost = new HttpPost(urlParam);
|
||||
|
|
|
@ -100,6 +100,8 @@ 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("检测客户端远程异常");
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.luckyframe.project.system.client.controller;
|
|||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import com.luckyframe.common.netty.NettyServer;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
|
@ -47,7 +48,7 @@ import com.luckyframe.project.system.project.service.IProjectService;
|
|||
public class ClientController extends BaseController
|
||||
{
|
||||
private String prefix = "system/client";
|
||||
|
||||
|
||||
@Autowired
|
||||
private IClientService clientService;
|
||||
|
||||
|
@ -192,6 +193,8 @@ public class ClientController extends BaseController
|
|||
return AjaxResult.error();
|
||||
}
|
||||
client.setRemark("修改客户端信息,重新初始化");
|
||||
//更新数据,删除心跳map中的数据
|
||||
NettyServer.clientMap.remove(client.getClientName());
|
||||
return toAjax(clientService.updateClient(client));
|
||||
}
|
||||
|
||||
|
@ -206,6 +209,11 @@ public class ClientController extends BaseController
|
|||
{
|
||||
try
|
||||
{
|
||||
String[] idList=ids.split(",");
|
||||
for (String s : idList) {
|
||||
Client client = clientService.selectClientById(Integer.valueOf(s));
|
||||
NettyServer.clientMap.remove(client.getClientName());
|
||||
}
|
||||
return toAjax(clientService.deleteClientByIds(ids));
|
||||
}
|
||||
catch (BusinessException e)
|
||||
|
|
|
@ -85,4 +85,12 @@ public interface ClientMapper
|
|||
* @date 2019年2月25日
|
||||
*/
|
||||
public Client checkIpUnique(String clientIp);
|
||||
|
||||
|
||||
/**
|
||||
* 根据客户端名称查找客户端
|
||||
* @param clientName
|
||||
* @return
|
||||
*/
|
||||
public Client selectClientByClientName(String clientName);
|
||||
}
|
|
@ -271,4 +271,10 @@ public class ClientServiceImpl implements IClientService
|
|||
}
|
||||
return returnClientProjects;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Client selectClientByClientName(String clientName) {
|
||||
Client info = clientMapper.selectClientByClientName(clientName);
|
||||
return info;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -96,4 +96,12 @@ public interface IClientService
|
|||
* @date 2019年3月14日
|
||||
*/
|
||||
public List<Client> selectClientsByProjectId(int projectId);
|
||||
|
||||
|
||||
/**
|
||||
* 根据客户端名称查找客户端
|
||||
* @param clientName
|
||||
* @return
|
||||
*/
|
||||
public Client selectClientByClientName(String clientName);
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ spring:
|
|||
master:
|
||||
url: jdbc:mysql://localhost:3306/luckyframe?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
|
||||
username: root
|
||||
password:
|
||||
password:
|
||||
# 从库数据源
|
||||
slave:
|
||||
# 从数据源开关/默认关闭
|
||||
|
|
|
@ -8,7 +8,10 @@ luckyframe:
|
|||
copyrightYear: 2019
|
||||
# 获取ip地址开关
|
||||
addressEnabled: true
|
||||
|
||||
# netty配置
|
||||
netty:
|
||||
url: 0.0.0.0
|
||||
port: 7070
|
||||
# 开发环境配置
|
||||
server:
|
||||
# 服务端口
|
||||
|
|
|
@ -102,4 +102,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<select id="checkIpUnique" parameterType="String" resultMap="ClientResult">
|
||||
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>
|
||||
</mapper>
|
|
@ -79,7 +79,6 @@
|
|||
},
|
||||
clientIp:{
|
||||
required:true,
|
||||
isIp:true,
|
||||
remote: {
|
||||
url: ctx + "system/client/checkIpUnique",
|
||||
type: "post",
|
||||
|
|
Loading…
Reference in New Issue