gpt4 book ai didi

java - ChannelId 会改变吗?

转载 作者:太空宇宙 更新时间:2023-11-04 10:26:43 25 4
gpt4 key购买 nike

我想我已经观察到 channel 的 ChannelId 随着时间的推移而变化。这是正常行为吗?

这就是我认为的原因:

我正在编写一个连接持续很长时间的游戏服务器。我想引用 Channels,因此我将它们包装在 Player 对象中,并使用 ChannelId.asLongText() 将它们映射为 HashMap 中的键。这是 HashMap:

private HashMap<String, Player> players = new HashMap<String, Player>();

public void registerPlayer(Channel c, String name, String password) {
Player p = new Player(c, name, password);
players.put(c.id().asLongText(), p);

try {
Future<CredentialCheckResult> future = workerTasks.submit(new AuthenticateCredentialsTask(context.getDatabase().getConnection(), c.id().asLongText(), name, password));
loginFutures.add(future);
} catch (SQLException e) {
System.out.println("["+Thread.currentThread().getName()+"] "+e.getMessage());
return;
}
System.out.println("["+Thread.currentThread().getName()+"] Registered and added worker for logging in "+name+" ("+c.id().asLongText()+") \t\t total players = "+players.size());
}

public void unregisterPlayer(String id) {
System.out.println("["+Thread.currentThread().getName()+"] Unregistering player ("+id+") \t\t total players = "+(players.size()-1));
Player p = players.get(id);
players.remove(id);

if (p == null) {
System.out.println("["+Thread.currentThread().getName()+"] P WAS NULL ("+id+") \t\t total players = "+players.size());
}

if (p.getChannel().isActive()) {
p.getChannel().close();
}
}

注册和取消注册方法是从不同的线程(称为 GameEngine)运行的。 HashMap 仅由该线程触及。

这是我的 ServerHandler 的样子,请记住这一点:

@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
GameEngine game = context.getGameService();
Packet p = (Packet) msg;

if (p instanceof NewConnectionPacket) {
NewConnectionPacket packet = (NewConnectionPacket) msg;
game.queueLogic(new Runnable() {
@Override
public void run() {
game.registerPlayer(ctx.channel(), packet.getUsername(), packet.getPassword());
}
});
}
}

@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
context.getGameService().queueLogic(new Runnable() {
@Override
public void run() {
context.getGameService().unregisterPlayer(ctx.channel().id().asLongText());
}
});
System.out.println("["+Thread.currentThread().getName()+"] "+" Kicked for inactive channel: "+ctx.channel().id().asLongText());
}

@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
System.err.println("["+Thread.currentThread().getName()+"] "+cause.getMessage());
ctx.close();
}

GameEngine.queueLogic(Runnable) 是线程安全的,仅对 GameEngine 线程的工作进行排队。

当我运行服务器并登录(对所有用户使用相同的凭据)一些用户,并快速断开客户端的连接时,服务器似乎无法正确从 HashMap 中注销播放器,因为players.get(ChannelId.asLongText()) 将返回 null。

以下是发生这种情况的 session 的日志:

    May 21, 2018 10:33:23 PM com.mchange.v2.log.MLog 
