作者 crossoverJie

:sparkles: Introducing new features新增路由

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>netty-action</artifactId>
<groupId>com.crossoverjie.netty</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cim-forward-route</artifactId>
<packaging>jar</packaging>
<properties>
<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>
<logback.version>1.2.3</logback.version>
</properties>
<dependencies>
<dependency>
<groupId>com.crossoverjie.netty</groupId>
<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>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>${netty.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<!-- spring-boot-maven-plugin (提供了直接运行项目的插件:如果是通过parent方式继承spring-boot-starter-parent则不用此插件) -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
... ...
package com.crossoverjie.cim.route;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author crossoverJie
*/
@SpringBootApplication
public class RouteApplication {
private final static Logger LOGGER = LoggerFactory.getLogger(RouteApplication.class);
public static void main(String[] args) {
SpringApplication.run(RouteApplication.class, args);
LOGGER.info("启动 route 成功");
}
}
\ No newline at end of file
... ...
package com.crossoverjie.cim.route.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.cim.route.controller"))
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("cim-forward-route")
.description("cim-forward-route api")
.termsOfServiceUrl("http://crossoverJie.top")
.contact("crossoverJie")
.version("1.0.0")
.build();
}
}
\ No newline at end of file
... ...
package com.crossoverjie.cim.route.controller;
import com.crossoverjie.cim.route.vo.req.P2PRequest;
import com.crossoverjie.cim.route.vo.req.GroupRequest;
import com.crossoverjie.netty.action.common.enums.StatusEnum;
import com.crossoverjie.netty.action.common.res.BaseResponse;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* Function:
*
* @author crossoverJie
* Date: 22/05/2018 14:46
* @since JDK 1.8
*/
@Controller
@RequestMapping("/")
public class RouteController {
private final static Logger LOGGER = LoggerFactory.getLogger(RouteController.class);
@ApiOperation("群聊 API")
@RequestMapping(value = "groupRoute",method = RequestMethod.POST)
@ResponseBody()
public BaseResponse groupRoute(@RequestBody GroupRequest groupRequest){
BaseResponse res = new BaseResponse();
LOGGER.info("msg=[{}]",groupRequest.toString());
res.setCode(StatusEnum.SUCCESS.getCode()) ;
res.setMessage(StatusEnum.SUCCESS.getMessage()) ;
return res ;
}
/**
* 私聊路由
* @param p2pRequest
* @return
*/
@ApiOperation("私聊 API")
@RequestMapping(value = "p2pRoute",method = RequestMethod.POST)
@ResponseBody()
public BaseResponse p2pRoute(@RequestBody P2PRequest p2pRequest){
BaseResponse res = new BaseResponse();
res.setCode(StatusEnum.SUCCESS.getCode()) ;
res.setMessage(StatusEnum.SUCCESS.getMessage()) ;
return res ;
}
}
... ...
package com.crossoverjie.cim.route.vo.req;
import com.crossoverjie.netty.action.common.req.BaseRequest;
import io.swagger.annotations.ApiModelProperty;
import javax.validation.constraints.NotNull;
/**
* Function: Google Protocol 编解码发送
*
* @author crossoverJie
* Date: 2018/05/21 15:56
* @since JDK 1.8
*/
public class GroupRequest 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;
}
@Override
public String toString() {
return "GroupRequest{" +
"msg='" + msg + '\'' +
"} " + super.toString();
}
}
... ...
package com.crossoverjie.cim.route.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 P2PRequest 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.cim.route.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 ;
@NotNull(message = "id 不能为空")
@ApiModelProperty(required = true, value = "id", example = "11")
private long id ;
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
}
... ...
package com.crossoverjie.cim.route.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;
}
}
... ...
spring.application.name=cim-forward-route
# web port
server.port=8083
# 是否打开swagger
swagger.enable = true
logging.level.root=info
# 关闭健康检查权限
management.security.enabled=false
... ...
... ... @@ -19,6 +19,11 @@
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<scope>compile</scope>
... ...
package com.crossoverjie.netty.action.client.config;
import com.crossoverjie.netty.action.common.pojo.CustomProtocol;
import org.springframework.beans.factory.annotation.Configurable;
import com.crossoverjie.netty.action.common.protocol.BaseRequestProto;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
... ... @@ -16,12 +15,18 @@ import org.springframework.context.annotation.Configuration;
@Configuration
public class HeartBeatConfig {
@Value("${channel.id}")
private long id ;
@Value("${client.request.id}")
private int requestId;
@Bean(value = "heartBeat")
public CustomProtocol heartBeat(){
return new CustomProtocol(id,"ping") ;
public BaseRequestProto.RequestProtocol heartBeat() {
BaseRequestProto.RequestProtocol heart = BaseRequestProto.RequestProtocol.newBuilder()
.setRequestId(requestId)
.setReqMsg("ping")
.build();
return heart;
}
}
... ...
... ... @@ -11,6 +11,10 @@ import com.crossoverjie.netty.action.common.pojo.CustomProtocol;
import com.crossoverjie.netty.action.common.res.BaseResponse;
import com.crossoverjie.netty.action.common.res.NULLBody;
import io.swagger.annotations.ApiOperation;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.metrics.CounterService;
import org.springframework.stereotype.Controller;
... ... @@ -19,6 +23,8 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import java.io.IOException;
/**
* Function:
*
... ... @@ -111,4 +117,50 @@ public class IndexController {
res.setMessage(StatusEnum.SUCCESS.getMessage()) ;
return res ;
}
/**
* 群发消息
* @param sendMsgReqVO
* @return
*/
@ApiOperation("群发消息")
@RequestMapping(value = "sendGroupMsg",method = RequestMethod.POST)
@ResponseBody
public BaseResponse<SendMsgResVO> sendGroupMsg(@RequestBody SendMsgReqVO sendMsgReqVO) throws IOException {
BaseResponse<SendMsgResVO> res = new BaseResponse();
OkHttpClient client = new OkHttpClient();
MediaType MEDIA_TYPE_MARKDOWN
= MediaType.parse("text/x-markdown; charset=utf-8");
String postBody = ""
+ "Releases\n"
+ "--------\n"
+ "\n"
+ " * _1.0_ May 6, 2013\n"
+ " * _1.1_ June 15, 2013\n"
+ " * _1.2_ August 11, 2013\n";
Request request = new Request.Builder()
.url("https://api.github.com/markdown/raw")
.post(okhttp3.RequestBody.create(MEDIA_TYPE_MARKDOWN, postBody))
.build();
Response response = client.newCall(request).execute();
if (!response.isSuccessful()){
throw new IOException("Unexpected code " + response);
}
System.out.println(response.body().string());
counterService.increment(Constants.COUNTER_SERVER_PUSH_COUNT);
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.handle;
import com.crossoverjie.netty.action.client.util.SpringBeanFactory;
import com.crossoverjie.netty.action.common.pojo.CustomProtocol;
import com.crossoverjie.netty.action.common.protocol.BaseRequestProto;
import com.crossoverjie.netty.action.common.protocol.BaseResponseProto;
import io.netty.channel.ChannelFutureListener;
... ... @@ -21,10 +23,7 @@ public class EchoClientHandle extends SimpleChannelInboundHandler<BaseResponsePr
private final static Logger LOGGER = LoggerFactory.getLogger(EchoClientHandle.class);
private final BaseRequestProto.RequestProtocol heart = BaseRequestProto.RequestProtocol.newBuilder()
.setRequestId(99999999)
.setReqMsg("ping")
.build();
@Override
... ... @@ -36,7 +35,8 @@ public class EchoClientHandle extends SimpleChannelInboundHandler<BaseResponsePr
if (idleStateEvent.state() == IdleState.WRITER_IDLE){
LOGGER.info("已经 10 秒没有发送信息!");
//向服务端发送消息
ctx.writeAndFlush(heart).addListener(ChannelFutureListener.CLOSE_ON_FAILURE) ;
BaseRequestProto.RequestProtocol heartBeat = SpringBeanFactory.getBean("heartBeat", BaseRequestProto.RequestProtocol.class);
ctx.writeAndFlush(heartBeat).addListener(ChannelFutureListener.CLOSE_ON_FAILURE) ;
}
... ...
... ... @@ -11,8 +11,8 @@ netty.server.port=11211
logging.level.root=info
# 通道 ID
channel.id=100
# 客户端唯一ID
client.request.id=100
# 关闭健康检查权限
... ...
... ... @@ -12,6 +12,7 @@ import org.springframework.boot.actuate.metrics.CounterService;
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.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
/**
... ... @@ -41,7 +42,7 @@ public class IndexController {
* @return
*/
@ApiOperation("服务端发送消息")
@RequestMapping("sendMsg")
@RequestMapping(value = "sendMsg",method = RequestMethod.POST)
@ResponseBody
public BaseResponse<SendMsgResVO> sendMsg(@RequestBody SendMsgReqVO sendMsgReqVO){
BaseResponse<SendMsgResVO> res = new BaseResponse();
... ... @@ -56,4 +57,5 @@ public class IndexController {
res.setDataBody(sendMsgResVO) ;
return res ;
}
}
... ...
... ... @@ -32,13 +32,18 @@
<module>netty-action-common</module>
<module>springboot-admin</module>
<module>netty-action-zk</module>
<module>cim-forward-route</module>
</modules>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.3.1</version>
</dependency>
<dependency>
<groupId>com.github.sgroschupf</groupId>
<artifactId>zkclient</artifactId>
... ...