如何让netty channel.writeAndFlush()在没有TCP ACK响应时抛出异常

时间:2016-04-19 12:24:02

标签: java exception netty

我正在使用Netty4框架开发IM服务器。同时我使用名为channel.writeAndFlush()的方法向客户端发送消息。然而,当移动电话上的客户端的插座异常关闭(例如关闭网络连接或打开设备上的飞行模式)时,netty4帧不会发现相应的信道处于非活动状态。此外,ChannelGroupFuture方法返回的writeAndFlush()使用方法ChannelGroupFuture.isSuccess()报告发送结果成功。 那么,为什么ChannelGroupFuture没有返回我发送失败而没有抛出任何异常?

ChannelGroupFuture future = connectionService.sendMessageToUser(msgBase, toUid).sync();

future.addListeners(new ChannelGroupFutureListener(){

@Override
                public void operationComplete(ChannelGroupFuture future)
                        throws Exception {
                    if(future.isDone() && future.isSuccess()){
                        chatMessageService.saveSentChatMessage(msgBase);
                    } else if(!future.isSuccess()){
                        chatMessageService.saveUnsentChatMessage(msgBase);
                    }
});

 public ChannelGroupFuture writeAndFlush(Object message, ChannelMatcher matcher) {
    if (message == null) {
        throw new NullPointerException("message");
    }
    if (matcher == null) {
        throw new NullPointerException("matcher");
    }
    if(matcher instanceof AttributeChannelMatcher){
        Map<Channel, ChannelFuture> futures = new LinkedHashMap<Channel, ChannelFuture>(1);
        AttributeChannelMatcher<T>  attributeMatcher = (AttributeChannelMatcher<T>) matcher;
        Channel c = nonServerChannelMap.get(attributeMatcher.getAttributeKeyValue());

        futures.put(c, c.writeAndFlush(safeDuplicate(message)));
        ReferenceCountUtil.release(message);
        return new DefaultChannelGroupFuture(this, futures, executor);
    }else{
        Map<Channel, ChannelFuture> futures = new LinkedHashMap<Channel, ChannelFuture>(size());

        for (Channel c :  nonServerChannelMap.values()) {
            if (matcher.matches(c)) {
                futures.put(c, c.writeAndFlush(safeDuplicate(message)));
            }
        }
        ReferenceCountUtil.release(message);
        return new DefaultChannelGroupFuture(this, futures, executor);
    }
}

1 个答案:

答案 0 :(得分:3)

你不能。 TCP写入与应用程序是异步的。他们在返回之前不会等待ACK。发送端有一个发送缓冲区,接收端有一个接收缓冲区。所有这些意味着它可能需要多次写入,并且在您检测到断开连接之前需要几秒钟。