我正在开发一个基于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() 中所做的那样也将是异步的?请注意,整个场景将由一个 channel /用户/线程触发。
我希望我的问题足够清楚。 谢谢!
最佳答案
如您所见here ,Netty 默认写入组也是一个简单的迭代。从这个意义上说,您的方法在性能和并发性方面不应该有差异。主要区别在于它将所有 future 收集到一个 Map 中,这种分组可以帮助您跟踪提出的任何问题。但是,如果已经实现了,为什么还要使用您的代码呢?
关于java - ConcurrentHashMap 上的 Netty ChannelGroup,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27651590/