首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Netty ChannelGroup over

Netty ChannelGroup over
EN

Stack Overflow用户
提问于 2014-12-25 23:41:05
回答 3查看 1.7K关注 0票数 2

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

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

代码语言:javascript
复制
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是:

代码语言:javascript
复制
public class PlayerHandler extends SimpleChannelInboundHandler<IncomingMessage>

并包含有状态成员变量。

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

代码语言:javascript
复制
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
    }
}

假设我想播放一条消息,因为玩家请求离开(或关闭连接)

代码语言:javascript
复制
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()是一个简单的方法,可以执行以下操作:

代码语言:javascript
复制
ctx.writeAndFlush(outgoingMsg)

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

代码语言:javascript
复制
playersChannels.writeAndFlush(outgoingMsg, matcher)

但我不知道为什么这是个好主意。Netty声明它是异步发生的,但是由于PlayerHandler没有自己的线程,那么像我在NotifyPlayerLeft()中所做的那样,迭代对象是否也是异步的呢?请注意,整个场景将由一个通道/用户/线程触发。

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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-12-25 23:50:22

正如您所看到的这里,Netty对一个组的默认写入同样是一个简单的迭代。从这个意义上说,您的方法在性能和并发性方面不应该存在差异。主要的区别是,它收集所有期货到一个地图,这个分组可能会帮助您跟踪任何问题提出。但是如果这已经实现了,为什么要使用您的代码呢?

票数 3
EN

Stack Overflow用户

发布于 2016-05-16 14:44:31

用信息更新它。因此,正如前面所述,虽然ChannelGroup对于简单的迭代非常有用,但是您也可以从API文档中获得这一好处。

Netty.io 4.1 ChannelGroup API文档

关闭的通道将自动从集合中移除,因此您不需要担心添加的通道的生命周期。一个通道可以属于多个ChannelGroup。

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

票数 1
EN

Stack Overflow用户

发布于 2018-11-25 01:56:50

只需小心使用Netty的ConcurrentHashMap;它实际上是错误的;它不是线程安全。您可以在一个线程上使用并发流验证此错误,而在另一个线程上进行验证。它并不总是失败,因为它与非原子内部数组突变有关(快速并发r/w应该失败于netty,而不是jdk)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27651590

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档