I'm running a game where clients are connected to the server for a while. 
To keep track of connected clients, I map the ChannelId's to their 
respective Channel (wrapped in a Player class, get gain fields), using the 
Map interface.

Each time an event happens on the server, I print the ChannelId of the 
Channel who generated the event. This is a log from the server of a session 
in full. Here I'm logging many users in with the same credentials rapidly.

May 21, 2018 9:53:23 PM com.mchange.v2.log.MLog 
INFO: MLog clients using java 1.4+ standard logging.
May 21, 2018 9:53: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 9:53:27 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 -> 1hge0wf9v10p55m216fqpad|3b94d659, 
debugUnreturnedConnectionStackTraces -> false, description -> null, 
driverClass -> com.mysql.jdbc.Driver, extensions -> {}, 
factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, 
forceSynchronousCheckins -> false, forceUseNamedDriverClass -> false, 
identityToken -> 1hge0wf9v10p55m216fqpad|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 21:53:27 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 21:53:27 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 21:53:27 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.
[pool-1-thread-1] Looking up SQL data on player mads
[GameEngine] Registered and added worker for logging in mads (499ecda8) total 
players = 1
[pool-1-thread-1] Finished looking up SQL data on player mads, result was 
VERIFIED
[GameEngine] Logged in succesfully mads
[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] Registered and added worker for logging in mads (3513c8e5) total 
players = 2
[GameEngine] Logged in succesfully mads
[GameEngine] Registered and added worker for logging in mads (c16ea97f) 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-1] An existing connection was forcibly closed by the 
remote host
[nioEventLoopGroup-3-1]  Kicked for inactive channel: 499ecda8
[GameEngine] Unregistering player (499ecda8) total players = 2
[GameEngine] Logged in succesfully mads
[nioEventLoopGroup-3-2] An existing connection was forcibly closed by the 
remote host
[nioEventLoopGroup-3-2]  Kicked for inactive channel: 3513c8e5
Mon May 21 21:53:33 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 21:53:33 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 21:53:33 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 (84b9ef81) total 
players = 3
[GameEngine] Unregistering player (3513c8e5) total players = 2
[pool-1-thread-1] Looking up SQL data on player mads
[GameEngine] Registered and added worker for logging in mads (5d642638) total 
players = 3
[pool-1-thread-2] Looking up SQL data on player mads
[pool-1-thread-1] Finished looking up SQL data on player mads, result was 
VERIFIED
[pool-1-thread-2] 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: c16ea97f
[GameEngine] Unregistering player (c16ea97f) total players = 2
[GameEngine] Registered and added worker for logging in mads (cf9bc561) total 
players = 3
[pool-1-thread-2] Looking up SQL data on player mads
[GameEngine] Logged in succesfully mads
[GameEngine] Logged in succesfully mads
[pool-1-thread-2] Finished looking up SQL data on player mads, result was 
VERIFIED
[GameEngine] Logged in succesfully mads
[nioEventLoopGroup-3-5]  Kicked for inactive channel: 5d642638
[nioEventLoopGroup-3-5] An existing connection was forcibly closed by the 
remote host
[GameEngine] Unregistering player (5d642638) total players = 2
Mon May 21 21:53:35 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 21:53:35 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 21:53:35 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.
[pool-1-thread-2] Looking up SQL data on player mads
[GameEngine] Registered and added worker for logging in mads (7de2128e) total 
players = 3
[pool-1-thread-2] Finished looking up SQL data on player mads, result was 
VERIFIED
[nioEventLoopGroup-3-8] An existing connection was forcibly closed by the 
remote host
[nioEventLoopGroup-3-8]  Kicked for inactive channel: ef699a38
[GameEngine] Unregistering player (ef699a38) total players = 2
[GameEngine] P WAS NULL (ef699a38) total players = 3
Exception in thread "GameEngine" java.lang.NullPointerException
at 
com.hydrozoa.onlinerp_server.game.GameEngine.unregisterPlayer(GameEngine.java:88)
at 
com.hydrozoa.onlinerp_server.net.RPServerHandler$2.run(RPServerHandler.java:49)
at com.hydrozoa.onlinerp_server.game.GameEngine.run(GameEngine.java:127)
at java.base/java.lang.Thread.run(Unknown Source)
[nioEventLoopGroup-3-1] An existing connection was forcibly closed by the 
remote host
[nioEventLoopGroup-3-1]  Kicked for inactive channel: 56e2118d

You can see that at one point, a NullPointerException happens, because the 
ChannelId was not found in the HashMap. Here are the methods for 
registering and unregistering:

private HashMap<ChannelId, Player> players = new HashMap<ChannelId, 
Player>();
public void registerPlayer(Channel c, String name, String password) {
Player p = new Player(c, name, password);
players.put(c.id(), p);
try {
loginFutures.add(workerTasks.submit(new 
AuthenticateCredentialsTask(context.getDatabase().getConnection(), c.id(), 
name, password)));
} 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().asShortText()+") \t\t total 
players = "+players.size());
}
public void unregisterPlayer(ChannelId id) {
System.out.println("["+Thread.currentThread().getName()+"] Unregistering 
player ("+id.asShortText()+") \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.asShortText()+") \t\t total players = "+players.size());
}
if (p.getChannel().isActive()) {
p.getChannel().close();
}
}

Finally, here is my 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());
}
});
System.out.println("["+Thread.currentThread().getName()+"] "+" Kicked for 
inactive channel: "+ctx.channel().id());
}

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

It seems either the ChannelId can change a little bit over time, or their 
hashing function can?

I'm not sure how to solve this problem, with my current understanding of 
netty. Maybe there is a better way to reference clients than by mapping 
them to their ChannelIds?

-- 
You received this message because you are subscribed to the Google Groups 
"Netty discussions" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/netty/19239cce-d018-4300-8a4a-5620bbbc64be%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to