ConcurrentHashMap上的Netty ChannelGroup

时间:2014-12-25 23:41:06

标签: java concurrency netty

我正在开发基于netty的多人游戏服务器。 传输到客户端的大多数消息都是特定于单个客户端的 但有时我需要向所有客户广播相同的消息。

我不确定是否有充分理由在我自己的Map上使用ChannelGroup。 所以现在我有:

public class GameSession {
  /* a map of all the players part of this game session */
  private ConcurrentHashMap<String, PlayerHandler> players = new ConcurrentHashMap<String, PlayerHandler>();
  private final ChannelGroup playersChannels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

PlayerHandler在哪里:

public class PlayerHandler extends SimpleChannelInboundHandler<IncomingMessage>

并包含有状态成员变量。

当一个新玩家加入时(经过一些逻辑)后,他被添加到GameSession中:

public void addPlayer(PlayerHandler p) {

    if (p.getGameSessionID().equals(this.gameId)) {
        players.put(p.getPlayerID(), p); //add this player to our game session
        playersChannels.add(p.getChannelFromCtx()); //get channel and add to ChannelGroup
    }
}

假设玩家要求离开(或关闭连接)

,我想播放一条消息
public void notifyPlayerLeft(String exPlayer) {
    //Broadcast message with the id of the player that left
    for (Map.Entry<String, PlayerHandler> entry : players.entrySet()) {
        PlayerHandler player = entry.getValue();
        player.sendPlayerLeft(exPlayer);

    }
}

其中sendPlayerLeft()是一个简单的方法,它可以执行以下操作:

ctx.writeAndFlush(outgoingMsg)

如果我使用 ChannelGroup ,我可以这样做:

playersChannels.writeAndFlush(outgoingMsg, matcher)

但我不确定为什么这是一个更好的主意。 Netty表示它是异步发生的 但由于PlayerHandler没有自己的线程,因此不会迭代对象 就像我在NotifyPlayerLeft()中做的那样也会异步?请注意,整个场景将由一个频道/用户/线程触发。

我希望我的问题足够清楚。 谢谢!

3 个答案:

答案 0 :(得分:2)

如您所见here,Netty默认写入群组再次是一个简单的迭代。从这个意义上讲,您的方法在性能和并发性方面应该没有区别。主要区别在于它将所有期货收集到地图中,这种分组可以帮助您跟踪引发的任何问题。但是,为什么要使用你的代码已经实现了呢?

答案 1 :(得分:1)

使用信息更新它。因此,虽然ChannelGroup对于前面所述的简单迭代很有用,但您也可以从API文档中获益。

Netty.io 4.1 ChannelGroup API Documents

  

自动从集合中删除已关闭的频道,这样您就不必担心添加频道的生命周期。频道可以属于多个频道组。

您可以通过扩展ChannelGroup.class来创建新的DefaultChannelGroup.class,并添加一些方法以在频道注销期间添加其他行为,以通知某些代码未注册频道,然后通知其他球员,或做清理。

答案 2 :(得分:0)

请小心Netty的ConcurrentHashMap;它实际上是越野车;它不是线程安全的。您可以使用一个线程上的并发流同时放置另一个线程来验证此错误。它并非总是失败,因为它与非原子内部数组突变有关(快速并发的读/写操作应该因netty而失败,而不是jdk。)

相关问题