본문 바로가기

IT for developer/Netty

Netty 예제 분석 - LocalTime

LocalTime

기존 예제들과 다른 형태의 통신방식을 보여준다.

73          LocalTimeClientHandler handler =
74              channel.getPipeline().get(LocalTimeClientHandler.class);
75  
76          // Request and get the response.
77          List<String> response = handler.getLocalTimes(cities);


핸들러에 구현한 함수를 호출해서 리턴받는 형태이다. 그러면 getLocalTImes 라는 함수를 한번 살펴보자.

65          channel.write(builder.build());
서버에 도시 목록을 전달하면 해당 도시들의 시간을 응답해주는 듯하다. 여기에서 하려는 것은 시간을 응답해줄 때 까지 기다렸다가 나머지 처리를 한다는데 있다. 혼동하지 말아야할 것은 기존에 설명했던 future.awaitUninterruptibly함수이다.  예를 들어 아래코드는 서버가 응답할 때 까지 기다리는 것이 아니라 write를 완료할 때가지만 기다리는 것이므로 이 예제에서 목표하는 것과는 다르게 동작한다는것이다.

ChannelFuture future = channel.wirte (..);
future.awaitUninterruptibly() 


그러면 어떻게 클라이언트가 서버가 응답할 때 까지 기다렸는지 살펴보자.

53      private final BlockingQueue<LocalTimes> answer = new LinkedBlockingQueue<LocalTimes>();
71                  localTimes = answer.take();

BlockingQueue는 큐에 값이 들어올 때 까지는 블럭상태로 대기하도록 해준다.

큐에 값을 넣는 함수는 offer() 이고 값이 들어올 때 까지 대기하는 함수는 take() 이다.
다시말하면 take() 함수를 호출하면 offer()함수를 어디선가 호출하지 않는 이상 해당 쓰레드는 대기상태에 빠진다.

그러면 이 예제에서는 어디에서 offer() 함수를 호출하는지 확인해보자.

115
@Override

116     public void messageReceived(
117             ChannelHandlerContext ctx, final MessageEvent e) {
118         boolean offered = answer.offer((LocalTimes) e.getMessage());
119         assert offered;
120     }

서버로 부터 전달받은 응답 메시지를 Queue에 넣는다. 즉, 서버가 응답한 메시지를 받을 때 까지는 take()함수에 의해 대기하다가 깨어난다. take()함수를 호출하는 쓰레드는 getLocalTImes 함수를 호출한 main 쓰레드이고 messageReceived 함수는 별도의 쓰레드에 의해 호출되는 것이므로  main 쓰레드부분이 대기상태에 되더라도 messageReceived 함수를 호출하는 쓰레드는 계속 진행하므로 offer함수는 정상적으로 호출된다.

서버측은 다른 예제들과 별반 다른 것이 없으므로 패스.