perf: 优化连接稳定性
This commit is contained in:
@@ -74,7 +74,6 @@ public abstract class BallAPI {
|
||||
bootstrap.group(executors)
|
||||
.channel(NioSocketChannel.class)
|
||||
.option(ChannelOption.TCP_NODELAY, true)
|
||||
.option(ChannelOption.SO_KEEPALIVE, true)
|
||||
.handler(BallChannelInitializer.INSTANCE);
|
||||
|
||||
addListener(new BallListener() {
|
||||
@@ -248,7 +247,7 @@ public abstract class BallAPI {
|
||||
}
|
||||
}
|
||||
|
||||
protected void reconnect(int ttl) {
|
||||
public void reconnect(int ttl) {
|
||||
if (!enabled) {
|
||||
return;
|
||||
}
|
||||
|
@@ -7,18 +7,26 @@ import cn.hamster3.mc.plugin.ball.common.event.server.ServerOfflineEvent;
|
||||
import cn.hamster3.mc.plugin.ball.common.event.server.ServerOnlineEvent;
|
||||
import cn.hamster3.mc.plugin.ball.common.listener.BallListener;
|
||||
import cn.hamster3.mc.plugin.core.common.constant.CoreConstantObjects;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class BallChannelInboundHandler extends SimpleChannelInboundHandler<String> {
|
||||
public static final BallChannelInboundHandler INSTANCE = new BallChannelInboundHandler();
|
||||
import java.util.logging.Level;
|
||||
|
||||
private BallChannelInboundHandler() {
|
||||
@ChannelHandler.Sharable
|
||||
public class BallChannelHandler extends SimpleChannelInboundHandler<String> {
|
||||
public static final BallChannelHandler INSTANCE = new BallChannelHandler();
|
||||
|
||||
private BallChannelHandler() {
|
||||
super(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void channelRead0(ChannelHandlerContext context, String message) {
|
||||
if ("pong".equals(message)) {
|
||||
return;
|
||||
}
|
||||
BallMessageInfo info = CoreConstantObjects.GSON.fromJson(message, BallMessageInfo.class);
|
||||
for (BallListener listener : BallAPI.getInstance().getListeners()) {
|
||||
try {
|
||||
@@ -143,4 +151,36 @@ public class BallChannelInboundHandler extends SimpleChannelInboundHandler<Strin
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelActive(@NotNull ChannelHandlerContext context) {
|
||||
BallAPI.getInstance().getLogger().warning("与服务器 " + context.channel().remoteAddress() + " 的连接已可用.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelInactive(@NotNull ChannelHandlerContext context) {
|
||||
context.close();
|
||||
BallAPI.getInstance().getLogger().warning("与服务器 " + context.channel().remoteAddress() + " 的连接已断开.");
|
||||
for (BallListener listener : BallAPI.getInstance().getListeners()) {
|
||||
try {
|
||||
listener.onConnectInactive();
|
||||
} catch (Exception | Error e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
BallAPI.getInstance().reconnect(5);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext context, Throwable cause) {
|
||||
BallAPI.getInstance().getLogger().log(Level.WARNING, "与服务器 " + context.channel().remoteAddress() + " 通信时出现了一个错误: ", cause);
|
||||
for (BallListener listener : BallAPI.getInstance().getListeners()) {
|
||||
try {
|
||||
listener.onConnectException(cause);
|
||||
} catch (Exception | Error e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -1,17 +1,16 @@
|
||||
package cn.hamster3.mc.plugin.ball.common.connector;
|
||||
|
||||
import cn.hamster3.mc.plugin.ball.common.api.BallAPI;
|
||||
import cn.hamster3.mc.plugin.ball.common.listener.BallListener;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.channel.socket.nio.NioSocketChannel;
|
||||
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
|
||||
import io.netty.handler.codec.LengthFieldPrepender;
|
||||
import io.netty.handler.codec.string.StringDecoder;
|
||||
import io.netty.handler.codec.string.StringEncoder;
|
||||
import io.netty.handler.timeout.IdleStateHandler;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class BallChannelInitializer extends ChannelInitializer<NioSocketChannel> {
|
||||
public static final BallChannelInitializer INSTANCE = new BallChannelInitializer();
|
||||
@@ -22,34 +21,14 @@ public class BallChannelInitializer extends ChannelInitializer<NioSocketChannel>
|
||||
@Override
|
||||
protected void initChannel(@NotNull NioSocketChannel channel) {
|
||||
channel.pipeline()
|
||||
.addLast(new IdleStateHandler(0, 7, 0, TimeUnit.SECONDS))
|
||||
.addLast(BallKeepAliveHandler.INSTANCE)
|
||||
.addLast(new LengthFieldPrepender(8))
|
||||
.addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 8, 0, 8))
|
||||
.addLast(new StringDecoder(StandardCharsets.UTF_8))
|
||||
.addLast(new StringEncoder(StandardCharsets.UTF_8))
|
||||
.addLast(BallChannelInboundHandler.INSTANCE)
|
||||
;
|
||||
.addLast(BallChannelHandler.INSTANCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelInactive(@NotNull ChannelHandlerContext context) {
|
||||
for (BallListener listener : BallAPI.getInstance().getListeners()) {
|
||||
try {
|
||||
listener.onConnectInactive();
|
||||
} catch (Exception | Error e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext context, Throwable cause) {
|
||||
for (BallListener listener : BallAPI.getInstance().getListeners()) {
|
||||
try {
|
||||
listener.onConnectException(cause);
|
||||
} catch (Exception | Error e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,20 @@
|
||||
package cn.hamster3.mc.plugin.ball.common.connector;
|
||||
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.SimpleUserEventChannelHandler;
|
||||
import io.netty.handler.timeout.IdleStateEvent;
|
||||
|
||||
@ChannelHandler.Sharable
|
||||
public class BallKeepAliveHandler extends SimpleUserEventChannelHandler<IdleStateEvent> {
|
||||
public static final BallKeepAliveHandler INSTANCE = new BallKeepAliveHandler();
|
||||
|
||||
private BallKeepAliveHandler() {
|
||||
super(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void eventReceived(ChannelHandlerContext context, IdleStateEvent event) {
|
||||
context.channel().writeAndFlush("ping");
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user