INFO: MLog clients using java 1.4+ standard logging.
May 21, 2018 10:33:23 PM com.mchange.v2.c3p0.C3P0Registry
INFO: Initializing c3p0-0.9.5.2 [built 08-December-2015 22:06:04 -0800; debug? true; trace: 10]
[main] GameEngine starting up...
May 21, 2018 10:33:44 PM com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource
INFO: Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, contextClassLoaderSource -> caller, dataSourceName -> 1hge0wf9v10qklm1j8rb36|3b94d659, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> com.mysql.jdbc.Driver, extensions -> {}, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, forceSynchronousCheckins -> false, forceUseNamedDriverClass -> false, identityToken -> 1hge0wf9v10qklm1j8rb36|3b94d659, idleConnectionTestPeriod -> 0, initialPoolSize -> 3, jdbcUrl -> jdbc:mysql://localhost:3306/onlinerp, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 0, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 15, maxStatements -> 0, maxStatementsPerConnection -> 0, minPoolSize -> 3, numHelperThreads -> 3, preferredTestQuery -> null, privilegeSpawnedThreads -> false, properties -> {password=******, user=******}, propertyCycle -> 0, statementCacheNumDeferredCloseThreads -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, userOverrides -> {}, usesTraditionalReflectiveProxies -> false ]
Mon May 21 22:33:44 CEST 2018 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
Mon May 21 22:33:44 CEST 2018 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
Mon May 21 22:33:44 CEST 2018 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
[GameEngine] Registered and added worker for logging in mads (cc2f71fffe2d38f4-0000287c-00000001-4b49379c0cc5629d-2b8fd125) total players = 1
[pool-1-thread-1] Looking up SQL data on player mads
[pool-1-thread-1] Finished looking up SQL data on player mads, result was VERIFIED
[GameEngine] Logged in succesfully mads
[GameEngine] Registered and added worker for logging in mads (cc2f71fffe2d38f4-0000287c-00000002-777e5a8cccc572e5-65acb968) total players = 2
[pool-1-thread-1] Looking up SQL data on player mads
[pool-1-thread-1] Finished looking up SQL data on player mads, result was VERIFIED
[GameEngine] Logged in succesfully mads
[GameEngine] Registered and added worker for logging in mads (cc2f71fffe2d38f4-0000287c-00000003-22a191d14cc5787b-f58eab6f) total players = 3
[pool-1-thread-1] Looking up SQL data on player mads
[pool-1-thread-1] Finished looking up SQL data on player mads, result was VERIFIED
[nioEventLoopGroup-3-3] An existing connection was forcibly closed by the remote host
[nioEventLoopGroup-3-3] Kicked for inactive channel: cc2f71fffe2d38f4-0000287c-00000003-22a191d14cc5787b-f58eab6f
[GameEngine] Unregistering player (cc2f71fffe2d38f4-0000287c-00000003-22a191d14cc5787b-f58eab6f) total players = 2
Mon May 21 22:33:51 CEST 2018 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
Mon May 21 22:33:51 CEST 2018 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
Mon May 21 22:33:51 CEST 2018 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
[GameEngine] Registered and added worker for logging in mads (cc2f71fffe2d38f4-0000287c-00000004-edfb71804cc58079-6c340605) total players = 3
[pool-1-thread-1] Looking up SQL data on player mads
[pool-1-thread-1] Finished looking up SQL data on player mads, result was VERIFIED
[nioEventLoopGroup-3-5] An existing connection was forcibly closed by the remote host
[nioEventLoopGroup-3-5] Kicked for inactive channel: cc2f71fffe2d38f4-0000287c-00000005-50468ea44cc5825e-52f26a37
[GameEngine] Unregistering player (cc2f71fffe2d38f4-0000287c-00000005-50468ea44cc5825e-52f26a37) total players = 2
[GameEngine] P WAS NULL (cc2f71fffe2d38f4-0000287c-00000005-50468ea44cc5825e-52f26a37) total players = 3
Exception in thread "GameEngine" java.lang.NullPointerException
at com.hydrozoa.onlinerp_server.game.GameEngine.unregisterPlayer(GameEngine.java:89)
at com.hydrozoa.onlinerp_server.net.RPServerHandler$2.run(RPServerHandler.java:49)
at com.hydrozoa.onlinerp_server.game.GameEngine.run(GameEngine.java:128)
at java.base/java.lang.Thread.run(Unknown Source)
[nioEventLoopGroup-3-4] An existing connection was forcibly closed by the remote host
[nioEventLoopGroup-3-4] Kicked for inactive channel: cc2f71fffe2d38f4-0000287c-00000004-edfb71804cc58079-6c340605
[nioEventLoopGroup-3-6] An existing connection was forcibly closed by the remote host
[nioEventLoopGroup-3-6] Kicked for inactive channel: cc2f71fffe2d38f4-0000287c-00000006-c3bd154facc587a0-3ef4f4b5
[nioEventLoopGroup-3-1] An existing connection was forcibly closed by the remote host
[nioEventLoopGroup-3-1] Kicked for inactive channel: cc2f71fffe2d38f4-0000287c-00000009-066e3818acc592cb-5618df97
[nioEventLoopGroup-3-8] An existing connection was forcibly closed by the remote host
[nioEventLoopGroup-3-8] Kicked for inactive channel: cc2f71fffe2d38f4-0000287c-00000008-65235126acc58ed4-10dc8b8f
[nioEventLoopGroup-3-2] An existing connection was forcibly closed by the remote host
[nioEventLoopGroup-3-2] Kicked for inactive channel: cc2f71fffe2d38f4-0000287c-0000000a-6034ea9b2cc59711-5b48e9f0
[nioEventLoopGroup-3-7] An existing connection was forcibly closed by the remote host
[nioEventLoopGroup-3-7] Kicked for inactive channel: cc2f71fffe2d38f4-0000287c-00000007-693ab465acc58a8a-8251ba2a

我也尝试过使用 ChannelId 对象作为键。我觉得我已经无计可施了。

我使用 NioServerSocketChannel.class 作为服务器,使用 NioSocketChannel.class 作为客户端。

如何以不随时间变化的方式引用频​​道?

顺便说一句,我正在使用 Netty 4.1.25,这是我今天能找到的最新版本。

最佳答案

事实证明,我在所有情况下尝试从 HashMap 中删除 Player 对象都犯了一个错误。

客户端有可能连接,然后空闲(导致它们无法注册,因为注册是通过登录数据包进行的),最后断开连接。这就是所发生的事情。

我的错。

总而言之,ChannelId 使用起来似乎很安全,而且据我所知,它不会随时间而改变。

关于java - ChannelId 会改变吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50456549/

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