上篇用sleep 这篇用的是netty时间轮定时器达到类似效果 只改了通用的EchoWrite 辅助类 这个类 换成时间片实现超时重传。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 public class EchoWrite { EventExecutor e; DefaultPromise t; int times1 = 0; final Timer timer = new HashedWheelTimer(); public EchoWrite2() { this.e = new DefaultEventExecutor(); t=new DefaultPromise(this.e); } public <T> DefaultPromise echoWrite(String msg, InetSocketAddress add ,Channel c,String attrKey ,T attrValue, int times, int timeoutS) { c.writeAndFlush(new DatagramPacket(Unpooled.copiedBuffer(msg, CharsetUtil.UTF_8), add)); log.info("发出echo"); log.info("位置4 "+String.valueOf(Thread.currentThread().getId())); timer.newTimeout(new TimerTask() { public void run(Timeout timeout) throws Exception { log.info("位置3 "+String.valueOf(Thread.currentThread().getId())); AttributeKey<Integer> bechoAttr = AttributeKey.valueOf(attrKey); Attribute<Integer> bechoA = c.attr(bechoAttr); times1++; if (times1 < times) { bechoA = c.attr(bechoAttr); if (bechoA.get() == attrValue) { t.setSuccess(true); } else { log.info("发出echo"); c.writeAndFlush(new DatagramPacket(Unpooled.copiedBuffer(msg, CharsetUtil.UTF_8), add)); timer.newTimeout(this, timeoutS, TimeUnit.SECONDS); } } if (times1 == times) { Exception ex = new Exception("超时没有回应"); t.setFailure(ex); } } }, timeoutS, TimeUnit.SECONDS); return t; } }
这个超时重传在tcp里也可以使用应该。。。不过由于udp传输可靠性没有。可以保证操作的可靠性,还有一定的保活的作用。 这里的times1是不是线程安全。。。。 如果多个线程都要可靠性发数据 那么是不是每个线程都弄个times1变量?会不会存在几个线程用一个EchoWrite对象的情况。
在琢磨琢磨 ,好像attr是线程安全的。