增加服务端和客户端通讯方式

This commit is contained in:
fengjian 2020-02-25 11:53:10 +08:00
parent b07d7d61ac
commit f07c034b0e
18 changed files with 681 additions and 5 deletions

View File

@ -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>

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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());
}
}
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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("检测客户端远程异常");

View File

@ -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)

View File

@ -85,4 +85,12 @@ public interface ClientMapper
* @date 2019年2月25日
*/
public Client checkIpUnique(String clientIp);
/**
* 根据客户端名称查找客户端
* @param clientName
* @return
*/
public Client selectClientByClientName(String clientName);
}

View File

@ -271,4 +271,10 @@ public class ClientServiceImpl implements IClientService
}
return returnClientProjects;
}
@Override
public Client selectClientByClientName(String clientName) {
Client info = clientMapper.selectClientByClientName(clientName);
return info;
}
}

View File

@ -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);
}

View File

@ -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:
# 从数据源开关/默认关闭

View File

@ -8,7 +8,10 @@ luckyframe:
copyrightYear: 2019
# 获取ip地址开关
addressEnabled: true
# netty配置
netty:
url: 0.0.0.0
port: 7070
# 开发环境配置
server:
# 服务端口

View File

@ -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>

View File

@ -79,7 +79,6 @@
},
clientIp:{
required:true,
isIp:true,
remote: {
url: ctx + "system/client/checkIpUnique",
type: "post",