尽量采用无锁化Netty通信处理棋牌房间逻辑

一,棋牌类服务器的特点

1,棋牌类不分区不分服

一般来说,棋牌游戏都是不分区不分服的。所以棋牌类服务器要满足随着用户量的增加而扩展的需要,所以需要设计Gate网关来处理连接到哪个逻辑服务器。

2,房间模式

即在同一局游戏中就是在同一个房间中,同一个房间中的人可以接收到其他人的消息。

3,每个房间的操作必须是顺序性

这个特性类似与一般游戏的回合制,每个玩家的操作都是有顺序性的。

二,需要解决的技术点

1,数据共享

因为棋牌类游戏不分区不分服,我们在设计服务器的时候,是按世界服的思想去设计,即服务器是一个n多台物理机的集群。当用户登陆服务器,创建房间时,可能根据负载均衡算法,它可以在任何一台服务器上面。所以,不管用户登陆到哪一台服务器上面了,都可以获得自己的数据。我们可以使用redis来做数据共享。

2,如何进入房间

在同一局游戏中,我们要求所有人都在同一个房间中,我们可以规定在同一个房间中的用户,必须登陆到同一台物理服务器上面。在创建房间完成之后,其他人根据房间号查找房间的时候,可以根据房间号,获取这个房间所在的服务器ip和端口,判断一个当前用户登陆的服务器ip与房间所在的服务器ip是否相同,如果相同,就不做切换,如果不一样,客户端就使用ip和端口,连接到房间所在的服务器上面。

3,保证房间操作的顺序性

创建房间成功之后,接下来的操作都要保证它的顺序性,所以房间需要有一个它自己的消息个队列。我们可以把每个房间到达服务器的消息封装为一个任务,把这个任务放到消息队列中,然后有一个任务执行者去按顺序执行这些任务。

以上三个问题,我们着重讲的是第三个问题:我们目前做的是一台逻辑服务器,没有涉及网关。

对于Netty来说,从此处得到消息之后,可以直接进行解析处理,在这儿我做了一个 private EventExecutor messageExecutor;用一个单线程来处理大厅消息。

对于房间消息,采用三个线程来处理,根据房间号求余三个线程,让不同的房间消息,使用着相同的线程来处理,避免了锁的处理。

以下是单线程消息分发器,分发知乎

int nthread=3;

int roomid = Integer.parseInt(JsonUtil.GetData(request.GetMessage(), "roomid").toString());
           int thread = roomid % nthreads;

// 分三个线程执行
           private EventExecutor[] executors = new DefaultEventExecutor[nthreads];

executors[thread].execute(new Runnable() {

@Override
                  public void run() {
                              int id = request.GetMessageId();
                              try {
                                          handleMap.get(id).execute(request);    //消息处理器handleMap
                                    } catch (java.lang.NullPointerException ex) {
                                           System.out.println(ex.toString());
                                    }
                             }

});

还需要考虑另外一种情况业务情况是,“如果设置定时器,10分钟内房间无操作,则强制解散房间”。这个时候也涉及到多线程对房间操作处理:

这个时候有两种方式:

1.考虑线程安全

2.使用前面说的消息分发,封装为一个房间操作命令,利用房间线程池来顺序处理,即可实现无锁化。

最新文章

  1. 用IntelliJ IDEA创建Gradle项目简单入门
  2. XPath Axes(轴)
  3. Unity3D 事件
  4. tshark过滤并保存包特定字段
  5. TC SRM 593 DIV1 250
  6. c#操作文件夹得读写权限
  7. Script to compile invalid objects in DB
  8. 【题解】【DP】【Leetcode】Climbing Stairs
  9. Selector中的各种状态详解
  10. 深入理解MFC子类化
  11. 输出一个string的所有排列情况
  12. VB.net结束进程
  13. get 和 post请求的区别
  14. sql嵌套批量更新
  15. mac 连接linux服务器,用scp命令实现本地文件与服务器文件之间的互相传输
  16. PHP----------PHP自身的性能优化注意事项
  17. QT中事件处理器和事件过滤器实现实例
  18. 安装Joomla!3
  19. R语言 格式化数字
  20. 04: 事件驱动、五种I/O操作、I/O多路复用select和epoll

热门文章

  1. 动态网站技术CGI
  2. Android笔记——UI开发
  3. Cocos2d-x中点九图(Scale9Sprite)创建图片按钮
  4. Wpf修改控制的大小
  5. 无埋点数据收集和adb monkey测试屏蔽通知栏
  6. Visual studio之C# 新建线程与定时器的使用
  7. 03-hibernate注解-关系映射级别注解-一对一
  8. 使用Guava报错NoSuchMethodError的解决方法
  9. Solr 缓存配置
  10. python selenium --frame