Merge branch 'Develop_Branch' of

https://gitee.com/fjcode/LuckyFrameClient into Develop_Branch

# Conflicts:
#	src/main/java/luckyclient/netty/ClientHandler.java
This commit is contained in:
seagull 2020-03-04 09:26:46 +08:00
commit f82667d909
3 changed files with 424 additions and 428 deletions

View File

@ -1,68 +1,68 @@
<html> <html>
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type="text/css"> <style type="text/css">
body { body {
margin:0; margin:0;
padding:0; padding:0;
font-family:Arial, Helvetica, sans-serif; font-family:Arial, Helvetica, sans-serif;
font-size:12px; font-size:12px;
color:#6a6a6a; color:#6a6a6a;
} }
a { a {
font-size:13px font-size:13px
} }
</style> </style>
</head> </head>
<body> <body>
<table width="780" border="0" align="center" cellpadding="0" cellspacing="0" > <table width="780" border="0" align="center" cellpadding="0" cellspacing="0" >
<tr> <tr>
<td height="10">&nbsp;</td> <td height="10">&nbsp;</td>
</tr> </tr>
<tr> <tr>
<td valign="top" style="border-left:1px solid #CCC; border-right:1px solid #CCC;border-top:1px solid #CCC;"> <td valign="top" style="border-left:1px solid #CCC; border-right:1px solid #CCC;border-top:1px solid #CCC;">
<table width="620" border="0" align="center" cellpadding="0" cellspacing="0"> <table width="620" border="0" align="center" cellpadding="0" cellspacing="0">
<tr> <tr>
<td height="92" style="background-color:rgba(51,204,255,0.6);"> <td height="92" style="background-color:rgba(51,204,255,0.6);">
<a href="http://www.luckyframe.cn" title="LuckyFrame" target="_blank"><img src="http://${webip}:${webport}/img/maillogo.png" alt="LuckyFrame" width="300" height="92" border="0" /></a></td> <a href="http://www.luckyframe.cn" title="LuckyFrame" target="_blank"><img src="http://${webip}:${webport}/img/maillogo.png" alt="LuckyFrame" width="300" height="92" border="0" /></a></td>
</tr> </tr>
<tr> <tr>
<td height="1" colspan="2"><hr style="border-bottom:5px solid #f1f1f1; display:block;" /></td> <td height="1" colspan="2"><hr style="border-bottom:5px solid #f1f1f1; display:block;" /></td>
</tr> </tr>
<tr> <tr>
<td height="20" colspan="2">&nbsp;</td> <td height="20" colspan="2">&nbsp;</td>
</tr> </tr>
<tr> <tr>
<td height="40" colspan="2" style="font-size:12px; text-indent:25px;"><div style="margin: 0px auto; padding: 0px 10px; width: 680px;"> <td height="40" colspan="2" style="font-size:12px; text-indent:25px;"><div style="margin: 0px auto; padding: 0px 10px; width: 680px;">
<div style="color: rgb(77, 77, 77); line-height: 1.5; font-size: 14px; margin-bottom: 25px;"> <div style="color: rgb(77, 77, 77); line-height: 1.5; font-size: 14px; margin-bottom: 25px;">
<strong style="margin-bottom: 15px; display: block;">亲爱的Tester 您好!以下是自动化任务【${jobname}】执行情况。</strong> <strong style="margin-bottom: 15px; display: block;">亲爱的Tester 您好!以下是自动化任务【${jobname}】执行情况。</strong>
<p><b>自动构建状态: </b> 【<font color='#5CACEE'>${buildstatus}</font>】</p> <p><b>自动构建状态: </b> 【<font color='#5CACEE'>${buildstatus}</font>】</p>
<p><b>自动重启TOMCAT状态 </b> 【<font color='#5CACEE'>${restartstatus}</font>】</p> <p><b>自动重启TOMCAT状态 </b> 【<font color='#5CACEE'>${restartstatus}</font>】</p>
<br> <br>
<p><b>本次任务预期执行用例共【<font color='#2828FF'>${casecount}</font>】条,耗時【${time}】</b></p> <p><b>本次任务预期执行用例共【<font color='#2828FF'>${casecount}</font>】条,耗時【${time}】</b></p>
<p><b>用例执行成功: </b> 【<font color='#28FF28'>${casesuc}</font>】</p> <p><b>用例执行成功: </b> 【<font color='#28FF28'>${casesuc}</font>】</p>
<p><b>用例执行失败: </b> 【<font color='#FF0000'>${casefail}</font>】</p> <p><b>用例执行失败: </b> 【<font color='#FF0000'>${casefail}</font>】</p>
<p><b>用例有可能由于脚本原因未成功解析被锁定:</b> 【<font color='#AE57A4'>${caselock}</font>】</p> <p><b>用例有可能由于脚本原因未成功解析被锁定:</b> 【<font color='#AE57A4'>${caselock}</font>】</p>
<p><b>用例由于长时间未收到接口Response未执行完成</b> 【<font color='#FFAD86'>${caseunex}</font>】</p> <p><b>用例由于长时间未收到接口Response未执行完成</b> 【<font color='#FFAD86'>${caseunex}</font>】</p>
<p>&nbsp;</p> <p>&nbsp;</p>
<p> 此为自动化平台LuckyFrame的系统邮件请勿回复</p> <p> 此为自动化平台LuckyFrame的系统邮件请勿回复</p>
<p> 请及时前往<a href='http://${webip}:${webport}'>LuckyFrame平台</a>查看您的任务执行的更多细节</p> <p> 请及时前往<a href='http://${webip}:${webport}'>LuckyFrame平台</a>查看您的任务执行的更多细节</p>
<p> <p>
</div> </div>
</td> </td>
</tr> </tr>
<tr> <tr>
<td height="10" colspan="2">&nbsp;</td> <td height="10" colspan="2">&nbsp;</td>
</tr> </tr>
<tr> <tr>
<td height="40" colspan="2">&nbsp;</td> <td height="40" colspan="2">&nbsp;</td>
</tr> </tr>
</table></td> </table></td>
</tr> </tr>
<tr> <tr>
<td height="30" align="center" bgcolor="#E3E3E3" style="font-size:12px; color:#666;">Copyright &copy; &nbsp;&nbsp;<a href='http://www.luckyframe.cn'>LuckyFrame</a>&nbsp;&nbsp; <td height="30" align="center" bgcolor="#E3E3E3" style="font-size:12px; color:#666;">Copyright &copy; &nbsp;&nbsp;<a href='http://www.luckyframe.cn'>LuckyFrame</a>&nbsp;&nbsp;
2017-2099 All Right Reserved </td> 2017-2099 All Right Reserved </td>
</tr> </tr>
</table> </table>
</body> </body>
</html> </html>

