作者 crossoverJie

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

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