V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
gramyang
V2EX  ›  Java

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

  •  
  •   gramyang · 2019-05-20 14:51:43 +08:00 · 5081 次点击
    这是一个创建于 2016 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

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

    第 1 条附言  ·  2019-05-20 15:50:27 +08:00
    服务端:

    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));
    }
    第 2 条附言  ·  2019-05-20 15:52:52 +08:00
    客户端 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));
    }
    });
    }
    第 3 条附言  ·  2019-05-20 15:53:15 +08:00
    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();
    }
    }
    });
    }
    });
    }
    第 4 条附言  ·  2019-05-20 17:03:01 +08:00
    无聊把 ssl 禁了再启动试了一下,终于不断开了。。。。

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