안녕하세요.
netty 사용한지 얼마 안된 뉴비인데요.
NTRIP이라는 위치 관련 위성의 정보를 받는 Client 기능의 Spring boot Application과
그 정보를 저장 가공하고 주기적으로 접속한 클라이언트들에게 전송하는 Caster를 동시에 만들고 있습니다.
Caster가 Spring boot에서 netty를 사용하여 클라이언트 접속을 받도록 구현하였는데요.
MessageToMessageDecoder를 상속받은 MessageHandler의 decode에서 로그인한 client에 대해 아래와 같이
주기적으로 데이터를 보내도록 하고 있습니다.
while(ctx.channel().isActive()){
// 최신 데이터를 가져오기
RtcmMessage rtcmMessage = new RtcmMessage(clientInfo, dBManager);
if(rtcmMessage.getSize() > 0){
ctx.writeAndFlush(rtcmMessage);
}else{
// 이런 경우 encode가 호출되지 않으므로 여기서 content release
rtcmMessage.getContent().release();
}
try {
Thread.sleep(fetchInterval);
} catch (InterruptedException ie) {
// Restore interrupted state...
Thread.currentThread().interrupt();
}
}
문제는 Client가 다른 해외 Ntrip Caster 서버에 붙었을 때는 연결이 유지되면서 주기적(주로 1초 간격)으로 데이터를 잘 받는데
제가 만든 Ntrip Caster에서는 데이터를 한번 받고는 연결이 끊어집니다.
이렇게 보면 제가 만든 Caster 쪽에서 연결을 끊는게 아닌가 생각되는데
로그를 찍어보면 그렇지가 않는것 같습니다.
위의 MessageHandler의 channelInactive에서 로그를 찍어보면 한참(30초 정도)후에 로그가 찍히거든요.
Client 쪽에서는 HttpURLConnection을 사용하여 connention을 맺고
아래와 같이 connention으로 부터 InputStream을 얻어
try (InputStream is = connection.getInputStream()) {
for (int r = fillUp(is); r >= 0; r = fillUp(is)) {
//버퍼에 받은 데이터 처리
}
} catch (Exception exception) {
log.error(mountPoint + " Exception : ", exception);
}
아래와 같은 fillup이라는 메소드에서 InputStream으로 부터 데이터를 읽어서
버퍼에 채워넣고 읽은 데이터 크기가 0이상이면 계속 for루프를 돌면서 버퍼의 데이터를 처리하도록 되어있습니다.
private int fillUp(final InputStream is) throws IOException {
final int max = bufferMaxWrite();
if (max == 0) {
throw new OrekitInternalError(null);
}
byte[] bytesRead = new byte[max];
int r = is.read(bytesRead);
if (r >= 0) {
System.arraycopy(bytesRead, 0, buffer, writeIndex, r);
writeIndex = (writeIndex + r) % BUFFER_SIZE;
}
return r;
}
그런데 해외 Ntrip Caster 서버에 연결을 했을때는 로그를 찍어보니 fillup의
int r = is.read(bytesRead);
에서 데이터가 올때까지 기다려서 r이 항상 0보다 큰 것을 확인하였습니다.
제가 만든 Ntrip Caster에 연결을 했을때는 로그를 찍어보니 fillup의
int r = is.read(bytesRead);
에서 첫번째는 데이터를 받지만 그 다음에는 바로 r이 -1이 되버리면서 for 루프를 빠져나갑니다.
왜 그런걸까요 ㅠㅠ
keep-alive 관련이라는 얘기를 들어서 클라이언트 header의
connetion : close로 되어 있는것을 keep-alive로 바꿔도 보고
이것 저것 해보았지만 마찬가지더라구요.
둘다 윈도우 vscode에서 로컬로 돌리고 있는데
그럼 방화벽이나 네트워크도 문제 없는 것 아닌가요?
제가 뭔가 놓치고 있는게 있을까요?
조언 부탁드리겠습니다.
감사합니다.