Skip to content

Commit

Permalink
add heatbeat for ws channel
Browse files Browse the repository at this point in the history
  • Loading branch information
iinti_cn committed Feb 1, 2024
1 parent b1f1102 commit e11a77f
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 3 deletions.
10 changes: 7 additions & 3 deletions src/main/java/cn/iinti/sekiro3/open/core/ServiceHttp.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@
import cn.iinti.sekiro3.business.netty.handler.codec.http.*;
import cn.iinti.sekiro3.business.netty.handler.codec.http.websocketx.WebSocketServerHandshaker;
import cn.iinti.sekiro3.business.netty.handler.codec.http.websocketx.WebSocketServerHandshakerFactory;
import cn.iinti.sekiro3.open.framework.trace.Recorder;
import cn.iinti.sekiro3.open.handlers.SekiroMsgEncoders;
import cn.iinti.sekiro3.open.core.client.InvokeRecord;
import cn.iinti.sekiro3.open.core.client.NettyClient;
import cn.iinti.sekiro3.open.core.client.NettySekiroGroup;
import cn.iinti.sekiro3.open.framework.trace.Recorder;
import cn.iinti.sekiro3.open.handlers.SekiroMsgEncoders;
import cn.iinti.sekiro3.open.handlers.WsHeartbeatHandler;
import cn.iinti.sekiro3.open.utils.ContentType;
import cn.iinti.sekiro3.open.utils.DefaultHtmlHttpResponse;
import cn.iinti.sekiro3.open.utils.NettyUtils;
Expand Down Expand Up @@ -101,7 +102,10 @@ private void doWsClientRegister(FullHttpRequest req, WebSocketServerHandshaker h
}
ChannelPipeline pipeline = ctx.pipeline();
NettyClient nettyClient = NettyClient.newWsNettyClient(ctx.channel(), group, clientId);
pipeline.addLast(new ServiceWsClient(nettyClient, handshaker));
pipeline.addLast(
new WsHeartbeatHandler(recorder),
new ServiceWsClient(nettyClient, handshaker)
);
pipeline.remove(this);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package cn.iinti.sekiro3.open.handlers;

import cn.iinti.sekiro3.business.api.util.Constants;
import cn.iinti.sekiro3.business.netty.channel.ChannelHandlerContext;
import cn.iinti.sekiro3.business.netty.handler.codec.http.websocketx.PingWebSocketFrame;
import cn.iinti.sekiro3.business.netty.handler.timeout.IdleStateEvent;
import cn.iinti.sekiro3.business.netty.handler.timeout.IdleStateHandler;
import cn.iinti.sekiro3.open.framework.trace.Recorder;

public class WsHeartbeatHandler extends IdleStateHandler {
private final Recorder recorder;

public WsHeartbeatHandler(Recorder recorder) {
super(Constants.SERVER_READ_IDLE, Constants.SERVER_WRITE_IDLE, Constants.SERVER_READ_WRITE);
this.recorder = recorder;
}

@Override
protected void channelIdle(ChannelHandlerContext ctx, IdleStateEvent event) throws Exception {
switch (event.state()) {
case READER_IDLE:
// 客户端需要在 SERVER_READ_IDLE - SERVER_READ_WRITE (默认 15s) 内回复
// 没有回复则会触发该事件,关闭客户端连接
recorder.recordEvent("Client READER_IDLE timeout, close channel");
ctx.channel().close();
break;
case WRITER_IDLE:
recorder.recordEvent("Server WRITE_IDLE timeout,send heartbeat to Client");
ctx.channel().writeAndFlush(new PingWebSocketFrame());
case ALL_IDLE:
// 服务端读写空闲超时发送一个心跳包给客户端
recorder.recordEvent("Server ALL_IDLE timeout, send heartbeat to Client");
ctx.channel().writeAndFlush(new PingWebSocketFrame());
break;
default:
// never call here
recorder.recordEvent("未知事件");
super.channelIdle(ctx, event);
}
}
}

0 comments on commit e11a77f

Please sign in to comment.