作者 crossoverJie

:sparkles: Introducing new features.客户端 push 消息 OK

@@ -12,4 +12,15 @@ @@ -12,4 +12,15 @@
12 <artifactId>netty-action-common</artifactId> 12 <artifactId>netty-action-common</artifactId>
13 13
14 14
  15 + <dependencies>
  16 + <dependency>
  17 + <groupId>io.springfox</groupId>
  18 + <artifactId>springfox-swagger2</artifactId>
  19 + <scope>compile</scope>
  20 + </dependency>
  21 + <dependency>
  22 + <groupId>io.springfox</groupId>
  23 + <artifactId>springfox-swagger-ui</artifactId>
  24 + </dependency>
  25 + </dependencies>
15 </project> 26 </project>
  1 +package com.crossoverjie.netty.action.common.enums;
  2 +
  3 +import java.util.ArrayList;
  4 +import java.util.List;
  5 +
  6 +public enum StatusEnum {
  7 +
  8 + /** 成功 */
  9 + SUCCESS("9000", "成功"),
  10 + /** 成功 */
  11 + FALLBACK("8000", "FALL_BACK"),
  12 + /** 参数校验失败**/
  13 + VALIDATION_FAIL("3000", "参数校验失败"),
  14 + /** 失败 */
  15 + FAIL("4000", "失败"),
  16 +
  17 + /** 重复请求 */
  18 + REPEAT_REQUEST("5000", "重复请求"),
  19 +
  20 + /** 请求限流 */
  21 + REQUEST_LIMIT("6000", "请求限流"),
  22 + ;
  23 +
  24 +
  25 + /** 枚举值码 */
  26 + private final String code;
  27 +
  28 + /** 枚举描述 */
  29 + private final String message;
  30 +
  31 + /**
  32 + * 构建一个 StatusEnum 。
  33 + * @param code 枚举值码。
  34 + * @param message 枚举描述。
  35 + */
  36 + private StatusEnum(String code, String message) {
  37 + this.code = code;
  38 + this.message = message;
  39 + }
  40 +
  41 + /**
  42 + * 得到枚举值码。
  43 + * @return 枚举值码。
  44 + */
  45 + public String getCode() {
  46 + return code;
  47 + }
  48 +
  49 + /**
  50 + * 得到枚举描述。
  51 + * @return 枚举描述。
  52 + */
  53 + public String getMessage() {
  54 + return message;
  55 + }
  56 +
  57 + /**
  58 + * 得到枚举值码。
  59 + * @return 枚举值码。
  60 + */
  61 + public String code() {
  62 + return code;
  63 + }
  64 +
  65 + /**
  66 + * 得到枚举描述。
  67 + * @return 枚举描述。
  68 + */
  69 + public String message() {
  70 + return message;
  71 + }
  72 +
  73 + /**
  74 + * 通过枚举值码查找枚举值。
  75 + * @param code 查找枚举值的枚举值码。
  76 + * @return 枚举值码对应的枚举值。
  77 + * @throws IllegalArgumentException 如果 code 没有对应的 StatusEnum 。
  78 + */
  79 + public static StatusEnum findStatus(String code) {
  80 + for (StatusEnum status : values()) {
  81 + if (status.getCode().equals(code)) {
  82 + return status;
  83 + }
  84 + }
  85 + throw new IllegalArgumentException("ResultInfo StatusEnum not legal:" + code);
  86 + }
  87 +
  88 + /**
  89 + * 获取全部枚举值。
  90 + *
  91 + * @return 全部枚举值。
  92 + */
  93 + public static List<StatusEnum> getAllStatus() {
  94 + List<StatusEnum> list = new ArrayList<StatusEnum>();
  95 + for (StatusEnum status : values()) {
  96 + list.add(status);
  97 + }
  98 + return list;
  99 + }
  100 +
  101 + /**
  102 + * 获取全部枚举值码。
  103 + *
  104 + * @return 全部枚举值码。
  105 + */
  106 + public static List<String> getAllStatusCode() {
  107 + List<String> list = new ArrayList<String>();
  108 + for (StatusEnum status : values()) {
  109 + list.add(status.code());
  110 + }
  111 + return list;
  112 + }
  113 +}
  1 +package com.crossoverjie.netty.action.common.req;
  2 +
  3 +import io.swagger.annotations.ApiModelProperty;
  4 +
  5 +/**
  6 + * Function:
  7 + * @author crossoverJie
  8 + * Date: 2017/6/7 下午11:28
  9 + * @since JDK 1.8
  10 + */
  11 +public class BaseRequest {
  12 +
  13 +
  14 + @ApiModelProperty(required=false, value="唯一请求号", example = "1234567890")
  15 + private String reqNo;
  16 +
  17 + @ApiModelProperty(required=false, value="当前请求的时间戳", example = "0")
  18 + private int timeStamp;
  19 +
  20 +
  21 +
  22 + public BaseRequest() {
  23 + this.setTimeStamp((int)(System.currentTimeMillis() / 1000));
  24 + }
  25 +
  26 + public String getReqNo() {
  27 + return reqNo;
  28 + }
  29 +
  30 + public void setReqNo(String reqNo) {
  31 + this.reqNo = reqNo;
  32 + }
  33 +
  34 + public int getTimeStamp() {
  35 + return timeStamp;
  36 + }
  37 +
  38 + public void setTimeStamp(int timeStamp) {
  39 + this.timeStamp = timeStamp;
  40 + }
  41 +
  42 +
  43 + @Override
  44 + public String toString() {
  45 + return "BaseRequest{" +
  46 + "reqNo='" + reqNo + '\'' +
  47 + ", timeStamp=" + timeStamp +
  48 + '}';
  49 + }
  50 +}
  1 +package com.crossoverjie.netty.action.common.res;
  2 +
  3 +
  4 +
  5 +import com.crossoverjie.netty.action.common.enums.StatusEnum;
  6 +import com.crossoverjie.netty.action.common.util.StringUtil;
  7 +
  8 +import java.io.Serializable;
  9 +
  10 +public class BaseResponse<T> implements Serializable{
  11 + private String code;
  12 +
  13 + private String message;
  14 +
  15 + /**
  16 + * 请求号
  17 + */
  18 + private String reqNo;
  19 +
  20 + private T dataBody;
  21 +
  22 + public BaseResponse() {}
  23 +
  24 + public BaseResponse(T dataBody) {
  25 + this.dataBody = dataBody;
  26 + }
  27 +
  28 + public BaseResponse(String code, String message) {
  29 + this.code = code;
  30 + this.message = message;
  31 + }
  32 +
  33 + public BaseResponse(String code, String message, T dataBody) {
  34 + this.code = code;
  35 + this.message = message;
  36 + this.dataBody = dataBody;
  37 + }
  38 +
  39 + public BaseResponse(String code, String message, String reqNo, T dataBody) {
  40 + this.code = code;
  41 + this.message = message;
  42 + this.reqNo = reqNo;
  43 + this.dataBody = dataBody;
  44 + }
  45 +
  46 + public static <T> BaseResponse<T> create(T t){
  47 + return new BaseResponse<T>(t);
  48 + }
  49 +
  50 + public static <T> BaseResponse<T> create(T t, StatusEnum statusEnum){
  51 + return new BaseResponse<T>(statusEnum.getCode(), statusEnum.getMessage(), t);
  52 + }
  53 +
  54 + public static <T> BaseResponse<T> createSuccess(T t, String message){
  55 + return new BaseResponse<T>(StatusEnum.SUCCESS.getCode(), StringUtil.isNullOrEmpty(message) ? StatusEnum.SUCCESS.getMessage() : message, t);
  56 + }
  57 +
  58 + public static <T> BaseResponse<T> createFail(T t, String message){
  59 + return new BaseResponse<T>(StatusEnum.FAIL.getCode(), StringUtil.isNullOrEmpty(message) ? StatusEnum.FAIL.getMessage() : message, t);
  60 + }
  61 +
  62 + public static <T> BaseResponse<T> create(T t, StatusEnum statusEnum, String message){
  63 +
  64 + return new BaseResponse<T>(statusEnum.getCode(), message, t);
  65 + }
  66 +
  67 +
  68 + public String getCode() {
  69 + return code;
  70 + }
  71 +
  72 + public void setCode(String code) {
  73 + this.code = code;
  74 + }
  75 +
  76 + public String getMessage() {
  77 + return message;
  78 + }
  79 +
  80 + public void setMessage(String message) {
  81 + this.message = message;
  82 + }
  83 +
  84 + public T getDataBody() {
  85 + return dataBody;
  86 + }
  87 +
  88 + public void setDataBody(T dataBody) {
  89 + this.dataBody = dataBody;
  90 + }
  91 +
  92 + public String getReqNo() {
  93 + return reqNo;
  94 + }
  95 +
  96 + public void setReqNo(String reqNo) {
  97 + this.reqNo = reqNo;
  98 + }
  99 +
  100 +
  101 +}
  1 +package com.crossoverjie.netty.action.common.res;
  2 +
  3 +/**
  4 + * Function:空对象,用在泛型中,表示没有额外的请求参数或者返回参数
  5 + *
  6 + * @author crossoverJie
  7 + * Date: 2017/6/7 下午11:57
  8 + * @since JDK 1.8
  9 + */
  10 +public class NULLBody {
  11 + public NULLBody() {}
  12 +
  13 + public static NULLBody create(){
  14 + return new NULLBody();
  15 + }
  16 +}
  1 +package com.crossoverjie.netty.action.common.util;
  2 +
  3 +/**
  4 + * Function:
  5 + *
  6 + * @author crossoverJie
  7 + * Date: 22/05/2018 15:16
  8 + * @since JDK 1.8
  9 + */
  10 +public class StringUtil {
  11 + public StringUtil() {
  12 + }
  13 +
  14 + public static boolean isNullOrEmpty(String str) {
  15 + return null == str || 0 == str.trim().length();
  16 + }
  17 +
  18 + public static boolean isEmpty(String str) {
  19 + return str == null || "".equals(str.trim());
  20 + }
  21 +
  22 + public static boolean isNotEmpty(String str) {
  23 + return str != null && !"".equals(str.trim());
  24 + }
  25 +
  26 + public static String formatLike(String str) {
  27 + return isNotEmpty(str)?"%" + str + "%":null;
  28 + }
  29 +}
