断线重连,心跳检测
This commit is contained in:
parent
ab63d47dac
commit
9441aa1c83
22
cloud-central-control-client/pom.xml
Normal file
22
cloud-central-control-client/pom.xml
Normal file
@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>cm-cloud</artifactId>
|
||||
<groupId>com.cm</groupId>
|
||||
<version>1.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>cloud-central-control-client</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.cm</groupId>
|
||||
<artifactId>cloud-common-socket</artifactId>
|
||||
<version>1.0.1-SNAPSHOT</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
@ -0,0 +1,83 @@
|
||||
package com.cm.central.control.client.socket.config.properties;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* When you feel like quitting. Think about why you started
|
||||
* 当你想要放弃的时候,想想当初你为何开始
|
||||
*
|
||||
* @ClassName: SocketClientProperties
|
||||
* @Description: Socket客户端配置
|
||||
* @Author: WangGeng
|
||||
* @Date: 2020/7/29 10:06 上午
|
||||
* @Version: 1.0
|
||||
**/
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "socket.central-control.client")
|
||||
public class SocketClientProperties {
|
||||
|
||||
private String clientId;
|
||||
private String clientSecret;
|
||||
private String host = "127.0.0.1";
|
||||
private int port = 9999;
|
||||
private int maxReconnectCount = 20;
|
||||
private int reconnectTimeStep = 0;
|
||||
private int delayPingSeconds = 3;
|
||||
|
||||
public String getClientId() {
|
||||
return clientId == null ? "" : clientId.trim();
|
||||
}
|
||||
|
||||
public void setClientId(String clientId) {
|
||||
this.clientId = clientId;
|
||||
}
|
||||
|
||||
public String getClientSecret() {
|
||||
return clientSecret == null ? "" : clientSecret.trim();
|
||||
}
|
||||
|
||||
public void setClientSecret(String clientSecret) {
|
||||
this.clientSecret = clientSecret;
|
||||
}
|
||||
|
||||
public String getHost() {
|
||||
return host == null ? "" : host.trim();
|
||||
}
|
||||
|
||||
public void setHost(String host) {
|
||||
this.host = host;
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
public void setPort(int port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public int getMaxReconnectCount() {
|
||||
return maxReconnectCount <= 0 ? 20 : maxReconnectCount;
|
||||
}
|
||||
|
||||
public void setMaxReconnectCount(int maxReconnectCount) {
|
||||
this.maxReconnectCount = maxReconnectCount;
|
||||
}
|
||||
|
||||
public int getReconnectTimeStep() {
|
||||
return reconnectTimeStep <= 0 ? 0 : reconnectTimeStep;
|
||||
}
|
||||
|
||||
public void setReconnectTimeStep(int reconnectTimeStep) {
|
||||
this.reconnectTimeStep = reconnectTimeStep;
|
||||
}
|
||||
|
||||
public int getDelayPingSeconds() {
|
||||
return delayPingSeconds <= 0 ? 3 : delayPingSeconds;
|
||||
}
|
||||
|
||||
public void setDelayPingSeconds(int delayPingSeconds) {
|
||||
this.delayPingSeconds = delayPingSeconds;
|
||||
}
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
package com.cm.central.control.client.socket.handler;
|
||||
|
||||
import com.cm.central.control.client.socket.config.properties.SocketClientProperties;
|
||||
import com.cm.central.control.client.socket.socket.SocketClientRunnable;
|
||||
import com.cm.socket.decoder.MessageDecoder;
|
||||
import com.cm.socket.encoder.MessageEncoder;
|
||||
import com.cm.socket.service.ISocketService;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* When you feel like quitting. Think about why you started
|
||||
* 当你想要放弃的时候,想想当初你为何开始
|
||||
*
|
||||
* @ClassName: MessageClientChannelInitializer
|
||||
* @Description: 消息客户端初始化
|
||||
* @Author: WangGeng
|
||||
* @Date: 2020/7/6 9:32 上午
|
||||
* @Version: 1.0
|
||||
**/
|
||||
@Component
|
||||
public class SocketClientChannelInitializer extends ChannelInitializer<SocketChannel> {
|
||||
|
||||
@Autowired
|
||||
private SocketClientRunnable socketClientRunnable;
|
||||
@Autowired
|
||||
private SocketClientProperties socketClientProperties;
|
||||
@Resource(name = "pingServiceImpl")
|
||||
private ISocketService pingServiceImpl;
|
||||
@Resource(name = "clientInfoServiceImpl")
|
||||
private ISocketService clientInfoServiceImpl;
|
||||
@Resource(name = "exceptionServiceImpl")
|
||||
private ISocketService exceptionServiceImpl;
|
||||
@Resource(name = "loginServiceImpl")
|
||||
private ISocketService loginServiceImpl;
|
||||
@Resource(name = "errorServiceImpl")
|
||||
private ISocketService errorServiceImpl;
|
||||
|
||||
@Override
|
||||
protected void initChannel(SocketChannel ch) throws Exception {
|
||||
ch.pipeline().addLast(new MessageEncoder());
|
||||
ch.pipeline().addLast(new MessageDecoder());
|
||||
ch.pipeline().addLast(getSocketClientHandler());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取消息处理器
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private SocketClientHandler getSocketClientHandler() {
|
||||
SocketClientHandler socketClientHandler = new SocketClientHandler();
|
||||
socketClientHandler.setClientInfoServiceImpl(clientInfoServiceImpl);
|
||||
socketClientHandler.setExceptionServiceImpl(exceptionServiceImpl);
|
||||
socketClientHandler.setLoginServiceImpl(loginServiceImpl);
|
||||
socketClientHandler.setPingServiceImpl(pingServiceImpl);
|
||||
socketClientHandler.setErrorServiceImpl(errorServiceImpl);
|
||||
socketClientHandler.setSocketClientProperties(socketClientProperties);
|
||||
socketClientHandler.setSocketClientRunnable(socketClientRunnable);
|
||||
return socketClientHandler;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,110 @@
|
||||
package com.cm.central.control.client.socket.handler;
|
||||
|
||||
import com.cm.central.control.client.socket.config.properties.SocketClientProperties;
|
||||
import com.cm.central.control.client.socket.manager.SocketClientManager;
|
||||
import com.cm.central.control.client.socket.socket.SocketClientRunnable;
|
||||
import com.cm.socket.enums.SocketTypeMessageEnum;
|
||||
import com.cm.socket.pojo.Message;
|
||||
import com.cm.socket.service.ISocketService;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* When you feel like quitting. Think about why you started
|
||||
* 当你想要放弃的时候,想想当初你为何开始
|
||||
*
|
||||
* @ClassName: MessageClientHandler
|
||||
* @Description: 消息客户端处理器
|
||||
* @Author: WangGeng
|
||||
* @Date: 2020/7/6 9:34 上午
|
||||
* @Version: 1.0
|
||||
**/
|
||||
public class SocketClientHandler extends SimpleChannelInboundHandler<Message> {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(SocketClientHandler.class);
|
||||
private SocketClientRunnable socketClientRunnable;
|
||||
private SocketClientProperties socketClientProperties;
|
||||
private ISocketService pingServiceImpl;
|
||||
private ISocketService clientInfoServiceImpl;
|
||||
private ISocketService exceptionServiceImpl;
|
||||
private ISocketService loginServiceImpl;
|
||||
private ISocketService errorServiceImpl;
|
||||
|
||||
@Override
|
||||
public void channelActive(ChannelHandlerContext ctx) throws Exception {
|
||||
LOG.debug("与服务器建立Socket链接已经建立,登录");
|
||||
loginServiceImpl.autoReply(ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void channelRead0(ChannelHandlerContext ctx, Message message) throws Exception {
|
||||
if (message.getType() == SocketTypeMessageEnum.MESSAGE_TYPE_PONG.getType()) {
|
||||
pingServiceImpl.readMessage(ctx, message);
|
||||
} else if (message.getType() == SocketTypeMessageEnum.MESSAGE_TYPE_CLIENT_LOGIN.getType()) {
|
||||
loginServiceImpl.readMessage(ctx, message);
|
||||
} else if (message.getType() == SocketTypeMessageEnum.MESSAGE_TYPE_EXCEPTION.getType()) {
|
||||
exceptionServiceImpl.readMessage(ctx, message);
|
||||
} else if (message.getType() == SocketTypeMessageEnum.MESSAGE_TYPE_ERROR.getType()) {
|
||||
errorServiceImpl.readMessage(ctx, message);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
|
||||
LOG.error("与服务断开连接");
|
||||
SocketClientManager socketClientManager = SocketClientManager.getInstance();
|
||||
int currentReconnectCount = socketClientManager.getCurrentReconnectCount();
|
||||
int waitTime = socketClientManager.getCurrentReconnectTime();
|
||||
if (socketClientManager.getCurrentReconnectCount() > socketClientProperties.getMaxReconnectCount()) {
|
||||
LOG.error("服务器重连失败");
|
||||
throw new RuntimeException("服务器重连失败");
|
||||
}
|
||||
LOG.error(waitTime + "s后进行第" + currentReconnectCount + "次重连");
|
||||
ctx.channel().eventLoop().schedule(() -> {
|
||||
LOG.debug("重新登录...");
|
||||
socketClientRunnable.run();
|
||||
}, waitTime, TimeUnit.SECONDS);
|
||||
socketClientManager.setCurrentReconnectCount(++currentReconnectCount);
|
||||
if (socketClientProperties.getReconnectTimeStep() > 0) {
|
||||
socketClientManager.setCurrentReconnectTime(waitTime + socketClientProperties.getReconnectTimeStep());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
||||
LOG.error(cause.getMessage(), cause);
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
public void setSocketClientRunnable(SocketClientRunnable socketClientRunnable) {
|
||||
this.socketClientRunnable = socketClientRunnable;
|
||||
}
|
||||
|
||||
public void setSocketClientProperties(SocketClientProperties socketClientProperties) {
|
||||
this.socketClientProperties = socketClientProperties;
|
||||
}
|
||||
|
||||
public void setPingServiceImpl(ISocketService pingServiceImpl) {
|
||||
this.pingServiceImpl = pingServiceImpl;
|
||||
}
|
||||
|
||||
public void setClientInfoServiceImpl(ISocketService clientInfoServiceImpl) {
|
||||
this.clientInfoServiceImpl = clientInfoServiceImpl;
|
||||
}
|
||||
|
||||
public void setExceptionServiceImpl(ISocketService exceptionServiceImpl) {
|
||||
this.exceptionServiceImpl = exceptionServiceImpl;
|
||||
}
|
||||
|
||||
public void setLoginServiceImpl(ISocketService loginServiceImpl) {
|
||||
this.loginServiceImpl = loginServiceImpl;
|
||||
}
|
||||
|
||||
public void setErrorServiceImpl(ISocketService errorServiceImpl) {
|
||||
this.errorServiceImpl = errorServiceImpl;
|
||||
}
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
package com.cm.central.control.client.socket.manager;
|
||||
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
|
||||
/**
|
||||
* When you feel like quitting. Think about why you started
|
||||
* 当你想要放弃的时候,想想当初你为何开始
|
||||
*
|
||||
* @ClassName: SocketClientManager
|
||||
* @Description: Socket客户端控制器
|
||||
* @Author: WangGeng
|
||||
* @Date: 2020/7/29 3:12 下午
|
||||
* @Version: 1.0
|
||||
**/
|
||||
public class SocketClientManager {
|
||||
|
||||
private static SocketClientManager socketClientManager = SocketClientManagerBuilder.socketClientManager;
|
||||
private String token;
|
||||
private int currentReconnectCount = 1;
|
||||
private int currentReconnectTime = 1;
|
||||
private Channel channel;
|
||||
|
||||
private SocketClientManager() {
|
||||
|
||||
}
|
||||
|
||||
public static SocketClientManager getInstance() {
|
||||
return socketClientManager;
|
||||
}
|
||||
|
||||
public void setToken(String token) {
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
public String getToken() {
|
||||
return token == null ? "" : token.trim();
|
||||
}
|
||||
|
||||
public int getCurrentReconnectCount() {
|
||||
return currentReconnectCount;
|
||||
}
|
||||
|
||||
public void setCurrentReconnectCount(int currentReconnectCount) {
|
||||
this.currentReconnectCount = currentReconnectCount;
|
||||
}
|
||||
|
||||
public int getCurrentReconnectTime() {
|
||||
return currentReconnectTime;
|
||||
}
|
||||
|
||||
public void setCurrentReconnectTime(int currentReconnectTime) {
|
||||
this.currentReconnectTime = currentReconnectTime;
|
||||
}
|
||||
|
||||
private static class SocketClientManagerBuilder {
|
||||
public static SocketClientManager socketClientManager = new SocketClientManager();
|
||||
}
|
||||
|
||||
public Channel getChannel() {
|
||||
return channel;
|
||||
}
|
||||
|
||||
public void setChannel(Channel channel) {
|
||||
this.channel = channel;
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package com.cm.central.control.client.socket.service;
|
||||
|
||||
import com.cm.common.base.AbstractService;
|
||||
|
||||
/**
|
||||
* When you feel like quitting. Think about why you started
|
||||
* 当你想要放弃的时候,想想当初你为何开始
|
||||
*
|
||||
* @ClassName: BaseService
|
||||
* @Description: 基础业务
|
||||
* @Author: WangGeng
|
||||
* @Date: 2020/7/29 10:41 上午
|
||||
* @Version: 1.0
|
||||
**/
|
||||
public class BaseService extends AbstractService {
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
package com.cm.central.control.client.socket.service.socket;
|
||||
|
||||
import com.cm.central.control.client.socket.manager.SocketClientManager;
|
||||
import com.cm.central.control.client.socket.service.BaseService;
|
||||
import com.cm.socket.enums.SocketTypeMessageEnum;
|
||||
import com.cm.socket.pojo.Message;
|
||||
import com.cm.socket.service.AbstractSocketService;
|
||||
import com.cm.socket.service.ISocketService;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
|
||||
/**
|
||||
* When you feel like quitting. Think about why you started
|
||||
* 当你想要放弃的时候,想想当初你为何开始
|
||||
*
|
||||
* @ClassName: AbstractSocketService
|
||||
* @Description: socket业务
|
||||
* @Author: WangGeng
|
||||
* @Date: 2020/7/29 10:40 上午
|
||||
* @Version: 1.0
|
||||
**/
|
||||
public abstract class BaseSocketService extends AbstractSocketService {
|
||||
|
||||
@Override
|
||||
public void readMessage(ChannelHandlerContext channelHandlerContext, Message readMessage) {
|
||||
readMessageService(channelHandlerContext, readMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取信息业务
|
||||
*
|
||||
* @param channelHandlerContext
|
||||
* @param readMessage
|
||||
*/
|
||||
@Override
|
||||
protected abstract void readMessageService(ChannelHandlerContext channelHandlerContext, Message readMessage);
|
||||
|
||||
/**
|
||||
* 输出信息
|
||||
*
|
||||
* @param channelHandlerContext
|
||||
* @param socketTypeMessageEnum
|
||||
* @param content
|
||||
*/
|
||||
@Override
|
||||
public void writeMessage(ChannelHandlerContext channelHandlerContext, SocketTypeMessageEnum socketTypeMessageEnum, String content) {
|
||||
Message message = new Message();
|
||||
message.setStart(SocketTypeMessageEnum.MESSAGE_TYPE_START.getType());
|
||||
message.setType(socketTypeMessageEnum.getType());
|
||||
message.setToken(SocketClientManager.getInstance().getToken());
|
||||
message.setContent(content);
|
||||
write(channelHandlerContext, message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 输出错误信息
|
||||
*
|
||||
* @param channelHandlerContext
|
||||
* @param errorMessage
|
||||
*/
|
||||
@Override
|
||||
public void writeError(ChannelHandlerContext channelHandlerContext, String errorMessage) {
|
||||
Message message = new Message();
|
||||
message.setStart(SocketTypeMessageEnum.MESSAGE_TYPE_START.getType());
|
||||
message.setType(SocketTypeMessageEnum.MESSAGE_TYPE_ERROR.getType());
|
||||
message.setToken(SocketClientManager.getInstance().getToken());
|
||||
message.setContent(errorMessage);
|
||||
write(channelHandlerContext, message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 输出数据
|
||||
*
|
||||
* @param channelHandlerContext
|
||||
* @param writeMessage
|
||||
*/
|
||||
@Override
|
||||
protected void write(ChannelHandlerContext channelHandlerContext, Message writeMessage) {
|
||||
channelHandlerContext.channel().writeAndFlush(writeMessage);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package com.cm.central.control.client.socket.service.socket.clientinfo;
|
||||
|
||||
import com.cm.central.control.client.socket.service.socket.BaseSocketService;
|
||||
import com.cm.socket.pojo.Message;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* When you feel like quitting. Think about why you started
|
||||
* 当你想要放弃的时候,想想当初你为何开始
|
||||
*
|
||||
* @ClassName: ClientInfoServiceImpl
|
||||
* @Description: 客户端信息
|
||||
* @Author: WangGeng
|
||||
* @Date: 2020/7/29 2:42 下午
|
||||
* @Version: 1.0
|
||||
**/
|
||||
@Service("clientInfoServiceImpl")
|
||||
public class ClientInfoServiceImpl extends BaseSocketService {
|
||||
|
||||
@Override
|
||||
protected void readMessageService(ChannelHandlerContext channelHandlerContext, Message readMessage) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void autoReply(ChannelHandlerContext channelHandlerContext) {
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package com.cm.central.control.client.socket.service.socket.error;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.cm.central.control.client.socket.service.socket.BaseSocketService;
|
||||
import com.cm.socket.pojo.Message;
|
||||
import com.cm.socket.pojo.SocketResult;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* When you feel like quitting. Think about why you started
|
||||
* 当你想要放弃的时候,想想当初你为何开始
|
||||
*
|
||||
* @ClassName: ErrorServiceImpl
|
||||
* @Description: error业务
|
||||
* @Author: WangGeng
|
||||
* @Date: 2020/7/29 10:22 下午
|
||||
* @Version: 1.0
|
||||
**/
|
||||
@Service("errorServiceImpl")
|
||||
public class ErrorServiceImpl extends BaseSocketService {
|
||||
|
||||
@Override
|
||||
protected void readMessageService(ChannelHandlerContext channelHandlerContext, Message readMessage) {
|
||||
SocketResult<String> result = JSONObject.parseObject(readMessage.getContent(), SocketResult.class);
|
||||
LOG.error(result.getErrorMsg());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void autoReply(ChannelHandlerContext channelHandlerContext) {
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package com.cm.central.control.client.socket.service.socket.exception;
|
||||
|
||||
import com.cm.central.control.client.socket.service.socket.BaseSocketService;
|
||||
import com.cm.socket.pojo.Message;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* When you feel like quitting. Think about why you started
|
||||
* 当你想要放弃的时候,想想当初你为何开始
|
||||
*
|
||||
* @ClassName: ExceptionServiceImpl
|
||||
* @Description: 异常业务
|
||||
* @Author: WangGeng
|
||||
* @Date: 2020/7/29 2:41 下午
|
||||
* @Version: 1.0
|
||||
**/
|
||||
@Service("exceptionServiceImpl")
|
||||
public class ExceptionServiceImpl extends BaseSocketService {
|
||||
|
||||
@Override
|
||||
protected void readMessageService(ChannelHandlerContext channelHandlerContext, Message readMessage) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void autoReply(ChannelHandlerContext channelHandlerContext) {
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
package com.cm.central.control.client.socket.service.socket.login;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.cm.central.control.client.socket.config.properties.SocketClientProperties;
|
||||
import com.cm.central.control.client.socket.manager.SocketClientManager;
|
||||
import com.cm.central.control.client.socket.service.socket.BaseSocketService;
|
||||
import com.cm.socket.consts.ISocketConst;
|
||||
import com.cm.socket.enums.SocketTypeMessageEnum;
|
||||
import com.cm.socket.pojo.Message;
|
||||
import com.cm.socket.pojo.SocketResult;
|
||||
import com.cm.socket.service.ISocketService;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* When you feel like quitting. Think about why you started
|
||||
* 当你想要放弃的时候,想想当初你为何开始
|
||||
*
|
||||
* @ClassName: LoginServiceImpl
|
||||
* @Description: 登录业务
|
||||
* @Author: WangGeng
|
||||
* @Date: 2020/7/29 2:40 下午
|
||||
* @Version: 1.0
|
||||
**/
|
||||
@Service("loginServiceImpl")
|
||||
public class LoginServiceImpl extends BaseSocketService {
|
||||
|
||||
@Autowired
|
||||
private SocketClientProperties socketClientProperties;
|
||||
@Resource(name = "pingServiceImpl")
|
||||
private ISocketService pingServiceImpl;
|
||||
|
||||
@Override
|
||||
public void readMessage(ChannelHandlerContext channelHandlerContext, Message readMessage) {
|
||||
readMessageService(channelHandlerContext, readMessage);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readMessageService(ChannelHandlerContext channelHandlerContext, Message readMessage) {
|
||||
SocketResult<String> socketResult = JSONObject.parseObject(readMessage.getContent(), SocketResult.class);
|
||||
SocketClientManager socketClientManager = SocketClientManager.getInstance();
|
||||
// 初始化重连
|
||||
socketClientManager.setCurrentReconnectCount(1);
|
||||
socketClientManager.setCurrentReconnectTime(1);
|
||||
socketClientManager.setToken(socketResult.getData());
|
||||
socketClientManager.setChannel(channelHandlerContext.channel());
|
||||
LOG.debug("登录成功,开启 ping-pong 心跳");
|
||||
pingServiceImpl.autoReply(channelHandlerContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void autoReply(ChannelHandlerContext channelHandlerContext) {
|
||||
String clientId = socketClientProperties.getClientId();
|
||||
String clientSecret = socketClientProperties.getClientSecret();
|
||||
Message message = new Message();
|
||||
message.setStart(SocketTypeMessageEnum.MESSAGE_TYPE_START.getType());
|
||||
message.setType(SocketTypeMessageEnum.MESSAGE_TYPE_CLIENT_LOGIN.getType());
|
||||
JSONObject loginObj = new JSONObject();
|
||||
loginObj.put(ISocketConst.CLIENT_ID, clientId);
|
||||
loginObj.put(ISocketConst.CLIENT_SECRET, clientSecret);
|
||||
message.setContent(loginObj.toJSONString());
|
||||
channelHandlerContext.channel().writeAndFlush(message);
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
package com.cm.central.control.client.socket.service.socket.ping;
|
||||
|
||||
import com.cm.central.control.client.socket.config.properties.SocketClientProperties;
|
||||
import com.cm.central.control.client.socket.service.socket.BaseSocketService;
|
||||
import com.cm.socket.enums.SocketMessageEnum;
|
||||
import com.cm.socket.enums.SocketTypeMessageEnum;
|
||||
import com.cm.socket.pojo.Message;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.util.concurrent.ScheduledFuture;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* When you feel like quitting. Think about why you started
|
||||
* 当你想要放弃的时候,想想当初你为何开始
|
||||
*
|
||||
* @ClassName: PingServiceImpl
|
||||
* @Description: PING业务
|
||||
* @Author: WangGeng
|
||||
* @Date: 2020/7/29 10:51 上午
|
||||
* @Version: 1.0
|
||||
**/
|
||||
@Component("pingServiceImpl")
|
||||
public class PingServiceImpl extends BaseSocketService {
|
||||
|
||||
@Autowired
|
||||
private SocketClientProperties socketClientProperties;
|
||||
|
||||
@Override
|
||||
protected void readMessageService(ChannelHandlerContext channelHandlerContext, Message readMessage) {
|
||||
System.out.println(readMessage.getToken() + ": " + readMessage.getContent());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void autoReply(ChannelHandlerContext channelHandlerContext) {
|
||||
Channel channel = channelHandlerContext.channel();
|
||||
ScheduledFuture<?> scheduledFuture = channel.eventLoop().schedule(() -> {
|
||||
if (channel.isActive()) {
|
||||
writeMessage(channelHandlerContext, SocketTypeMessageEnum.MESSAGE_TYPE_PING, SocketMessageEnum.MESSAGE_PING.getMessage());
|
||||
} else {
|
||||
channelHandlerContext.close();
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}, socketClientProperties.getDelayPingSeconds(), TimeUnit.SECONDS);
|
||||
scheduledFuture.addListener(future -> {
|
||||
if (future.isSuccess()) {
|
||||
autoReply(channelHandlerContext);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
package com.cm.central.control.client.socket.socket;
|
||||
|
||||
import com.cm.central.control.client.socket.config.properties.SocketClientProperties;
|
||||
import com.cm.central.control.client.socket.handler.SocketClientChannelInitializer;
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelFutureListener;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import io.netty.channel.socket.nio.NioSocketChannel;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* When you feel like quitting. Think about why you started
|
||||
* 当你想要放弃的时候,想想当初你为何开始
|
||||
*
|
||||
* @ClassName: SocketClient
|
||||
* @Description: Socket客户端
|
||||
* @Author: WangGeng
|
||||
* @Date: 2020/7/29 10:29 上午
|
||||
* @Version: 1.0
|
||||
**/
|
||||
@Component
|
||||
public class SocketClientRunnable implements Runnable, InitializingBean {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(SocketClientRunnable.class);
|
||||
@Autowired
|
||||
private SocketClientProperties socketClientProperties;
|
||||
@Autowired
|
||||
private SocketClientChannelInitializer socketClientChannelInitializer;
|
||||
private Bootstrap bootstrap = new Bootstrap();
|
||||
private EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
bootstrap.group(eventLoopGroup);
|
||||
bootstrap.channel(NioSocketChannel.class);
|
||||
bootstrap.option(ChannelOption.SO_KEEPALIVE, true);
|
||||
bootstrap.handler(socketClientChannelInitializer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
ChannelFuture channelFuture = bootstrap.connect(socketClientProperties.getHost(), socketClientProperties.getPort());
|
||||
channelFuture.addListener((ChannelFutureListener) future -> {
|
||||
if (!future.isSuccess()) {
|
||||
future.channel().pipeline().fireChannelInactive();
|
||||
}
|
||||
});
|
||||
channelFuture.channel().closeFuture();
|
||||
} catch (Exception e) {
|
||||
LOG.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package com.cm.central.control.client.socket.startup;
|
||||
|
||||
import com.cm.central.control.client.socket.socket.SocketClientRunnable;
|
||||
import com.cm.socket.pojo.SocketClient;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.ApplicationArguments;
|
||||
import org.springframework.boot.ApplicationRunner;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* When you feel like quitting. Think about why you started
|
||||
* 当你想要放弃的时候,想想当初你为何开始
|
||||
*
|
||||
* @ClassName: SocketClientStartUp
|
||||
* @Description: Socket客户端启动
|
||||
* @Author: WangGeng
|
||||
* @Date: 2020/7/29 4:55 下午
|
||||
* @Version: 1.0
|
||||
**/
|
||||
@Component
|
||||
public class SocketClientStartUp implements ApplicationRunner {
|
||||
|
||||
@Autowired
|
||||
private SocketClientRunnable socketClientRunnable;
|
||||
|
||||
@Override
|
||||
public void run(ApplicationArguments args) throws Exception {
|
||||
new Thread(socketClientRunnable).start();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user