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

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

  •  
  •   gramyang · 148 天前 · 1506 次点击
    这是一个创建于 148 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

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

    第 1 条附言  ·  148 天前
    服务端:

    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 条附言  ·  148 天前
    客户端 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 条附言  ·  148 天前
    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 条附言  ·  148 天前
    无聊把 ssl 禁了再启动试了一下,终于不断开了。。。。

    这尼玛的 ssl,虐的我不要不要的。
    9 回复  |  直到 2019-05-21 10:18:47 +08:00
        1
    iamniconico   148 天前
    有没有可能是 soTimeOut 没有设置
        2
    gramyang   148 天前
    @iamniconico 你说的是 CONNECT_TIMEOUT_MILLIS ?这个前端设置了后端没设置,关键这个东西不是连接超时吗?为什么和这个有关?
        3
    loveCoding   148 天前
    是不是 netty 启动写错了,用的阻塞方式启动 netty,连接完了自动走到了 finally 里面的释放逻辑?
        4
    loveCoding   148 天前
    最好是贴下代码
        5
    gramyang   148 天前
    @loveCoding 我知道你的意思,但是肯定不是那种简单的错误。
        6
    justicelove   148 天前
    抓包分析下
        7
    gramyang   148 天前
    @justicelove 最后把 ssl 禁用了,就可以了。ssl 真的是虐死我了
        8
    anyele   148 天前
    那如果是 SSL 的问题,那怎么解决呢
        9
    iamniconico   148 天前
    @gramyang soTimeOut 是原生 Socket 中的设置,意思是最大心跳间隔,就是说这个时间段之内如果没有任何通讯,服务端就会自动关闭这个连接,同样的,netty 也有类似的设置,你可以注意下这个点,仅供参考
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   3543 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 23ms · UTC 04:18 · PVG 12:18 · LAX 21:18 · JFK 00:18
    ♥ Do have faith in what you're doing.