View File

@ -1,268 +1,264 @@
package luckyclient.netty; package luckyclient.netty;
import java.io.*; import java.io.*;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.Logger;
import org.springframework.core.io.ClassPathResource; import org.slf4j.LoggerFactory;
import org.springframework.core.io.Resource; import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.support.PropertiesLoaderUtils; import org.springframework.core.io.Resource;
import com.alibaba.fastjson.JSON; import org.springframework.core.io.support.PropertiesLoaderUtils;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSON;
import io.netty.buffer.Unpooled; import com.alibaba.fastjson.JSONObject;
import io.netty.channel.ChannelHandlerAdapter; import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.EventLoop; import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.timeout.IdleState; import io.netty.channel.EventLoop;
import io.netty.handler.timeout.IdleStateEvent; import io.netty.handler.timeout.IdleState;
import luckyclient.utils.config.SysConfig; import io.netty.handler.timeout.IdleStateEvent;
import luckyclient.utils.config.SysConfig;
public class ClientHandler extends ChannelHandlerAdapter {
public class ClientHandler extends ChannelHandlerAdapter {
//从application.properties文件中获取用到的参数;
private static Resource resource = new ClassPathResource("application.properties"); //从application.properties文件中获取用到的参数;
private static Properties props; private static Resource resource = new ClassPathResource("application.properties");
private static Properties props;
static {
try { static {
props = PropertiesLoaderUtils.loadProperties(resource); try {
} catch (IOException e) { props = PropertiesLoaderUtils.loadProperties(resource);
e.printStackTrace(); } catch (IOException e) {
} e.printStackTrace();
} }
}
private static String port = props.getProperty("server.port");
private static String port = props.getProperty("server.port");
static final String ECHO_REQ = "$_";
private static final Logger log = LoggerFactory.getLogger(ClientHandler.class);
private static final Logger log = LoggerFactory.getLogger(ClientHandler.class);
private static final String HOST_NAME = SysConfig.getConfiguration().getProperty("host.name");
private static final String HOST_NAME= SysConfig.getConfiguration().getProperty("host.name");
private static final String CLIENT_VERSION = SysConfig.getConfiguration().getProperty("client.verison");
private static final String CLIENT_VERSION= SysConfig.getConfiguration().getProperty("client.verison");
private static final String SERVER_IP = SysConfig.getConfiguration().getProperty("server.web.ip");
private static final String SERVER_IP= SysConfig.getConfiguration().getProperty("server.web.ip");
private static final String SERVER_PORT = SysConfig.getConfiguration().getProperty("server.web.port");
private static final String SERVER_PORT= SysConfig.getConfiguration().getProperty("server.web.port");
private int byteRead;
private int byteRead;
private volatile int start = 0; private volatile int lastLength = 0;
private volatile int lastLength = 0; public RandomAccessFile randomAccessFile;
public RandomAccessFile randomAccessFile;
private static ChannelHandlerContext ctx;
private static ChannelHandlerContext ctx; public ClientHandler() throws IOException {
}
public ClientHandler() throws IOException {
} @Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws UnsupportedEncodingException, InterruptedException {
@Override //服务端消息处理,如果接收到测试任务方法则直接产生一个http请求并发送请求到本地
public void channelRead(ChannelHandlerContext ctx, Object msg) throws UnsupportedEncodingException, InterruptedException { String jsonStr = new String(msg.toString().getBytes(), "UTF-8");
//服务端消息处理,如果接收到测试任务方法则直接产生一个http请求并发送请求到本地 JSONObject json = new JSONObject();
String jsonStr=new String(msg.toString().getBytes(),"UTF-8"); try {
JSONObject json=new JSONObject(); json = JSON.parseObject(jsonStr);
try
{ } catch (Exception e) {
json= JSON.parseObject(jsonStr); log.error("收到服务端非Json消息,但是异常:" + jsonStr);
return;
}catch (Exception e) }
{ log.info("收到服务端消息:" + json.toString());
System.out.println("收到服务端非Json消息"+jsonStr); //解析消息
return; if ("run".equals(json.get("method"))) {
} try {
System.out.println("收到服务端消息:"+json.toString()); //返回请求
//解析消息 JSONObject re = new JSONObject();
if("run".equals(json.get("method"))){ re.put("method", "return");
try { Result result = new Result(1, "同步等待消息返回", json.get("uuid").toString(), null);
//返回请求 //如果是调度请求则发起一个HTTP请求
JSONObject re=new JSONObject(); //获取是get方法还是post方法
re.put("method","return"); String getOrPost = json.get("getOrPost").toString();
Result result=new Result(1,"同步等待消息返回",json.get("uuid").toString(),null); String urlParam = "http://127.0.0.1:" + port + "/" + json.get("url").toString();
//如果是调度请求则发起一个HTTP请求 Integer socketTimeout = Integer.valueOf(json.get("socketTimeout").toString());
//获取是get方法还是post方法 String tmpResult = "";
String getOrPost=json.get("getOrPost").toString(); if ("get".equals(getOrPost)) {
String urlParam="http://127.0.0.1:"+port+"/"+json.get("url").toString(); @SuppressWarnings("unchecked")
Integer socketTimeout=Integer.valueOf(json.get("socketTimeout").toString()); Map<String, Object> jsonparams = (Map<String, Object>) json.get("data");
String tmpResult=""; //get方法
if("get".equals(getOrPost)) try {
{ tmpResult = HttpRequest.httpClientGet(urlParam, jsonparams, socketTimeout);
@SuppressWarnings("unchecked") } catch (Exception e) {
Map<String,Object> jsonparams = (Map<String,Object>)json.get("data"); log.error("转发服务端GET请求出错");
//get方法 }
try { } else {
tmpResult=HttpRequest.httpClientGet(urlParam,jsonparams,socketTimeout); String jsonparams = json.get("data").toString();
} catch (Exception e) { //post方法
System.out.println("转发服务端GET请求出错"); try {
} tmpResult = HttpRequest.httpClientPost(urlParam, jsonparams, socketTimeout);
} } catch (Exception e) {
else log.error("转发服务端POST请求出错");
{ }
String jsonparams=json.get("data").toString(); }
//post方法 result.setMessage(tmpResult);
try { re.put("data", result);
tmpResult=HttpRequest.httpClientPost(urlParam,jsonparams,socketTimeout); sendMessage(re.toString());
} catch (Exception e) { } catch (InterruptedException e) {
System.out.println("转发服务端POST请求出错"); e.printStackTrace();
} }
} } else if ("download".equals(json.get("method"))) {
result.setMessage(tmpResult); String loadpath = json.get("path").toString();
re.put("data",result); String path = System.getProperty("user.dir") + loadpath;
sendMessage(re.toString()); String fileName = json.get("fileName").toString();
} catch (InterruptedException e) { //发出http请求下载文件
e.printStackTrace(); try {
} HttpRequest.downLoadFromUrl("http://" + SERVER_IP + ":" + SERVER_PORT + "/common/download?fileName=" + fileName, fileName, path);
} //返回请求
else if("download".equals(json.get("method"))){ JSONObject re = new JSONObject();
String loadpath=json.get("path").toString(); Result result = new Result(1, "上传成功", json.get("uuid").toString(), null);
String path = System.getProperty("user.dir")+loadpath; re.put("method", "return");
String fileName=json.get("fileName").toString(); re.put("data", result);
//发出http请求下载文件 sendMessage(re.toString());
try { log.info("下载驱动包成功,路径为:" + path + ";文件名为:" + fileName);
HttpRequest.downLoadFromUrl("http://"+SERVER_IP+":"+SERVER_PORT+"/common/download?fileName="+fileName,fileName,path); } catch (Exception e) {
//返回请求 e.printStackTrace();
JSONObject re=new JSONObject(); //返回请求
Result result=new Result(1,"上传成功",json.get("uuid").toString(),null); JSONObject re = new JSONObject();
re.put("method","return"); Result result = new Result(0, "上传失败", json.get("uuid").toString(), null);
re.put("data",result); re.put("method", "return");
sendMessage(re.toString()); re.put("data", result);
System.out.println("下载驱动包成功,路径为:"+path+";文件名为:"+fileName); sendMessage(re.toString());
} catch (Exception e) { log.error("下载驱动包失败,路径为:" + path + ";文件名为:" + fileName);
e.printStackTrace(); }
//返回请求 } else if ("upload".equals(json.get("method"))) {
JSONObject re=new JSONObject(); try {
Result result=new Result(0,"上传失败",json.get("uuid").toString(),null); //上传截图到服务器
re.put("method","return"); @SuppressWarnings("unchecked")
re.put("data",result); Map<String, Object> jsonparams = (Map<String, Object>) json.get("data");
sendMessage(re.toString()); String fileName = jsonparams.get("imgName").toString();
System.out.println("下载驱动包失败,路径为:"+path+";文件名为:"+fileName); String ctxPath = System.getProperty("user.dir") + File.separator + "log" + File.separator + "ScreenShot" + File.separator + fileName;
} File file = new File(ctxPath);
} int start = Integer.valueOf(json.get("start").toString());
else if("upload".equals(json.get("method"))) FileUploadFile fileUploadFile = new FileUploadFile();
{ fileUploadFile.setFile(file);
//上传截图到服务器 if (start != -1) {
@SuppressWarnings("unchecked") if (start == 0)
Map<String,Object> jsonparams = (Map<String,Object>)json.get("data"); lastLength = 1024 * 10;
String fileName=jsonparams.get("imgName").toString(); randomAccessFile = new RandomAccessFile(fileUploadFile.getFile(), "r");
String ctxPath = System.getProperty("user.dir")+File.separator+"log"+File.separator+"ScreenShot"+File.separator+fileName; randomAccessFile.seek(start); //将文件定位到start
File file=new File(ctxPath); log.info("长度:" + (randomAccessFile.length() - start));
start=Integer.valueOf(json.get("start").toString()); int a = (int) (randomAccessFile.length() - start);
FileUploadFile fileUploadFile=new FileUploadFile(); int b = (int) (randomAccessFile.length() / 1024 * 2);
fileUploadFile.setFile(file); if (a < lastLength) {
if (start != -1) { lastLength = a;
try { }
if(start==0) log.info("文件长度:" + (randomAccessFile.length()) + ",start:" + start + ",a:" + a + ",b:" + b + ",lastLength:" + lastLength);
lastLength = 1024 * 10; byte[] bytes = new byte[lastLength];
randomAccessFile = new RandomAccessFile(fileUploadFile.getFile(), "r"); log.info("bytes的长度是=" + bytes.length);
randomAccessFile.seek(start); //将文件定位到start if ((byteRead = randomAccessFile.read(bytes)) != -1 && (randomAccessFile.length() - start) > 0) {
System.out.println("长度:" + (randomAccessFile.length() - start)); log.info("byteRead = " + byteRead);
int a = (int) (randomAccessFile.length() - start); fileUploadFile.setEndPos(byteRead);
int b = (int) (randomAccessFile.length() / 1024 * 2); fileUploadFile.setBytes(bytes);
if (a < lastLength) { //返回请求
lastLength = a; JSONObject re = new JSONObject();
} Result result = new Result(1, "上传成功", json.get("uuid").toString(), fileUploadFile);
System.out.println("文件长度:" + (randomAccessFile.length()) + ",start:" + start + ",a:" + a + ",b:" + b + ",lastLength:" + lastLength); re.put("method", "upload");
byte[] bytes = new byte[lastLength]; re.put("data", result);
System.out.println("bytes的长度是="+bytes.length); re.put("uuid", json.get("uuid").toString());
if ((byteRead = randomAccessFile.read(bytes)) != -1 && (randomAccessFile.length() - start) > 0) { re.put("imgName", fileName);
System.out.println("byteRead = " + byteRead); re.put("start", start);
fileUploadFile.setEndPos(byteRead); sendMessage(re.toString());
fileUploadFile.setBytes(bytes); try {
//返回请求 ctx.writeAndFlush(fileUploadFile);
JSONObject re=new JSONObject(); } catch (Exception e) {
Result result=new Result(1,"上传成功",json.get("uuid").toString(),fileUploadFile); e.printStackTrace();
re.put("method","upload"); }
re.put("data",result); } else {
re.put("uuid",json.get("uuid").toString()); randomAccessFile.close();
re.put("imgName",fileName); log.info("文件已经读完channelRead()--------" + byteRead);
sendMessage(re.toString()); //返回请求
try { JSONObject re = new JSONObject();
ctx.writeAndFlush(fileUploadFile); Result result = new Result(1, "上传成功", json.get("uuid").toString(), null);
} catch (Exception e) { re.put("method", "return");
e.printStackTrace(); re.put("data", result);
} sendMessage(re.toString());
} else {
randomAccessFile.close(); }
System.out.println("文件已经读完channelRead()--------" + byteRead); }
//返回请求 } catch (Exception e) {
JSONObject re=new JSONObject(); e.printStackTrace();
Result result=new Result(1,"上传成功",json.get("uuid").toString(),null); //返回请求
re.put("method","return"); JSONObject re = new JSONObject();
re.put("data",result); Result result = new Result(0, "异常错误", json.get("uuid").toString(), null);
sendMessage(re.toString()); re.put("method", "return");
re.put("data", result);
} sendMessage(re.toString());
} catch (Exception e) { }
e.printStackTrace();
} }
} }
} @Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
} //发送客户端登录消息
JSONObject json = new JSONObject();
@Override json.put("hostName", HOST_NAME);
public void channelActive(ChannelHandlerContext ctx) throws Exception { json.put("version", CLIENT_VERSION);
//发送客户端登录消息 json.put("method", "clientUp");
JSONObject json=new JSONObject(); ClientHandler.ctx = ctx;
json.put("hostName",HOST_NAME); sendMessage(json.toString());
json.put("version",CLIENT_VERSION); }
json.put("method","clientUp");
ClientHandler.ctx=ctx; @Override
sendMessage(json.toString()); public void channelInactive(ChannelHandlerContext ctx) {
} log.info("连接已断开,正在尝试重连...");
//使用过程中断线重连
@Override final EventLoop eventLoop = ctx.channel().eventLoop();
public void channelInactive(ChannelHandlerContext ctx) eventLoop.schedule(new Runnable() {
{ @Override
System.out.println("连接已断开,正在尝试重连..."); public void run() {
//使用过程中断线重连 try {
final EventLoop eventLoop = ctx.channel().eventLoop(); NettyClient.start();
eventLoop.schedule(new Runnable() { } catch (InterruptedException e) {
@Override e.printStackTrace();
public void run() { }
try { }
NettyClient.start(); }, 1, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace(); ctx.fireChannelInactive();
} }
}
}, 1, TimeUnit.SECONDS); @Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
ctx.fireChannelInactive(); cause.printStackTrace();
} ctx.close();
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { @Override
cause.printStackTrace(); public void userEventTriggered(ChannelHandlerContext ctx, Object evt)
ctx.close(); throws Exception {
} if (evt instanceof IdleStateEvent) {
IdleStateEvent event = (IdleStateEvent) evt;
@Override if (event.state().equals(IdleState.READER_IDLE)) {
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) /**发送心跳,保持长连接*/
throws Exception { JSONObject json = new JSONObject();
if (evt instanceof IdleStateEvent) { json.put("method", "ping");
IdleStateEvent event = (IdleStateEvent) evt; json.put("hostName", HOST_NAME);
if (event.state().equals(IdleState.READER_IDLE)) { //ctx.channel().writeAndFlush(json.toString() + "$_").sync();
/**发送心跳,保持长连接*/ sendMessage(json.toString());
JSONObject json=new JSONObject(); //log.info("心跳发送成功!");
json.put("method","ping"); }
json.put("hostName",HOST_NAME); }
ctx.channel().writeAndFlush(json.toString()+"$_").sync(); super.userEventTriggered(ctx, evt);
//log.info("心跳发送成功!"); }
}
}
super.userEventTriggered(ctx, evt); public static void sendMessage(String json) throws InterruptedException {
} ctx.channel().writeAndFlush(Unpooled.copiedBuffer((json + "$_").getBytes()));
}
public static void sendMessage(String json) throws InterruptedException {
ctx.channel().writeAndFlush(Unpooled.copiedBuffer((json+"$_").getBytes()));
}
} }

