作者 crossoverJie

:sparkles: Introducing new features.服务端分开 push

正在显示 15 个修改的文件 包含 247 行增加24 行删除
  1 +package com.crossoverjie.netty.action.common.constant;
  2 +
  3 +/**
  4 + * Function:常量
  5 + *
  6 + * @author crossoverJie
  7 + * Date: 28/03/2018 17:41
  8 + * @since JDK 1.8
  9 + */
  10 +public class Constants {
  11 +
  12 +
  13 + /**
  14 + * 服务端手动 push 次数
  15 + */
  16 + public static final String COUNTER_SERVER_PUSH_COUNT = "counter.server.push.count" ;
  17 +
  18 +
  19 + /**
  20 + * 客户端手动 push 次数
  21 + */
  22 + public static final String COUNTER_CLIENT_PUSH_COUNT = "counter.client.push.count" ;
  23 +
  24 +
  25 +}
1 package com.crossoverjie.netty.action.common.pojo; 1 package com.crossoverjie.netty.action.common.pojo;
2 2
  3 +import java.io.Serializable;
  4 +
3 /** 5 /**
4 * Function: 6 * Function:
5 * 7 *
@@ -7,8 +9,9 @@ package com.crossoverjie.netty.action.common.pojo; @@ -7,8 +9,9 @@ package com.crossoverjie.netty.action.common.pojo;
7 * Date: 17/05/2018 17:50 9 * Date: 17/05/2018 17:50
8 * @since JDK 1.8 10 * @since JDK 1.8
9 */ 11 */
10 -public class CustomProtocol { 12 +public class CustomProtocol implements Serializable{
11 13
  14 + private static final long serialVersionUID = 4671171056588401542L;
12 private long id ; 15 private long id ;
13 private String content ; 16 private String content ;
14 17
  1 +package com.crossoverjie.netty.action.client.config;
  2 +
  3 +import com.crossoverjie.netty.action.common.pojo.CustomProtocol;
  4 +import org.springframework.beans.factory.annotation.Configurable;
  5 +import org.springframework.beans.factory.annotation.Value;
  6 +import org.springframework.context.annotation.Bean;
  7 +import org.springframework.context.annotation.Configuration;
  8 +
  9 +/**
  10 + * Function:构建心跳使用的 bean
  11 + *
  12 + * @author crossoverJie
  13 + * Date: 24/05/2018 15:55
  14 + * @since JDK 1.8
  15 + */
  16 +@Configuration
  17 +public class HeartBeatConfig {
  18 +
  19 + @Value("${channel.id}")
  20 + private long id ;
  21 +
  22 +
  23 + @Bean(value = "heartBeat")
  24 + public CustomProtocol heartBeat(){
  25 + return new CustomProtocol(id,"ping") ;
  26 + }
  27 +}
@@ -3,12 +3,14 @@ package com.crossoverjie.netty.action.client.controller; @@ -3,12 +3,14 @@ package com.crossoverjie.netty.action.client.controller;
3 import com.crossoverjie.netty.action.client.HeartbeatClient; 3 import com.crossoverjie.netty.action.client.HeartbeatClient;
4 import com.crossoverjie.netty.action.client.vo.req.SendMsgReqVO; 4 import com.crossoverjie.netty.action.client.vo.req.SendMsgReqVO;
5 import com.crossoverjie.netty.action.client.vo.res.SendMsgResVO; 5 import com.crossoverjie.netty.action.client.vo.res.SendMsgResVO;
  6 +import com.crossoverjie.netty.action.common.constant.Constants;
6 import com.crossoverjie.netty.action.common.enums.StatusEnum; 7 import com.crossoverjie.netty.action.common.enums.StatusEnum;
7 import com.crossoverjie.netty.action.common.pojo.CustomProtocol; 8 import com.crossoverjie.netty.action.common.pojo.CustomProtocol;
8 import com.crossoverjie.netty.action.common.res.BaseResponse; 9 import com.crossoverjie.netty.action.common.res.BaseResponse;
9 import com.crossoverjie.netty.action.common.util.RandomUtil; 10 import com.crossoverjie.netty.action.common.util.RandomUtil;
10 import io.swagger.annotations.ApiOperation; 11 import io.swagger.annotations.ApiOperation;
11 import org.springframework.beans.factory.annotation.Autowired; 12 import org.springframework.beans.factory.annotation.Autowired;
  13 +import org.springframework.boot.actuate.metrics.CounterService;
12 import org.springframework.stereotype.Controller; 14 import org.springframework.stereotype.Controller;
13 import org.springframework.web.bind.annotation.RequestBody; 15 import org.springframework.web.bind.annotation.RequestBody;
14 import org.springframework.web.bind.annotation.RequestMapping; 16 import org.springframework.web.bind.annotation.RequestMapping;
@@ -25,6 +27,12 @@ import org.springframework.web.bind.annotation.ResponseBody; @@ -25,6 +27,12 @@ import org.springframework.web.bind.annotation.ResponseBody;
25 @RequestMapping("/") 27 @RequestMapping("/")
26 public class IndexController { 28 public class IndexController {
27 29
  30 + /**
  31 + * 统计 service
  32 + */
  33 + @Autowired
  34 + private CounterService counterService;
  35 +
28 @Autowired 36 @Autowired
29 private HeartbeatClient heartbeatClient ; 37 private HeartbeatClient heartbeatClient ;
30 38
@@ -33,13 +41,15 @@ public class IndexController { @@ -33,13 +41,15 @@ public class IndexController {
33 * @param sendMsgReqVO 41 * @param sendMsgReqVO
34 * @return 42 * @return
35 */ 43 */
36 - @ApiOperation("发送消息") 44 + @ApiOperation("客户端发送消息")
37 @RequestMapping("sendMsg") 45 @RequestMapping("sendMsg")
38 @ResponseBody 46 @ResponseBody
39 public BaseResponse<SendMsgResVO> sendMsg(@RequestBody SendMsgReqVO sendMsgReqVO){ 47 public BaseResponse<SendMsgResVO> sendMsg(@RequestBody SendMsgReqVO sendMsgReqVO){
40 BaseResponse<SendMsgResVO> res = new BaseResponse(); 48 BaseResponse<SendMsgResVO> res = new BaseResponse();
41 heartbeatClient.sendMsg(new CustomProtocol(sendMsgReqVO.getId(),sendMsgReqVO.getMsg())) ; 49 heartbeatClient.sendMsg(new CustomProtocol(sendMsgReqVO.getId(),sendMsgReqVO.getMsg())) ;
42 50
  51 + counterService.increment(Constants.COUNTER_CLIENT_PUSH_COUNT);
  52 +
43 SendMsgResVO sendMsgResVO = new SendMsgResVO() ; 53 SendMsgResVO sendMsgResVO = new SendMsgResVO() ;
44 sendMsgResVO.setMsg("OK") ; 54 sendMsgResVO.setMsg("OK") ;
45 res.setCode(StatusEnum.SUCCESS.getCode()) ; 55 res.setCode(StatusEnum.SUCCESS.getCode()) ;
1 package com.crossoverjie.netty.action.client.handle; 1 package com.crossoverjie.netty.action.client.handle;
2 2
  3 +import com.crossoverjie.netty.action.client.util.SpringBeanFactory;
3 import com.crossoverjie.netty.action.common.pojo.CustomProtocol; 4 import com.crossoverjie.netty.action.common.pojo.CustomProtocol;
4 import io.netty.buffer.ByteBuf; 5 import io.netty.buffer.ByteBuf;
5 import io.netty.buffer.Unpooled; 6 import io.netty.buffer.Unpooled;
@@ -23,6 +24,7 @@ public class EchoClientHandle extends SimpleChannelInboundHandler<ByteBuf> { @@ -23,6 +24,7 @@ public class EchoClientHandle extends SimpleChannelInboundHandler<ByteBuf> {
23 private final static Logger LOGGER = LoggerFactory.getLogger(EchoClientHandle.class); 24 private final static Logger LOGGER = LoggerFactory.getLogger(EchoClientHandle.class);
24 25
25 26
  27 +
26 @Override 28 @Override
27 public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { 29 public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
28 30
@@ -31,9 +33,9 @@ public class EchoClientHandle extends SimpleChannelInboundHandler<ByteBuf> { @@ -31,9 +33,9 @@ public class EchoClientHandle extends SimpleChannelInboundHandler<ByteBuf> {
31 33
32 if (idleStateEvent.state() == IdleState.WRITER_IDLE){ 34 if (idleStateEvent.state() == IdleState.WRITER_IDLE){
33 LOGGER.info("已经 10 秒没有发送信息!"); 35 LOGGER.info("已经 10 秒没有发送信息!");
34 - //向客户端发送消息  
35 - CustomProtocol customProtocol = new CustomProtocol(45678L,"ping") ;  
36 - ctx.writeAndFlush(Unpooled.copiedBuffer(customProtocol.toString(), CharsetUtil.UTF_8)) ; 36 + //向服务端发送消息
  37 + CustomProtocol heartBeat = SpringBeanFactory.getBean("heartBeat", CustomProtocol.class);
  38 + ctx.writeAndFlush(heartBeat) ;
37 } 39 }
38 40
39 41
  1 +package com.crossoverjie.netty.action.client.util;
  2 +
  3 +import org.springframework.beans.BeansException;
  4 +import org.springframework.context.ApplicationContext;
  5 +import org.springframework.context.ApplicationContextAware;
  6 +import org.springframework.stereotype.Component;
  7 +
  8 +@Component
  9 +public final class SpringBeanFactory implements ApplicationContextAware{
  10 + private static ApplicationContext context;
  11 +
  12 + public static <T> T getBean(Class<T> c){
  13 + return context.getBean(c);
  14 + }
  15 +
  16 +
  17 + public static <T> T getBean(String name,Class<T> clazz){
  18 + return context.getBean(name,clazz);
  19 + }
  20 +
  21 + @Override
  22 + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
  23 + context = applicationContext;
  24 + }
  25 +
  26 +
  27 +}
@@ -11,6 +11,8 @@ netty.server.port=11211 @@ -11,6 +11,8 @@ netty.server.port=11211
11 11
12 logging.level.root=info 12 logging.level.root=info
13 13
  14 +channel.id=100
  15 +
14 16
15 # 关闭健康检查权限 17 # 关闭健康检查权限
16 management.security.enabled=false 18 management.security.enabled=false
  1 +package com.crossoverjie.netty.action.config;
  2 +
  3 +import com.crossoverjie.netty.action.endpoint.CustomEndpoint;
  4 +import org.springframework.beans.factory.annotation.Value;
  5 +import org.springframework.context.annotation.Bean;
  6 +import org.springframework.context.annotation.Configuration;
  7 +
  8 +/**
  9 + * Function: 监控端点配置
  10 + *
  11 + * @author crossoverJie
  12 + * Date: 17/04/2018 15:48
  13 + * @since JDK 1.8
  14 + */
  15 +@Configuration
  16 +public class EndPointConfig {
  17 +
  18 +
  19 + @Value("${monitor.channel.map.key}")
  20 + private String sortList;
  21 +
  22 + @Bean
  23 + public CustomEndpoint buildEndPoint(){
  24 + CustomEndpoint customEndpoint = new CustomEndpoint(sortList) ;
  25 + return customEndpoint ;
  26 + }
  27 +}
1 package com.crossoverjie.netty.action.controller; 1 package com.crossoverjie.netty.action.controller;
2 2
  3 +import com.crossoverjie.netty.action.common.constant.Constants;
3 import com.crossoverjie.netty.action.common.enums.StatusEnum; 4 import com.crossoverjie.netty.action.common.enums.StatusEnum;
4 import com.crossoverjie.netty.action.common.pojo.CustomProtocol; 5 import com.crossoverjie.netty.action.common.pojo.CustomProtocol;
5 import com.crossoverjie.netty.action.common.res.BaseResponse; 6 import com.crossoverjie.netty.action.common.res.BaseResponse;
@@ -9,6 +10,7 @@ import com.crossoverjie.netty.action.vo.req.SendMsgReqVO; @@ -9,6 +10,7 @@ import com.crossoverjie.netty.action.vo.req.SendMsgReqVO;
9 import com.crossoverjie.netty.action.vo.res.SendMsgResVO; 10 import com.crossoverjie.netty.action.vo.res.SendMsgResVO;
10 import io.swagger.annotations.ApiOperation; 11 import io.swagger.annotations.ApiOperation;
11 import org.springframework.beans.factory.annotation.Autowired; 12 import org.springframework.beans.factory.annotation.Autowired;
  13 +import org.springframework.boot.actuate.metrics.CounterService;
12 import org.springframework.stereotype.Controller; 14 import org.springframework.stereotype.Controller;
13 import org.springframework.web.bind.annotation.RequestBody; 15 import org.springframework.web.bind.annotation.RequestBody;
14 import org.springframework.web.bind.annotation.RequestMapping; 16 import org.springframework.web.bind.annotation.RequestMapping;
@@ -30,18 +32,27 @@ public class IndexController { @@ -30,18 +32,27 @@ public class IndexController {
30 @Autowired 32 @Autowired
31 private HeartBeatServer heartbeatClient ; 33 private HeartBeatServer heartbeatClient ;
32 34
  35 +
  36 + /**
  37 + * 统计 service
  38 + */
  39 + @Autowired
  40 + private CounterService counterService;
  41 +
33 /** 42 /**
34 * 向服务端发消息 43 * 向服务端发消息
35 * @param sendMsgReqVO 44 * @param sendMsgReqVO
36 * @return 45 * @return
37 */ 46 */
38 - @ApiOperation("发送消息") 47 + @ApiOperation("服务端发送消息")
39 @RequestMapping("sendMsg") 48 @RequestMapping("sendMsg")
40 @ResponseBody 49 @ResponseBody
41 public BaseResponse<SendMsgResVO> sendMsg(@RequestBody SendMsgReqVO sendMsgReqVO){ 50 public BaseResponse<SendMsgResVO> sendMsg(@RequestBody SendMsgReqVO sendMsgReqVO){
42 BaseResponse<SendMsgResVO> res = new BaseResponse(); 51 BaseResponse<SendMsgResVO> res = new BaseResponse();
43 heartbeatClient.sendMsg(new CustomProtocol(sendMsgReqVO.getId(),sendMsgReqVO.getMsg())) ; 52 heartbeatClient.sendMsg(new CustomProtocol(sendMsgReqVO.getId(),sendMsgReqVO.getMsg())) ;
44 53
  54 + counterService.increment(Constants.COUNTER_SERVER_PUSH_COUNT);
  55 +
45 SendMsgResVO sendMsgResVO = new SendMsgResVO() ; 56 SendMsgResVO sendMsgResVO = new SendMsgResVO() ;
46 sendMsgResVO.setMsg("OK") ; 57 sendMsgResVO.setMsg("OK") ;
47 res.setCode(StatusEnum.SUCCESS.getCode()) ; 58 res.setCode(StatusEnum.SUCCESS.getCode()) ;
  1 +package com.crossoverjie.netty.action.endpoint;
  2 +
  3 +import com.crossoverjie.netty.action.util.NettySocketHolder;
  4 +import io.netty.channel.socket.nio.NioSocketChannel;
  5 +import org.springframework.beans.factory.annotation.Autowired;
  6 +import org.springframework.boot.actuate.endpoint.AbstractEndpoint;
  7 +
  8 +import java.util.HashMap;
  9 +import java.util.List;
  10 +import java.util.Map;
  11 +
  12 +/**
  13 + * Function: 自定义端点监控
  14 + *
  15 + * @author crossoverJie
  16 + * Date: 17/04/2018 14:47
  17 + * @since JDK 1.8
  18 + */
  19 +public class CustomEndpoint extends AbstractEndpoint<Map<Long,NioSocketChannel>> {
  20 +
  21 +
  22 + /**
  23 + * 监控端点的 访问地址
  24 + * @param id
  25 + */
  26 + public CustomEndpoint(String id) {
  27 + //false 表示不是敏感端点
  28 + super(id, false);
  29 + }
  30 +
  31 + @Override
  32 + public Map<Long, NioSocketChannel> invoke() {
  33 + return NettySocketHolder.getMAP();
  34 + }
  35 +}
@@ -3,6 +3,7 @@ package com.crossoverjie.netty.action.handle; @@ -3,6 +3,7 @@ package com.crossoverjie.netty.action.handle;
3 import com.crossoverjie.netty.action.common.pojo.CustomProtocol; 3 import com.crossoverjie.netty.action.common.pojo.CustomProtocol;
4 import com.crossoverjie.netty.action.common.util.RandomUtil; 4 import com.crossoverjie.netty.action.common.util.RandomUtil;
5 import com.crossoverjie.netty.action.util.NettySocketHolder; 5 import com.crossoverjie.netty.action.util.NettySocketHolder;
  6 +import io.netty.buffer.ByteBuf;
6 import io.netty.buffer.Unpooled; 7 import io.netty.buffer.Unpooled;
7 import io.netty.channel.ChannelFutureListener; 8 import io.netty.channel.ChannelFutureListener;
8 import io.netty.channel.ChannelHandlerContext; 9 import io.netty.channel.ChannelHandlerContext;
@@ -27,6 +28,19 @@ public class HeartBeatSimpleHandle extends SimpleChannelInboundHandler<CustomPro @@ -27,6 +28,19 @@ public class HeartBeatSimpleHandle extends SimpleChannelInboundHandler<CustomPro
27 28
28 private final static Logger LOGGER = LoggerFactory.getLogger(HeartBeatSimpleHandle.class); 29 private final static Logger LOGGER = LoggerFactory.getLogger(HeartBeatSimpleHandle.class);
29 30
  31 + private static final ByteBuf HEART_BEAT = Unpooled.unreleasableBuffer(Unpooled.copiedBuffer(new CustomProtocol(123456L,"pong").toString(),CharsetUtil.UTF_8));
  32 +
  33 +
  34 + /**
  35 + * 取消绑定
  36 + * @param ctx
  37 + * @throws Exception
  38 + */
  39 + @Override
  40 + public void channelInactive(ChannelHandlerContext ctx) throws Exception {
  41 +
  42 + NettySocketHolder.remove((NioSocketChannel) ctx.channel());
  43 + }
30 44
31 @Override 45 @Override
32 public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { 46 public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
@@ -37,9 +51,7 @@ public class HeartBeatSimpleHandle extends SimpleChannelInboundHandler<CustomPro @@ -37,9 +51,7 @@ public class HeartBeatSimpleHandle extends SimpleChannelInboundHandler<CustomPro
37 if (idleStateEvent.state() == IdleState.READER_IDLE){ 51 if (idleStateEvent.state() == IdleState.READER_IDLE){
38 LOGGER.info("已经5秒没有收到信息!"); 52 LOGGER.info("已经5秒没有收到信息!");
39 //向客户端发送消息 53 //向客户端发送消息
40 - CustomProtocol customProtocol = new CustomProtocol(RandomUtil.getRandom(),"pong") ;  
41 - ctx.writeAndFlush(Unpooled.copiedBuffer(customProtocol.toString(), CharsetUtil.UTF_8))  
42 - .addListener(ChannelFutureListener.CLOSE_ON_FAILURE) ; 54 + ctx.writeAndFlush(HEART_BEAT) ;
43 } 55 }
44 56
45 57
@@ -50,7 +62,7 @@ public class HeartBeatSimpleHandle extends SimpleChannelInboundHandler<CustomPro @@ -50,7 +62,7 @@ public class HeartBeatSimpleHandle extends SimpleChannelInboundHandler<CustomPro
50 62
51 @Override 63 @Override
52 protected void channelRead0(ChannelHandlerContext ctx, CustomProtocol customProtocol) throws Exception { 64 protected void channelRead0(ChannelHandlerContext ctx, CustomProtocol customProtocol) throws Exception {
53 - LOGGER.info("customProtocol={}", customProtocol); 65 + LOGGER.info("收到customProtocol={}", customProtocol);
54 66
55 NettySocketHolder.put(customProtocol.getId(),(NioSocketChannel)ctx.channel()) ; 67 NettySocketHolder.put(customProtocol.getId(),(NioSocketChannel)ctx.channel()) ;
56 } 68 }
@@ -38,12 +38,13 @@ public class HeartBeatServer { @@ -38,12 +38,13 @@ public class HeartBeatServer {
38 38
39 39
40 @Value("${netty.server.port}") 40 @Value("${netty.server.port}")
41 - private int nettyPort ; 41 + private int nettyPort;
42 42
43 - private NioServerSocketChannel channel ; 43 + private NioServerSocketChannel channel;
44 44
45 /** 45 /**
46 * 启动 Netty 46 * 启动 Netty
  47 + *
47 * @return 48 * @return
48 * @throws InterruptedException 49 * @throws InterruptedException
49 */ 50 */
@@ -55,14 +56,14 @@ public class HeartBeatServer { @@ -55,14 +56,14 @@ public class HeartBeatServer {
55 .channel(NioServerSocketChannel.class) 56 .channel(NioServerSocketChannel.class)
56 .localAddress(new InetSocketAddress(nettyPort)) 57 .localAddress(new InetSocketAddress(nettyPort))
57 //保持长连接 58 //保持长连接
58 - .childOption(ChannelOption.SO_KEEPALIVE,true) 59 + .childOption(ChannelOption.SO_KEEPALIVE, true)
59 .childHandler(new HeartbeatInitializer()); 60 .childHandler(new HeartbeatInitializer());
60 61
61 ChannelFuture future = bootstrap.bind().sync(); 62 ChannelFuture future = bootstrap.bind().sync();
62 - if (future.isSuccess()){ 63 + if (future.isSuccess()) {
63 LOGGER.info("启动 Netty 成功"); 64 LOGGER.info("启动 Netty 成功");
64 } 65 }
65 - channel = (NioServerSocketChannel) future.channel() ; 66 + channel = (NioServerSocketChannel) future.channel();
66 } 67 }
67 68
68 69
@@ -70,22 +71,23 @@ public class HeartBeatServer { @@ -70,22 +71,23 @@ public class HeartBeatServer {
70 * 销毁 71 * 销毁
71 */ 72 */
72 @PreDestroy 73 @PreDestroy
73 - public void destroy(){  
74 - boss.shutdownGracefully().syncUninterruptibly() ;  
75 - work.shutdownGracefully().syncUninterruptibly() ; 74 + public void destroy() {
  75 + boss.shutdownGracefully().syncUninterruptibly();
  76 + work.shutdownGracefully().syncUninterruptibly();
76 LOGGER.info("关闭 Netty 成功"); 77 LOGGER.info("关闭 Netty 成功");
77 } 78 }
78 79
79 80
80 /** 81 /**
81 * 发送消息 82 * 发送消息
  83 + *
82 * @param customProtocol 84 * @param customProtocol
83 */ 85 */
84 - public void sendMsg(CustomProtocol customProtocol){ 86 + public void sendMsg(CustomProtocol customProtocol) {
85 NioSocketChannel socketChannel = NettySocketHolder.get(customProtocol.getId()); 87 NioSocketChannel socketChannel = NettySocketHolder.get(customProtocol.getId());
86 88
87 - if (null == socketChannel){  
88 - throw new NullPointerException("没有["+customProtocol.getId()+"]的socketChannel") ; 89 + if (null == socketChannel) {
  90 + throw new NullPointerException("没有[" + customProtocol.getId() + "]的socketChannel");
89 } 91 }
90 92
91 ChannelFuture future = socketChannel.writeAndFlush(Unpooled.copiedBuffer(customProtocol.toString(), CharsetUtil.UTF_8)); 93 ChannelFuture future = socketChannel.writeAndFlush(Unpooled.copiedBuffer(customProtocol.toString(), CharsetUtil.UTF_8));
@@ -15,13 +15,23 @@ import java.util.concurrent.ConcurrentHashMap; @@ -15,13 +15,23 @@ import java.util.concurrent.ConcurrentHashMap;
15 * @since JDK 1.8 15 * @since JDK 1.8
16 */ 16 */
17 public class NettySocketHolder { 17 public class NettySocketHolder {
18 - private static final Map<Long,NioSocketChannel> MAP = new ConcurrentHashMap<>(16) ; 18 + private static final Map<Long, NioSocketChannel> MAP = new ConcurrentHashMap<>(16);
19 19
20 - public static void put(Long id,NioSocketChannel socketChannel){  
21 - MAP.put(id,socketChannel) ; 20 + public static void put(Long id, NioSocketChannel socketChannel) {
  21 + MAP.put(id, socketChannel);
22 } 22 }
23 23
24 public static NioSocketChannel get(Long id) { 24 public static NioSocketChannel get(Long id) {
25 return MAP.get(id); 25 return MAP.get(id);
26 } 26 }
  27 +
  28 + public static Map<Long, NioSocketChannel> getMAP() {
  29 + return MAP;
  30 + }
  31 +
  32 + public static void remove(NioSocketChannel nioSocketChannel) {
  33 + MAP.entrySet().stream().filter(entry -> entry.getValue() == nioSocketChannel).forEach(entry -> {
  34 + MAP.remove(entry.getKey());
  35 + });
  36 + }
27 } 37 }
  1 +package com.crossoverjie.netty.action.util;
  2 +
  3 +import org.springframework.beans.BeansException;
  4 +import org.springframework.context.ApplicationContext;
  5 +import org.springframework.context.ApplicationContextAware;
  6 +import org.springframework.stereotype.Component;
  7 +
  8 +@Component
  9 +public final class SpringBeanFactory implements ApplicationContextAware{
  10 + private static ApplicationContext context;
  11 +
  12 + public static <T> T getBean(Class<T> c){
  13 + return context.getBean(c);
  14 + }
  15 +
  16 +
  17 + public static <T> T getBean(String name,Class<T> clazz){
  18 + return context.getBean(name,clazz);
  19 + }
  20 +
  21 + @Override
  22 + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
  23 + context = applicationContext;
  24 + }
  25 +
  26 +
  27 +}
@@ -15,3 +15,6 @@ logging.level.root=info @@ -15,3 +15,6 @@ logging.level.root=info
15 management.security.enabled=false 15 management.security.enabled=false
16 # SpringAdmin 地址 16 # SpringAdmin 地址
17 spring.boot.admin.url=http://127.0.0.1:8888 17 spring.boot.admin.url=http://127.0.0.1:8888
  18 +
  19 +#自定义监控端点 key
  20 +monitor.channel.map.key=channelMap