From 9441aa1c830f356c8007487ae87b1014ebecf90e Mon Sep 17 00:00:00 2001 From: wenc000 <450292408@qq.com> Date: Fri, 31 Jul 2020 19:24:05 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=AD=E7=BA=BF=E9=87=8D=E8=BF=9E=EF=BC=8C?= =?UTF-8?q?=E5=BF=83=E8=B7=B3=E6=A3=80=E6=B5=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloud-central-control-client/pom.xml | 22 ++++ .../properties/SocketClientProperties.java | 83 +++++++++++++ .../SocketClientChannelInitializer.java | 67 +++++++++++ .../socket/handler/SocketClientHandler.java | 110 ++++++++++++++++++ .../socket/manager/SocketClientManager.java | 67 +++++++++++ .../client/socket/service/BaseService.java | 16 +++ .../service/socket/BaseSocketService.java | 81 +++++++++++++ .../clientinfo/ClientInfoServiceImpl.java | 30 +++++ .../socket/error/ErrorServiceImpl.java | 33 ++++++ .../exception/ExceptionServiceImpl.java | 30 +++++ .../socket/login/LoginServiceImpl.java | 68 +++++++++++ .../service/socket/ping/PingServiceImpl.java | 54 +++++++++ .../socket/socket/SocketClientRunnable.java | 61 ++++++++++ .../socket/startup/SocketClientStartUp.java | 30 +++++ 14 files changed, 752 insertions(+) create mode 100644 cloud-central-control-client/pom.xml create mode 100644 cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/config/properties/SocketClientProperties.java create mode 100644 cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/handler/SocketClientChannelInitializer.java create mode 100644 cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/handler/SocketClientHandler.java create mode 100644 cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/manager/SocketClientManager.java create mode 100644 cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/service/BaseService.java create mode 100644 cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/service/socket/BaseSocketService.java create mode 100644 cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/service/socket/clientinfo/ClientInfoServiceImpl.java create mode 100644 cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/service/socket/error/ErrorServiceImpl.java create mode 100644 cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/service/socket/exception/ExceptionServiceImpl.java create mode 100644 cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/service/socket/login/LoginServiceImpl.java create mode 100644 cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/service/socket/ping/PingServiceImpl.java create mode 100644 cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/socket/SocketClientRunnable.java create mode 100644 cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/startup/SocketClientStartUp.java diff --git a/cloud-central-control-client/pom.xml b/cloud-central-control-client/pom.xml new file mode 100644 index 0000000..578ef0d --- /dev/null +++ b/cloud-central-control-client/pom.xml @@ -0,0 +1,22 @@ + + + + cm-cloud + com.cm + 1.0.1-SNAPSHOT + + 4.0.0 + + cloud-central-control-client + + + + com.cm + cloud-common-socket + 1.0.1-SNAPSHOT + + + + \ No newline at end of file diff --git a/cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/config/properties/SocketClientProperties.java b/cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/config/properties/SocketClientProperties.java new file mode 100644 index 0000000..8000f48 --- /dev/null +++ b/cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/config/properties/SocketClientProperties.java @@ -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; + } +} diff --git a/cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/handler/SocketClientChannelInitializer.java b/cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/handler/SocketClientChannelInitializer.java new file mode 100644 index 0000000..1a7982b --- /dev/null +++ b/cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/handler/SocketClientChannelInitializer.java @@ -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 { + + @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; + } + +} diff --git a/cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/handler/SocketClientHandler.java b/cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/handler/SocketClientHandler.java new file mode 100644 index 0000000..70a6a3e --- /dev/null +++ b/cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/handler/SocketClientHandler.java @@ -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 { + + 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; + } +} diff --git a/cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/manager/SocketClientManager.java b/cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/manager/SocketClientManager.java new file mode 100644 index 0000000..bea2f29 --- /dev/null +++ b/cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/manager/SocketClientManager.java @@ -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; + } +} diff --git a/cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/service/BaseService.java b/cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/service/BaseService.java new file mode 100644 index 0000000..ce6b11d --- /dev/null +++ b/cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/service/BaseService.java @@ -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 { +} diff --git a/cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/service/socket/BaseSocketService.java b/cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/service/socket/BaseSocketService.java new file mode 100644 index 0000000..257e2e2 --- /dev/null +++ b/cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/service/socket/BaseSocketService.java @@ -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); + } + +} diff --git a/cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/service/socket/clientinfo/ClientInfoServiceImpl.java b/cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/service/socket/clientinfo/ClientInfoServiceImpl.java new file mode 100644 index 0000000..e1ebc3a --- /dev/null +++ b/cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/service/socket/clientinfo/ClientInfoServiceImpl.java @@ -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) { + + } +} diff --git a/cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/service/socket/error/ErrorServiceImpl.java b/cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/service/socket/error/ErrorServiceImpl.java new file mode 100644 index 0000000..409df7c --- /dev/null +++ b/cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/service/socket/error/ErrorServiceImpl.java @@ -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 result = JSONObject.parseObject(readMessage.getContent(), SocketResult.class); + LOG.error(result.getErrorMsg()); + } + + @Override + public void autoReply(ChannelHandlerContext channelHandlerContext) { + + } +} diff --git a/cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/service/socket/exception/ExceptionServiceImpl.java b/cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/service/socket/exception/ExceptionServiceImpl.java new file mode 100644 index 0000000..8670d40 --- /dev/null +++ b/cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/service/socket/exception/ExceptionServiceImpl.java @@ -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) { + + } +} diff --git a/cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/service/socket/login/LoginServiceImpl.java b/cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/service/socket/login/LoginServiceImpl.java new file mode 100644 index 0000000..1d225b4 --- /dev/null +++ b/cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/service/socket/login/LoginServiceImpl.java @@ -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 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); + } +} diff --git a/cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/service/socket/ping/PingServiceImpl.java b/cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/service/socket/ping/PingServiceImpl.java new file mode 100644 index 0000000..566edd5 --- /dev/null +++ b/cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/service/socket/ping/PingServiceImpl.java @@ -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); + } + }); + } +} diff --git a/cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/socket/SocketClientRunnable.java b/cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/socket/SocketClientRunnable.java new file mode 100644 index 0000000..8d8e580 --- /dev/null +++ b/cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/socket/SocketClientRunnable.java @@ -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); + } + } +} diff --git a/cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/startup/SocketClientStartUp.java b/cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/startup/SocketClientStartUp.java new file mode 100644 index 0000000..1f05182 --- /dev/null +++ b/cloud-central-control-client/src/main/java/com/cm/central/control/client/socket/startup/SocketClientStartUp.java @@ -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(); + } +}