본문 바로가기
Programming/JAVA

[JAVA/Netty] 클라이언트의 연결 종료 확인

by Pendine 2023. 1. 17.
728x90

클라이언트 입장에서 Bootstrap을 다루고 연결 종료를 확인한 뒤 재접속을 시도하려 했지만

연결 종료를 확인하는게 불가능하다는걸 알았다.

 

 

		try {
		    if( bootstrap != null) {
		    	Future future = bootstrap.config().group().shutdownGracefully();
		    	
		    	logger.debug("future shutdownGracefully() Status :: isDone : {} , isCancelled : {} " , future.isDone(), future.isCancelled() );

//		    	while( !bootstrap.config().group().isShutdown() ) {
//		    		logger.debug( "connect info : {} / bootstrap.config().group().isShutdown() : {}" 
//		    				, conInfo.toString()
//		    				, bootstrap.config().group().isShutdown() 
//		    				);
//		    		bootstrap.config().group().wait();
//		    	}
		    	
//		    	logger.debug( "connect info : {} / bootstrap.config().group().isShutdown() : {}" 
//	    				, conInfo.toString()
//	    				, bootstrap.config().group().isShutdown() 
//	    				);
		    }
		}
		catch(Exception e) {
			logger.error("Bootstrap reset error / Exception Log : {}" , LogHelper.getPrintStackTrace(e) );
		}

 

이런식으로 bootstrap의 연결을 확실히 종료된걸 파악하고

새로운 접속을 시도하려고 해봤지만

(여기서 작성된건 if문이지만 while문으로 작성했다가 작동을 안해서 try catch문으로 감싼후에야, exception이 발생하면서 접속 관련 부분처리중 위 부분에서 오류가 터지는것과 재접속전 while문으로 bootstrap이 종료된뒤 재접속하기위해 작성했던 부분에서 뒤로 왜 안넘어가는지, 재접속이 제대로 안되는지 알게됐음.)

 

bootstrap의 종료된걸 Future 로 반환하는 메서드를 확인하고 isCanceled나 isDone으로 확인하고

isDone이 true가 반환될때까지 future의 wait를 호출해봤지만

wait를 호출하면  java.lang.IllegalMonitorStateException 를 호출한다.

 

		try { 
		    if( bootstrap != null) {
		    	Future future = bootstrap.config().group().shutdownGracefully();
		    	
		    	logger.debug("future shutdownGracefully() Status :: isDone : {} , isCancelled : {} " , future.isDone(), future.isCancelled() );
		    	
		    	if(!future.isDone()) {
		    		try {
		    			new Thread().sleep(100L);
		    		}catch(Exception e) {
		    			logger.error("bootstrap is Done / 기다리다가 오류 / Exception Log : {}" , LogHelper.getPrintStackTrace(e));
		    		}
		    	}
		    	logger.debug("future shutdownGracefully() Status :: isDone : {} , isCancelled : {} " , future.isDone(), future.isCancelled() );

이후 이렇게 추가해봤지만

 

접속 객체의 bootstrap의 future가  isDone이나 isCancelled가 true가 호출되는 일은 없었다.

 

따라서 bootstrap의 연결종료를 호출하는 shutdownGracefully를 호출한 뒤

해당 bootstrap의 연결 종료 여부를 파악하지 않고 null로 초기화, 그뒤 재접속을 위해 다시 bootstrap을 할당한뒤

재접속을 시도하도록 변경했다.

 

bootstrap이 종료된걸 확인하려고 내 나름대로 모든 수를 써봤지만 상태가 종료된걸 확인할 수는 없다.
최종적으로 종료단계의 shutdownGracefully에 들어가면 객체가 native를 반환하는 메서드가 동작하며 잠기게되는데 
모든 클래스의 syncronized에 걸렸을때 wait를 호출하게되면 객체가 lock 인 상태에서 호출을 하므로
 java.lang.illegalmonitorstateexception 이 걸리게 되고 이것 대신 notify를 이용하면 notify의 반환값은 void 이므로 정보를 알수 없다.


잘못 사용했다

 

사용한 future의 클래스를 잘못 이용했다.

내가 위의 코드에서 사용한 future는 java의 util 패키지의 future이고

사용해야하는 future는 netty의 future를 이용해야했다.

 

		try { 
		    if( bootstrap != null) {
		    	Future future = bootstrap.config().group().shutdownGracefully();
		    	
		    	logger.debug("ip : {} port : {} future shutdownGracefully() Status :: isDone : {} isSuccess : {} , isCancellable : {} , cause : {} " 
		    			, host
		    			, port
		    			, future.isDone()
		    			, future.isSuccess()
		    			, future.isCancellable() 
		    			, ((future.cause() == null ) ? "null" : LogHelper.getPrintStackTrace(future.cause() ) ) 
		    			);
		    	
		    	while(!( future.isDone() || future.isCancellable() || future.isDone() ) ) {
		    		try {
		    			logger.debug("ip : " + ip + " port : " + port + " future.await();");
		    			future.await();
		    		}catch(Exception e) {
		    			logger.error("bootstrap is Done / 기다리다가 오류 / Exception Log : {}" , LogHelper.getPrintStackTrace(e));
		    		}
		    	}
		    	
		    	logger.debug("ip : {} port : {} future shutdownGracefully() Status :: isDone : {} isSuccess : {} , isCancellable : {} , cause : {} " 
		    			, host
		    			, port
		    			, future.isDone()
		    			, future.isSuccess()
		    			, future.isCancellable() 
		    			, ((future.cause() == null ) ? "null" : LogHelper.getPrintStackTrace(future.cause() ) ) 
		    			);
		    	
		    }
		}
		catch(Exception e) {
			logger.error("Bootstrap reset error / Exception Log : {}" , LogHelper.getPrintStackTrace(e) );
		}

위의 코드를 이용하여

bootstrap의  shoutdownGracefully 를 이용하여 bootstrap의 상태를 파악하고 재접속 시도부분으로 넘어가도록 수정했다.

 

공식 API 문서에서 참고해서 클라이언트가 bootstrap을 사용하는 방법을 이용하여 접속을 시도하는것,

그리고 그 방법을 이용해서 재접속을 시도했을때 발생하는

메모리와 CPU 사용량 증가를 확인하고 수정한 코드를 작성할 예정이다. 

728x90

댓글