【发布时间】:2018-11-25 09:56:50
【问题描述】:
我正在开发基于 netty 的多人游戏服务器。 传输到客户端的大多数消息都特定于单个客户端 但有时我需要向所有客户端广播相同的消息。
我不确定是否有充分的理由在我自己的地图上使用 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/User/Thread 触发。
我希望我的问题足够清楚。 谢谢!
【问题讨论】:
标签: java concurrency netty