| | |
| | | import com.xcong.excoin.netty.common.Contans; |
| | | import com.xcong.excoin.netty.common.NettyTools; |
| | | import com.xcong.excoin.netty.dispatch.MsgDispatch; |
| | | import com.xcong.excoin.utils.SpringContextHolder; |
| | | import io.netty.buffer.ByteBuf; |
| | | import io.netty.buffer.Unpooled; |
| | | import io.netty.channel.*; |
| | |
| | | import static io.netty.handler.codec.http.HttpUtil.isKeepAlive; |
| | | |
| | | /** |
| | | * @author wzy |
| | | * @email wangdoubleone@gmail.com |
| | | * @date 2019-05-06 |
| | | * 项目启动时,在控制台有 |
| | | * Unable to proxy interface-implementing method [public final void io.netty.channel.ChannelInitializer.channelRegistered(io.netty.channel.ChannelHandlerContext) throws java.lang.Exception] because it is marked as final: Consider using interface-based JDK proxies instead! |
| | | * 输出 |
| | | * 表明,此类将走代理enhancerbyspringcglib代理 |
| | | * 此时,获取到此类将为null(不知道原因),从而导致netty连接在初始化时会有空指针异常 |
| | | */ |
| | | @Slf4j |
| | | @Component |
| | |
| | | |
| | | private WebSocketServerHandshaker handshaker; |
| | | |
| | | @Resource(name = "msgDispatch") |
| | | private MsgDispatch msgDispatch; |
| | | // @Resource(name = "msgDispatch") |
| | | // private MsgDispatch msgDispatch; |
| | | |
| | | @Override |
| | | public void channelActive(ChannelHandlerContext ctx) throws Exception { |
| | |
| | | content = ((TextWebSocketFrame) frame).text(); |
| | | if (content.contains(Contans.HEART_BEAT)) { |
| | | resetTimes(ctx.channel()); |
| | | // ctx.channel().writeAndFlush(NettyTools.webSocketBytes(Contans.HEART_BEAT)); |
| | | } else { |
| | | this.msgDispatch.webSocketDispatch(ctx, content); |
| | | SpringContextHolder.getBean(MsgDispatch.class).webSocketDispatch(ctx, content); |
| | | } |
| | | } catch (ClassCastException e) { |
| | | content = ((CloseWebSocketFrame) frame).reasonText(); |
| | |
| | | |
| | | @Override |
| | | public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { |
| | | log.info("[触发器触发]"); |
| | | // super.userEventTriggered(ctx, evt); |
| | | // log.info("[触发器触发]"); |
| | | if (evt instanceof IdleStateEvent) { |
| | | IdleStateEvent event = (IdleStateEvent) evt; |
| | | if (event.state() == IdleState.READER_IDLE) { |
| | | |
| | | Integer times = pingTimes.get(ctx.channel().id().asShortText()); |
| | | if (times == null) { |
| | | times = 0; |
| | | } |
| | | /*读超时*/ |
| | | // log.info("===服务端===({}读超时, {})", ctx.channel().id().asShortText(), times); |
| | | // 失败计数器次数大于等于3次的时候,关闭链接,等待client重连 |
| | | if (times >= MAX_UN_REC_PING_TIMES) { |
| | | log.info("===服务端===(读超时,关闭chanel)"); |
| | | // 连续超过N次未收到client的ping消息,那么关闭该通道,等待client重连 |
| | | ctx.channel().close(); |
| | | } else { |
| | | // 失败计数器加1 |
| | | times++; |
| | | pingTimes.remove(ctx.channel().id().asShortText()); |
| | | pingTimes.put(ctx.channel().id().asShortText(), times); |
| | | } |
| | | } else if (event.state() == IdleState.WRITER_IDLE) { |
| | | /*写超时*/ |
| | | ctx.channel().writeAndFlush(NettyTools.webSocketBytes(Contans.HEART_BEAT)); |