ChannelId меняется? - PullRequest
       4

ChannelId меняется?

0 голосов
/ 21 мая 2018

Я думаю, что наблюдал изменение ChannelId для канала с течением времени.Это нормальное поведение?

Вот почему я думаю, что:

Я программирую игровой сервер, на котором соединения длятся долго.Я хочу сослаться на каналы, поэтому я обертываю их в объект 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 ()) вернет ноль.

Вот журналы из сеанса, где это происходит:

    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, который является самым новым, который я мог найти на сегодняшний день.

1 Ответ

0 голосов
/ 22 мая 2018

Оказывается, я ошибся, пытаясь удалить объект Player из HashMap во всех случаях.

Клиент мог подключиться, а затем бездействовать (в результате чего они не были зарегистрированы, поскольку регистрация происходит с пакетом входа в систему), и, наконец, отключиться.Вот что случилось.

Мой плохой.

В целом, ChannelId кажется безопасным в использовании, и, насколько я могу судить, со временем он не меняется.

...