@@ -15,6 +15,7 @@ @@ -15,6 +15,7 @@
15 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 15 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
16 <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> 16 <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
17 <java.version>1.8</java.version> 17 <java.version>1.8</java.version>
  18 + <swagger.version>2.5.0</swagger.version>
18 </properties> 19 </properties>
19 20
20 21
@@ -25,6 +26,17 @@ @@ -25,6 +26,17 @@
25 <artifactId>netty-action-common</artifactId> 26 <artifactId>netty-action-common</artifactId>
26 </dependency> 27 </dependency>
27 28
  29 +
  30 + <dependency>
  31 + <groupId>io.springfox</groupId>
  32 + <artifactId>springfox-swagger2</artifactId>
  33 + <scope>compile</scope>
  34 + </dependency>
  35 + <dependency>
  36 + <groupId>io.springfox</groupId>
  37 + <artifactId>springfox-swagger-ui</artifactId>
  38 + </dependency>
  39 +
28 <dependency> 40 <dependency>
29 <groupId>org.springframework.boot</groupId> 41 <groupId>org.springframework.boot</groupId>
30 <artifactId>spring-boot-starter-web</artifactId> 42 <artifactId>spring-boot-starter-web</artifactId>
@@ -17,8 +17,6 @@ public class HeartbeatClientApplication implements CommandLineRunner{ @@ -17,8 +17,6 @@ public class HeartbeatClientApplication implements CommandLineRunner{
17 private final static Logger LOGGER = LoggerFactory.getLogger(HeartbeatClientApplication.class); 17 private final static Logger LOGGER = LoggerFactory.getLogger(HeartbeatClientApplication.class);
18 18
19 19
20 - @Autowired  
21 - private HeartbeatClient heartbeatClient ;  
22 20
23 public static void main(String[] args) { 21 public static void main(String[] args) {
24 SpringApplication.run(HeartbeatClientApplication.class, args); 22 SpringApplication.run(HeartbeatClientApplication.class, args);
@@ -27,6 +25,5 @@ public class HeartbeatClientApplication implements CommandLineRunner{ @@ -27,6 +25,5 @@ public class HeartbeatClientApplication implements CommandLineRunner{
27 25
28 @Override 26 @Override
29 public void run(String... args) throws Exception { 27 public void run(String... args) throws Exception {
30 - heartbeatClient.sendMsg(new CustomProtocol(999999L,"ping"));  
31 } 28 }
32 } 29 }
  1 +package com.crossoverjie.netty.action.client.config;
  2 +
  3 +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
  4 +import org.springframework.context.annotation.Bean;
  5 +import org.springframework.context.annotation.Configuration;
  6 +import springfox.documentation.builders.ApiInfoBuilder;
  7 +import springfox.documentation.builders.PathSelectors;
  8 +import springfox.documentation.builders.RequestHandlerSelectors;
  9 +import springfox.documentation.service.ApiInfo;
  10 +import springfox.documentation.spi.DocumentationType;
  11 +import springfox.documentation.spring.web.plugins.Docket;
  12 +import springfox.documentation.swagger2.annotations.EnableSwagger2;
  13 +
  14 +
  15 +@Configuration
  16 +@EnableSwagger2
  17 +/** 是否打开swagger **/
  18 +@ConditionalOnExpression("'${swagger.enable}' == 'true'")
  19 +public class SwaggerConfig {
  20 +
  21 +
  22 + @Bean
  23 + public Docket createRestApi() {
  24 + return new Docket(DocumentationType.SWAGGER_2)
  25 + .apiInfo(apiInfo())
  26 + .select()
  27 + .apis(RequestHandlerSelectors.basePackage("com.crossoverjie.netty.action.client.controller"))
  28 + .paths(PathSelectors.any())
  29 + .build();
  30 + }
  31 +
  32 + private ApiInfo apiInfo() {
  33 + return new ApiInfoBuilder()
  34 + .title("sbc order api")
  35 + .description("sbc order api")
  36 + .termsOfServiceUrl("http://crossoverJie.top")
  37 + .contact("crossoverJie")
  38 + .version("1.0.0")
  39 + .build();
  40 + }
  41 +
  42 +}
  1 +package com.crossoverjie.netty.action.client.controller;
  2 +
  3 +import com.crossoverjie.netty.action.client.HeartbeatClient;
  4 +import com.crossoverjie.netty.action.client.vo.req.SendMsgReqVO;
  5 +import com.crossoverjie.netty.action.client.vo.res.SendMsgResVO;
  6 +import com.crossoverjie.netty.action.common.enums.StatusEnum;
  7 +import com.crossoverjie.netty.action.common.pojo.CustomProtocol;
  8 +import com.crossoverjie.netty.action.common.res.BaseResponse;
  9 +import io.swagger.annotations.ApiOperation;
  10 +import org.springframework.beans.factory.annotation.Autowired;
  11 +import org.springframework.stereotype.Controller;
  12 +import org.springframework.web.bind.annotation.RequestBody;
  13 +import org.springframework.web.bind.annotation.RequestMapping;
  14 +import org.springframework.web.bind.annotation.ResponseBody;
  15 +
  16 +/**
  17 + * Function:
  18 + *
  19 + * @author crossoverJie
  20 + * Date: 22/05/2018 14:46
  21 + * @since JDK 1.8
  22 + */
  23 +@Controller
  24 +@RequestMapping("/")
  25 +public class IndexController {
  26 +
  27 + @Autowired
  28 + private HeartbeatClient heartbeatClient ;
  29 +
  30 + /**
  31 + * 向服务端发消息
  32 + * @param sendMsgReqVO
  33 + * @return
  34 + */
  35 + @ApiOperation("发送消息")
  36 + @RequestMapping("sendMsg")
  37 + @ResponseBody
  38 + public BaseResponse<SendMsgResVO> sendMsg(@RequestBody SendMsgReqVO sendMsgReqVO){
  39 + BaseResponse<SendMsgResVO> res = new BaseResponse();
  40 + heartbeatClient.sendMsg(new CustomProtocol(122,sendMsgReqVO.getMsg())) ;
  41 +
  42 + SendMsgResVO sendMsgResVO = new SendMsgResVO() ;
  43 + sendMsgResVO.setMsg("OK") ;
  44 + res.setCode(StatusEnum.SUCCESS.getCode()) ;
  45 + res.setMessage(StatusEnum.SUCCESS.getMessage()) ;
  46 + res.setDataBody(sendMsgResVO) ;
  47 + return res ;
  48 + }
  49 +}
  1 +package com.crossoverjie.netty.action.client.vo.req;
  2 +
  3 +import com.crossoverjie.netty.action.common.req.BaseRequest;
  4 +import io.swagger.annotations.ApiModelProperty;
  5 +
  6 +import javax.validation.constraints.NotNull;
  7 +
  8 +/**
  9 + * Function:
  10 + *
  11 + * @author crossoverJie
  12 + * Date: 2018/05/21 15:56
  13 + * @since JDK 1.8
  14 + */
  15 +public class SendMsgReqVO extends BaseRequest {
  16 +
  17 + @NotNull(message = "msg 不能为空")
  18 + @ApiModelProperty(required = true, value = "msg", example = "hello")
  19 + private String msg ;
  20 +
  21 + public String getMsg() {
  22 + return msg;
  23 + }
  24 +
  25 + public void setMsg(String msg) {
  26 + this.msg = msg;
  27 + }
  28 +
  29 +}
  1 +package com.crossoverjie.netty.action.client.vo.res;
  2 +
  3 +/**
  4 + * Function:
  5 + *
  6 + * @author crossoverJie
  7 + * Date: 2017/6/26 15:43
  8 + * @since JDK 1.8
  9 + */
  10 +public class SendMsgResVO {
  11 + private String msg ;
  12 +
  13 + public String getMsg() {
  14 + return msg;
  15 + }
  16 +
  17 + public void setMsg(String msg) {
  18 + this.msg = msg;
  19 + }
  20 +}
1 # web port 1 # web port
2 server.port=8082 2 server.port=8082
3 3
  4 +# 是否打开swagger
  5 +swagger.enable = true
  6 +
4 netty.server.host=127.0.0.1 7 netty.server.host=127.0.0.1
5 netty.server.port=11211 8 netty.server.port=11211
6 9
@@ -4,6 +4,7 @@ import com.crossoverjie.netty.action.client.channel.init.HeartbeatInitializer; @@ -4,6 +4,7 @@ import com.crossoverjie.netty.action.client.channel.init.HeartbeatInitializer;
4 import io.netty.bootstrap.ServerBootstrap; 4 import io.netty.bootstrap.ServerBootstrap;
5 import io.netty.channel.*; 5 import io.netty.channel.*;
6 import io.netty.channel.nio.NioEventLoopGroup; 6 import io.netty.channel.nio.NioEventLoopGroup;
  7 +import io.netty.channel.socket.SocketChannel;
7 import io.netty.channel.socket.nio.NioServerSocketChannel; 8 import io.netty.channel.socket.nio.NioServerSocketChannel;
8 import org.slf4j.Logger; 9 import org.slf4j.Logger;
9 import org.slf4j.LoggerFactory; 10 import org.slf4j.LoggerFactory;
@@ -33,6 +34,8 @@ public class HeartBeatServer { @@ -33,6 +34,8 @@ public class HeartBeatServer {
33 @Value("${netty.server.port}") 34 @Value("${netty.server.port}")
34 private int nettyPort ; 35 private int nettyPort ;
35 36
  37 + private SocketChannel channel ;
  38 +
36 /** 39 /**
37 * 启动 Netty 40 * 启动 Netty
38 * @return 41 * @return
@@ -53,6 +56,7 @@ public class HeartBeatServer { @@ -53,6 +56,7 @@ public class HeartBeatServer {
53 if (future.isSuccess()){ 56 if (future.isSuccess()){
54 LOGGER.info("启动 Netty 成功"); 57 LOGGER.info("启动 Netty 成功");
55 } 58 }
  59 + channel = (SocketChannel) future.channel() ;
56 } 60 }
57 61
58 62
@@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
16 <logback.version>1.0.13</logback.version> 16 <logback.version>1.0.13</logback.version>
17 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 17 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
18 <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> 18 <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  19 + <swagger.version>2.5.0</swagger.version>
19 </properties> 20 </properties>
20 21
21 <parent> 22 <parent>
@@ -41,6 +42,19 @@ @@ -41,6 +42,19 @@
41 <version>1.0.0-SNAPSHOT</version> 42 <version>1.0.0-SNAPSHOT</version>
42 </dependency> 43 </dependency>
43 44
  45 +
  46 + <dependency>
  47 + <groupId>io.springfox</groupId>
  48 + <artifactId>springfox-swagger2</artifactId>
  49 + <version>${swagger.version}</version>
  50 + <scope>compile</scope>
  51 + </dependency>
  52 + <dependency>
  53 + <groupId>io.springfox</groupId>
  54 + <artifactId>springfox-swagger-ui</artifactId>
  55 + <version>${swagger.version}</version>
  56 + </dependency>
  57 +
44 <dependency> 58 <dependency>
45 <groupId>io.netty</groupId> 59 <groupId>io.netty</groupId>
46 <artifactId>netty-all</artifactId> 60 <artifactId>netty-all</artifactId>