V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
gramyang
V2EX  ›  Java

netty 连接成功后过几秒马上又中断,这是什么鬼?

  •  
  •   gramyang · May 20, 2019 · 5760 views
    This topic created in 2533 days ago, the information mentioned may be changed or developed.

    前端 android,后端 springboot,连接用的 netty,用 tls 加密了的。环境是 win10 本机同时部署客户端和服务端。

    每次都是连接成功后过几秒又会断开连接。这期间发送请求都会发送失败。断开连接时触发 channelinactive 方法。

    前后端的 log 中没有任何报错或者警告信息,因为我已经排除过了。

    如果不是前后端代码的问题,而是什么别的问题(例如防火墙),该如何排查?

    Supplement 1  ·  May 20, 2019
    服务端:

    ServerBootstrap b = new ServerBootstrap();
    b.group(boss, work)
    .channel(NioServerSocketChannel.class)
    .option(ChannelOption.SO_BACKLOG, 128)
    .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10 * 1000)
    .childOption(ChannelOption.TCP_NODELAY, true)
    .childHandler(this)
    .bind(6789)
    .addListener(new ChannelFutureListener() {
    @Override
    public void operationComplete(ChannelFuture future) throws Exception {
    future.removeListener(this);
    if(!future.isSuccess() && future.cause() != null) log.error("服务器绑定端口失败", future.cause());
    if(future.isSuccess()) log.info("服务器绑定端口成功");
    }
    });

    @Override
    protected void initChannel(NioSocketChannel ch) throws Exception {
    ChannelPipeline pipeline = ch.pipeline();
    ByteBuf delimiter = Unpooled.copiedBuffer(Constant.LINE_SEPARATOR.getBytes());
    pipeline.addLast(new IdleStateHandler(60,60, 0));
    pipeline.addLast(new DelimiterBasedFrameDecoder(2048,delimiter));
    pipeline.addLast(new StringDecoder(Charset.forName("UTF-8")));
    pipeline.addLast(new StringEncoder(Charset.forName("UTF-8")));
    pipeline.addLast(handleGroup, new NettyServerHandler(playerMap, tableMap, userName2Player));
    SSLEngine engine = ContextSSLFactory.getServerSslContext().createSSLEngine();
    engine.setUseClientMode(false);
    engine.setNeedClientAuth(true);
    pipeline.addFirst(new SslHandler(engine));
    }
    Supplement 2  ·  May 20, 2019
    客户端 1

    private GameClient() {
    EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
    bootstrap = new Bootstrap();
    bootstrap.group(eventLoopGroup)
    .channel(NioSocketChannel.class)
    .option(ChannelOption.TCP_NODELAY, true)
    .option(ChannelOption.SO_KEEPALIVE, true)
    .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, CONNECT_TIMEOUT)
    .handler(new ChannelInitializer<NioSocketChannel>() {
    @Override
    protected void initChannel(NioSocketChannel ch) throws Exception {
    ChannelPipeline pipeline = ch.pipeline();
    ByteBuf delimiter = Unpooled.copiedBuffer(Constants.LINE_SEPARATOR.getBytes());
    pipeline.addLast(new IdleStateHandler(60, 60, 0));
    pipeline.addLast(new DelimiterBasedFrameDecoder(2048, delimiter));
    pipeline.addLast(new StringDecoder(Charset.forName("UTF-8")));
    pipeline.addLast(new StringEncoder(Charset.forName("UTF-8")));
    pipeline.addLast(new GameClientHandler());
    SSLEngine engine = ContextSSLFactory.getInstance().getClientSslContext().createSSLEngine();
    engine.setUseClientMode(true);
    pipeline.addFirst(new SslHandler(engine, true));
    }
    });
    }
    Supplement 3  ·  May 20, 2019
    public void connectServer() {
    if(isConnected() || !semaphore.tryAcquire()) return;
    executor.execute(new Runnable() {
    @Override
    public void run() {
    Logger.i("正在连接游戏服务器" + Constants.gameHost + ":" + Constants.gamePort + ".......");
    InetSocketAddress remoteAddress = new InetSocketAddress(Constants.gameHost, Constants.gamePort);
    bootstrap.connect(remoteAddress).addListener(new ChannelFutureListener() {
    @Override
    public void operationComplete(ChannelFuture future) throws Exception {
    semaphore.release();
    future.removeListener(this);
    if(!future.isSuccess() && future.cause() != null) handleConnectFailure(future.cause(), remoteAddress);
    if(future.isSuccess()) {
    Logger.w("服务器连接成功" + remoteAddress.getHostName() + ":" + remoteAddress.getPort());
    channel = future.channel();
    }
    }
    });
    }
    });
    }
    Supplement 4  ·  May 20, 2019
    无聊把 ssl 禁了再启动试了一下,终于不断开了。。。。

    这尼玛的 ssl,虐的我不要不要的。
    10 replies    2020-05-07 17:18:11 +08:00
    iamniconico
        1
    iamniconico  
       May 20, 2019
    有没有可能是 soTimeOut 没有设置
    gramyang
        2
    gramyang  
    OP
       May 20, 2019
    @iamniconico 你说的是 CONNECT_TIMEOUT_MILLIS ?这个前端设置了后端没设置,关键这个东西不是连接超时吗?为什么和这个有关?
    loveCoding
        3
    loveCoding  
       May 20, 2019
    是不是 netty 启动写错了,用的阻塞方式启动 netty,连接完了自动走到了 finally 里面的释放逻辑?
    loveCoding
        4
    loveCoding  
       May 20, 2019
    最好是贴下代码
    gramyang
        5
    gramyang  
    OP
       May 20, 2019
    @loveCoding 我知道你的意思,但是肯定不是那种简单的错误。
    justicelove
        6
    justicelove  
       May 20, 2019
    抓包分析下
    gramyang
        7
    gramyang  
    OP
       May 20, 2019
    @justicelove 最后把 ssl 禁用了,就可以了。ssl 真的是虐死我了
    anyele
        8
    anyele  
       May 21, 2019
    那如果是 SSL 的问题,那怎么解决呢
    iamniconico
        9
    iamniconico  
       May 21, 2019
    @gramyang soTimeOut 是原生 Socket 中的设置,意思是最大心跳间隔,就是说这个时间段之内如果没有任何通讯,服务端就会自动关闭这个连接,同样的,netty 也有类似的设置,你可以注意下这个点,仅供参考
    resist
        10
    resist  
       May 7, 2020
    我好像也遇到了这种情况,一连接就断开了,read 都不跑,我用 IDE 运行了一个客户端是正常的,然后用模拟器运行了一个 APP 客户端,一连就断,也不知道什么原因,代码是一样的。。。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   4182 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 52ms · UTC 05:26 · PVG 13:26 · LAX 22:26 · JFK 01:26
    ♥ Do have faith in what you're doing.