View File

@ -1,93 +1,93 @@
package luckyclient.netty; package luckyclient.netty;
import java.io.IOException; import java.io.IOException;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import io.netty.bootstrap.Bootstrap; import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import io.netty.channel.Channel; import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption; import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline; import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoop; import io.netty.channel.EventLoop;
import io.netty.channel.EventLoopGroup; import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder; import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.string.StringDecoder; import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder; import io.netty.handler.codec.string.StringEncoder;
import io.netty.handler.timeout.IdleStateHandler; import io.netty.handler.timeout.IdleStateHandler;
import luckyclient.utils.config.SysConfig; import luckyclient.utils.config.SysConfig;
public class NettyClient { public class NettyClient {
private static final String NETTY_SERVER_IP= SysConfig.getConfiguration().getProperty("server.web.ip"); private static final String NETTY_SERVER_IP= SysConfig.getConfiguration().getProperty("server.web.ip");
private static final int NETTY_SERVER_PORT=Integer.parseInt(SysConfig.getConfiguration().getProperty("netty.server.port")); private static final int NETTY_SERVER_PORT=Integer.parseInt(SysConfig.getConfiguration().getProperty("netty.server.port"));
protected static Channel channel; protected static Channel channel;
private static ChannelFuture connect; private static ChannelFuture connect;
private static final Logger log = LoggerFactory.getLogger(NettyClient.class); private static final Logger log = LoggerFactory.getLogger(NettyClient.class);
private static ClientHandler clientHandler; private static ClientHandler clientHandler;
public static void start() throws InterruptedException{ public static void start() throws InterruptedException{
EventLoopGroup group = new NioEventLoopGroup(); EventLoopGroup group = new NioEventLoopGroup();
try { try {
Bootstrap b = new Bootstrap(); Bootstrap b = new Bootstrap();
clientHandler=new ClientHandler(); clientHandler=new ClientHandler();
b.group(group) b.group(group)
.channel(NioSocketChannel.class) .channel(NioSocketChannel.class)
.option(ChannelOption.SO_KEEPALIVE,true) .option(ChannelOption.SO_KEEPALIVE,true)
.handler(new ChannelInitializer<SocketChannel>() { .handler(new ChannelInitializer<SocketChannel>() {
@Override @Override
public void initChannel(SocketChannel ch) throws Exception { public void initChannel(SocketChannel ch) throws Exception {
ByteBuf delimiter = Unpooled.copiedBuffer("$_".getBytes()); ByteBuf delimiter = Unpooled.copiedBuffer("$_".getBytes());
ChannelPipeline p = ch.pipeline(); ChannelPipeline p = ch.pipeline();
p.addLast("decoder", new StringDecoder()); p.addLast(new DelimiterBasedFrameDecoder(1024, delimiter));
p.addLast("encoder", new StringEncoder()); p.addLast("decoder", new StringDecoder());
p.addLast(new DelimiterBasedFrameDecoder(1024, delimiter)); p.addLast("encoder", new StringEncoder());
p.addLast(new IdleStateHandler(1,0,0,TimeUnit.SECONDS)); p.addLast(new IdleStateHandler(1,0,0,TimeUnit.SECONDS));
p.addLast(clientHandler); p.addLast(clientHandler);
} }
}); });
//连接服务端 //连接服务端
connect = b.connect(NETTY_SERVER_IP, NETTY_SERVER_PORT); connect = b.connect(NETTY_SERVER_IP, NETTY_SERVER_PORT);
//断线重连 //断线重连
connect.addListener(new ChannelFutureListener() { connect.addListener(new ChannelFutureListener() {
@Override @Override
public void operationComplete(ChannelFuture channelFuture) throws Exception { public void operationComplete(ChannelFuture channelFuture) throws Exception {
if (!channelFuture.isSuccess()) { if (!channelFuture.isSuccess()) {
final EventLoop loop = channelFuture.channel().eventLoop(); final EventLoop loop = channelFuture.channel().eventLoop();
loop.schedule(new Runnable() { loop.schedule(new Runnable() {
@Override @Override
public void run() { public void run() {
try { try {
log.error("服务端链接不上,开始重连操作..."); log.error("服务端链接不上,开始重连操作...");
start(); start();
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
}, 1L, TimeUnit.SECONDS); }, 1L, TimeUnit.SECONDS);
} else { } else {
channel = channelFuture.channel(); channel = channelFuture.channel();
log.info("服务端链接成功..."); log.info("服务端链接成功...");
} }
} }
}); });
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} finally { } finally {
//不关闭通道 //不关闭通道
//group.shutdownGracefully(); //group.shutdownGracefully();
} }
} }
} }