gpt4 book ai didi

java - Netty channel 随机关闭

转载 作者:太空宇宙 更新时间:2023-11-04 15:19:55 28 4
gpt4 key购买 nike

我的问题是,当多个 channel 连接到我的游戏时,随机会出现断开连接,导致所有 channel 被关闭。调用了channelDisconnected方法,并且我已经完成了这次事件的堆栈跟踪打印输出,一切看起来都很正常。我的代码如下;有什么问题吗?

public final class ServerChannelHandler extends SimpleChannelHandler {

private static ChannelGroup channels;
private static ServerBootstrap bootstrap;

public static final void init() {
new ServerChannelHandler();
}

/**
* Gets the amount of channels that are currently connected to us
* @return A {@code Integer} {@code Object}
*/
public static int getConnectedChannelsSize() {
return channels == null ? 0 : channels.size();
}

/**
* Creates a new private constructor of this class
*/
private ServerChannelHandler() {
channels = new DefaultChannelGroup();
bootstrap = new ServerBootstrap(new NioServerSocketChannelFactory(CoresManager.serverBossChannelExecutor, CoresManager.serverWorkerChannelExecutor, CoresManager.serverWorkersCount));
bootstrap.getPipeline().addLast("handler", this);
bootstrap.setOption("reuseAddress", true); // reuses adress for bind
bootstrap.setOption("child.tcpNoDelay", true);
bootstrap.setOption("child.TcpAckFrequency", true);
bootstrap.setOption("child.keepAlive", true);
bootstrap.bind(new InetSocketAddress(Constants.PORT_ID));
}

/**
* What happens when a new channel is open and connects to us
*/
@Override
public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e) {
channels.add(e.getChannel());
}

/**
* What happens when an open channel closes the connection with us
*/
@Override
public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) {
channels.remove(e.getChannel());
}

@Override
public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) {
ctx.setAttachment(new Session(e.getChannel()));
}

@Override
public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) {
Object sessionObject = ctx.getAttachment();
if (sessionObject != null && sessionObject instanceof Session) {
Session session = (Session) sessionObject;
if (session.getDecoder() == null)
return;
if (session.getDecoder() instanceof WorldPacketsDecoder) {
session.getWorldPackets().getPlayer().finish();
}
}
}

@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
if (!(e.getMessage() instanceof ChannelBuffer))
return;
Object sessionObject = ctx.getAttachment();
if (sessionObject != null && sessionObject instanceof Session) {
Session session = (Session) sessionObject;
if (session.getDecoder() == null)
return;
ChannelBuffer buf = (ChannelBuffer) e.getMessage();
buf.markReaderIndex();
int avail = buf.readableBytes();
if (avail < 1 || avail > Constants.RECEIVE_DATA_LIMIT) {
return;
}
byte[] buffer = new byte[avail];
buf.readBytes(buffer);
try {
session.getDecoder().decode(new InputStream(buffer));
} catch (Throwable er) {
er.printStackTrace();
}
}
}

@Override
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent ee) throws Exception {
ee.getCause().printStackTrace();
}

/**
* On server shutdown, all channels are closed and the external resources
* are released from the {{@link #bootstrap}
*/
public static final void shutdown() {
channels.close().awaitUninterruptibly();
bootstrap.releaseExternalResources();
}

}

堆栈跟踪:

java.lang.Exception: Stack trace
at java.lang.Thread.dumpStack(Thread.java:1364)
at com.sallesy.game.player.Player.realFinish(Player.java:854)
at com.sallesy.game.player.Player.finish(Player.java:848)
at com.sallesy.game.player.Player.finish(Player.java:815)
at com.sallesy.networking.ServerChannelHandler.channelDisconnected(ServerChannelHandler.java:71)
at org.jboss.netty.channel.SimpleChannelHandler.handleUpstream(SimpleChannelHandler.java:120)
at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:558)
at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:553)
at org.jboss.netty.channel.Channels.fireChannelDisconnected(Channels.java:399)
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.close(AbstractNioWorker.java:721)
at org.jboss.netty.channel.socket.nio.NioServerSocketPipelineSink.handleAcceptedSocket(NioServerSocketPipelineSink.java:111)
at org.jboss.netty.channel.socket.nio.NioServerSocketPipelineSink.eventSunk(NioServerSocketPipelineSink.java:66)
at org.jboss.netty.channel.DefaultChannelPipeline$DefaultChannelHandlerContext.sendDownstream(DefaultChannelPipeline.java:774)
at org.jboss.netty.channel.SimpleChannelHandler.closeRequested(SimpleChannelHandler.java:338)
at org.jboss.netty.channel.SimpleChannelHandler.handleDownstream(SimpleChannelHandler.java:260)
at org.jboss.netty.channel.DefaultChannelPipeline.sendDownstream(DefaultChannelPipeline.java:585)
at org.jboss.netty.channel.DefaultChannelPipeline.sendDownstream(DefaultChannelPipeline.java:576)
at org.jboss.netty.channel.Channels.close(Channels.java:820)
at org.jboss.netty.channel.AbstractChannel.close(AbstractChannel.java:197)
at org.jboss.netty.channel.ChannelFutureListener$1.operationComplete(ChannelFutureListener.java:41)
at org.jboss.netty.channel.DefaultChannelFuture.notifyListener(DefaultChannelFuture.java:428)
at org.jboss.netty.channel.DefaultChannelFuture.addListener(DefaultChannelFuture.java:145)
at com.sallesy.networking.encoders.WorldPacketsEncoder.sendLogout(WorldPacketsEncoder.java:1179)
at com.sallesy.game.player.Player.logout(Player.java:801)
at com.sallesy.networking.decoders.handlers.ButtonHandler.handleButtons(ButtonHandler.java:227)
at com.sallesy.networking.decoders.WorldPacketsDecoder.processPackets(WorldPacketsDecoder.java:1122)
at com.sallesy.networking.decoders.WorldPacketsDecoder.decode(WorldPacketsDecoder.java:297)
at com.sallesy.networking.ServerChannelHandler.messageReceived(ServerChannelHandler.java:100)
at org.jboss.netty.channel.SimpleChannelHandler.handleUpstream(SimpleChannelHandler.java:88)
at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:558)
at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:553)
at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:268)
at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:255)
at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:84)
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.processSelectedKeys(AbstractNioWorker.java:471)
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.java:332)
at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:35)
at org.jboss.netty.util.ThreadRenamingRunnable.run(ThreadRenamingRunnable.java:102)
at org.jboss.netty.util.internal.DeadLockProofWorker$1.run(DeadLockProofWorker.java:42)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)

最佳答案

确实有点猜测,但可能是保活超时。您可以尝试使用 IdleStateHandler 来保持连接处于 Activity 状态。

关于java - Netty channel 随机关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20505883/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com