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