Does Channeld change over time? Problem with hashing?

19 views
Skip to first unread message

Mads Horndrup

unread,
May 22, 2018, 2:58:21 PM5/22/18
to Netty discussions
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?

Norman Maurer

unread,
May 22, 2018, 2:59:17 PM5/22/18
to ne...@googlegroups.com
No it does not change. There must be a bug in your usage as it is computed on Channel creation only.

Bye
Norman


--
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 netty+un...@googlegroups.com.
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 all
Reply to author
Forward
0 new messages