繁体   English   中英

ConcurrentHashMap上的Netty ChannelGroup

[英]Netty ChannelGroup over ConcurrentHashMap

我正在开发一款基于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()中那样迭代对象也会异步吗? 请注意,整个场景将由一个频道/用户/线程触发。

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

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

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

Netty.io 4.1 ChannelGroup API文档

关闭的频道会自动从集合中删除,因此您无需担心添加的频道的生命周期。 频道可以属于多个频道组。

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

小心Netty的ConcurrentHashMap; 它实际上是马车; 它不是线程安全的。 您可以在放置另一个线程时在一个线程上使用并发流来验证此错误。 它并不总是失败,因为它与非原子内部数组突变有关(快节奏并发r / w应该与netty但不是jdk失败。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM