KKSU
2024-09-30 36be00e0f3cbe0d559c646fd2977e6e3a74aa6f9
src/main/java/com/xcong/excoin/netty/handler/WebSocketServerHandler.java
@@ -5,6 +5,7 @@
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.*;
@@ -29,9 +30,11 @@
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
@@ -44,8 +47,8 @@
    private WebSocketServerHandshaker handshaker;
    @Resource(name = "msgDispatch")
    private MsgDispatch msgDispatch;
//    @Resource(name = "msgDispatch")
//    private MsgDispatch msgDispatch;
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
@@ -75,8 +78,9 @@
                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();
@@ -87,12 +91,27 @@
    @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));