HeartBeatTask implements Runnable { public void run() { try { long now = System.currentTimeMillis(); for ( Channel channel : channelProvider.getChannels() ) { if (channel.isClosed()) { continue; } try { Long lastRead = ( Long ) channel.getAttribute( HeaderExchangeHandler.KEY_READ_TIMESTAMP ); Long lastWrite = ( Long ) channel.getAttribute( HeaderExchangeHandler.KEY_WRITE_TIMESTAMP ); if ( ( lastRead != null && now - lastRead > heartbeat ) || ( lastWrite != null && now - lastWrite > heartbeat ) ) { Request req = new Request(); req.setVersion( "2.0.0" ); req.setTwoWay( true ); req.setEvent( Request.HEARTBEAT_EVENT ); channel.send( req ); if ( logger.isDebugEnabled() ) { logger.debug( "Send heartbeat to remote channel " + channel.getRemoteAddress() + ", cause: The channel has no data-transmission exceeds a heartbeat period: " + heartbeat + "ms" ); } } if ( lastRead != null && now - lastRead > heartbeatTimeout ) { logger.warn( "Close channel " + channel + ", because heartbeat read idle time out: " + heartbeatTimeout + "ms" ); if (channel instanceof Client) { try { ((Client)channel).reconnect(); }catch (Exception e) { } } else { channel.close(); } } } catch ( Throwable t ) { logger.warn( "Exception when heartbeat to remote channel " + channel.getRemoteAddress(), t ); } } } catch ( Throwable t ) { logger.warn( "Unhandled exception when heartbeat, cause: " + t.getMessage(), t ); } } HeartBeatTask( ChannelProvider provider, int heartbeat, int heartbeatTimeout ); void run();  }
@Test public void testHeartBeat() throws Exception { url = url.addParameter(Constants.DUBBO_VERSION_KEY, "2.1.1"); channel.setAttribute( HeaderExchangeHandler.KEY_READ_TIMESTAMP, System.currentTimeMillis()); channel.setAttribute( HeaderExchangeHandler.KEY_WRITE_TIMESTAMP, System.currentTimeMillis()); Thread.sleep( 2000L ); task.run(); List<Object> objects = channel.getSentObjects(); Assert.assertTrue(objects.size() > 0); Object obj = objects.get(0); Assert.assertTrue(obj instanceof Request); Request request = (Request)obj; Assert.assertTrue(request.isHeartbeat()); }