Java 응용 프로그램에서 netty.io (4.0.4)를 사용하여 외부 하드웨어 드라이버와 통신하기 위해 TCP 클라이언트를 구현합니다. 이 하드웨어의 요구 사항 중 하나는 클라이언트가 30 초마다 KEEP_ALIVE (하트 비트) 메시지를 보내지 만 하드웨어가이 과열에 응답하지 않는다는 것입니다. 내 문제는 연결이 갑자기 끊어진 경우 (예 : 네트워크 케이블이 빠져 있음) 클라이언트가이를 인식하지 못하고 작업 시간 초과 예외가 발생하기 전에 KEEP_ALIVE 메시지를 훨씬 오래 (약 5-10 분) 보냅니다. 즉, 클라이언트 측에서는 아직 연결되어 있는지 여부를 알 수있는 방법이 없습니다. 이깨진 네트워크가 감지되기 전에 netty 클라이언트가 매우 오래 걸림
// bootstrap setup
bootstrap = new Bootstrap().group(group)
.channel(NioSocketChannel.class)
.option(ChannelOption.SO_KEEPALIVE, true)
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 3000)
.remoteAddress(ip, port)
.handler(tcpChannelInitializer);
// part of the pipeline responsible for keep alive messages
pipeline.addLast("idleStateHandler", new IdleStateHandler(0, 0, 30, TimeUnit.SECONDS));
pipeline.addLast("keepAliveHandler", keepAliveMessageHandler);
클라이언트가 살아 메시지를 계속 보내고 이후 기대
을하는 데 도움이, 그리고 그 메시지가 다른 쪽 끝에서 수신되지 않는 경우 아래
내 부트 스트랩 설치의 조각이다, 누락 확인을 표시해야 훨씬 이전에 연결 문제가 있습니까? 2피곤 명시 적으로 아래의 코드를 사용하여 전달 살아 메시지를 계속 보장하는 KeepAliveMessageHandler
public class KeepAliveMessageHandler extends ChannelDuplexHandler
{
private static final Logger LOGGER = getLogger(KeepAliveMessageHandler.class);
private static final String KEEP_ALIVE_MESSAGE = "";
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception
{
if (!(evt instanceof IdleStateEvent)) {
return;
}
IdleStateEvent e = (IdleStateEvent) evt;
Channel channel = ctx.channel();
if (e.state() == IdleState.ALL_IDLE) {
LOGGER.info("Sending KEEP_ALIVE_MESSAGE");
channel.writeAndFlush(KEEP_ALIVE_MESSAGE);
}
}
}
편집에서
는편집
코드
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception
{
if (!(evt instanceof IdleStateEvent)) {
return;
}
IdleStateEvent e = (IdleStateEvent) evt;
Channel channel = ctx.channel();
if (e.state() == IdleState.ALL_IDLE) {
LOGGER.info("Sending KEEP_ALIVE_MESSAGE");
channel.writeAndFlush(KEEP_ALIVE_MESSAGE).addListener(future -> {
if (!future.isSuccess()) {
LOGGER.error("KEEP_ALIVE message write error");
channel.close();
}
});
}
}
이것은 또한 작동하지 않습니다. : this answer에 따르면이 동작은 의미가 있지만 필자는 쓰기가 "진짜"성공인지 파악할 수있는 방법이 있기를 바라고 있습니다. 하드웨어를 가지고 있으면 듣기가 불가능합니다.
는 아마 여기에 대한 답을 살펴? https://stackoverflow.com/questions/21358800/tcp-keep-alive-to-determine-if-client-disconnected-in-netty –
그 링크를 주셔서 감사합니다. 질문하기 전에 저것을 보았습니다. 문제는 해결책은 다음과 같습니다. a. 네트워크 케이블이 연결되어 있지 않으므로 채널을 정상적으로 닫을 수 없습니다. b. ReadTimeoutHandler를 구현하는 것은 하드웨어가 그다지 말하지 않기 때문에 작동하지 않을 수 있습니다. 이렇게하면 너무 자주 트리거됩니다./(질문에서 말하는 것은 응용 프로그램 수준이 아닌 TCP 레이어입니다.) 이해가 되니? 아마 내가 원한 것은 TCP에 의해서조차 가능하지 않으며, 그것은 질문의 일부분이다. – codeCruncher
몇 분 후에 '연결 재설정'또는 '소프트웨어로 인해 연결이 중단됨'을 기대합니다. 청취 신호를 보낼 때 올바르게 송신 오류를 감지하고 있습니까? – EJP