Klaytn에서 WebSocket을 연결하여 스마트컨트랙트에서 발생하는 이벤트를 구독하려고 했다.
문제는 웹소켓 연결이 시간이 지나면 계속 끊겼다.
이 문제를 정의하고 해결하려고 한다.
1. 문제
1분간 별도의 request가 없으면 끊긴다.
클레이튼 데브포럼에서 클레이튼 팀에서 직접 단 댓글이다.
하지만 나는 1분간 별도의 request가 없어도 정상적으로 연결되다가 몇 시간 후에 갑자기 끊겨 버린다.
21년 6월에 작성한 글이라 오래되서 뭔가 바꼈나 하고 다시 찾아봤다.
그랬더니 위와 같이 최근에도 같은 답변이 있었다.
주기적으로 getblocknumber를 호출하는 방법보다 더 효율적인 방법을 찾고 싶었다.
그래서 WebSocketService의 connect가 끊겼을때를 감지해서 다시 connect를 하는 방법을 생각했다.
실제로 이 방법이 가능하게끔 WebSocketService의 connect 메소드의 파라미터에 onClose 부분이 있었다.
public void connect(Consumer<String> onMessage, Consumer<Throwable> onError, Runnable onClose)
throws ConnectException {
try {
connectToWebSocket();
setWebSocketListener(onMessage, onError, onClose);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
log.warn("Interrupted while connecting via WebSocket protocol");
}
}
그래서 onClose를 이용하여 WebSocket이 끊겼을 경우에만 다시 연결하도록 하려고 한다.
2. 해결
(1) 웹소켓 서비스 연결
@Bean
public WebSocketService webSocketService() {
WebSocketService webSocketService = new WebSocketService(WEBSOCKET_URI, false);
connectWebSocketService(webSocketService);
return webSocketService;
}
private void connectWebSocketService(WebSocketService webSocketService) {
Consumer<String> onMessage = message -> {
System.out.println(message);
};
Consumer<Throwable> onError = throwable -> {
log.error("WebSocket 오류 발생: ", throwable);
};
Runnable onClose = () -> {
log.warn("WebSocket 연결이 종료됨. 재연결 시도...");
connectWebSocketService(websocketService);
};
try {
webSocketService.connect(onMessage, onError, onClose);
} catch (Exception e) {
log.error("WebSocket 연결 중 오류 발생", e);
}
}
위와 같이 onClose 부분에 connect하는 함수를 다시 호출하여 connect를 다시 실행시키도록 짰다.
하지만 스레드가 없다는 에러로 다시 끊겼다.
WebSocketService가 끊기면서 스레드가 종료된다고 한다.
그래서 새로운 스레드를 추가하여 다시 실행시켜 줬다.
Runnable onClose = () -> {
log.warn("WebSocket 연결이 종료됨. 재연결 시도...");
// 기존 스레드는 close 되면서 종료됨. 별도의 스레드에서 재연결
new Thread(() -> connectWebSocketService(webSocketService)).start();
};
3. 추측
추가로 1분동안 request를 하지 않으면 끊기는 부분에 대해서 다시 짚고 넘어가려고 한다.
위 코드에서 봤듯이 onMessage부분에서 println을 찍도록 짰다.
아무 이벤트도 발생시키지 않아도 1분에 4개정도의 메시지를 출력했다.
이 부분이 klaytn의 노드와 계속해서 통신을 하기때문에 websocket이 계속 연결되어 있는것 같다는 추측이다.
'개발 > BlockChain' 카테고리의 다른 글
[BlockChain] gasPrice 상승 이슈 (0) | 2023.12.05 |
---|---|
[Blockchain] 언어별 web3 차이로 트랜잭션 해시값 차이 (0) | 2023.08.08 |
[Blockchain] web3j 에서 nonce값 동시성 해결 (0) | 2023.08.07 |
[BlockChain] EIP 55란? (0) | 2023.07.18 |
[BlockChain] 코인과 토큰의 차이 (0) | 2023.02.06 |