语言:php
框架:workerman
需求: 用户点击匹配,然后从匹配大厅里选取一名玩家与该用户对战
请教一下各路大神“匹配大厅”该用什么思路来实现?
1
arsom OP google 无果,知乎上有两个问题跟我类似,但是下面没人回答
|
2
ovear 2017-12-06 19:13:45 +08:00
最简单可以直接用 Queue
依赖外部的话,可以用 MySQL update battle set player2 = ? where player2 = '' order time desc limit 1 或者带排序的 NoSQL,实在不行就用 MQ |
3
inkbxy 2017-12-06 19:20:50 +08:00
没得其它条件的话,从匹配的人中 rand 一个,然后把它从匹配从群中踢出去。
|
5
chairuosen 2017-12-06 19:24:42 +08:00
没写过,纯想的。
开始匹配与匹配到结果是异步的。 一个队列,新来的放队尾。 定时从队首拿一个人出来遍历队列找到与他相匹配的人抽走。 如果玩家有 rank 值就不用遍历,排队的人可以维护一个以 rank 分段的小组,从小组里选就行。 |
7
gouchaoer 2017-12-06 19:48:20 +08:00 via Android
workerman 里面你用了集群了么? 2 个人是 2 条 tcp,找个地方存连接不难
|
10
ovear 2017-12-06 21:44:12 +08:00
|
11
zhx1991 2017-12-06 22:20:51 +08:00
这要考虑一个问题是, 如果按照分数匹配
假设要匹配的人是 5 分, 那么现在有 1 2 3 4 5 6 7 8 9 10 分 10 个人同时参与匹配 正常的匹配逻辑是 5 分的人可以匹配到 4-6 分的人, 而 4 分的那个人要匹配到 3-5 的人 单一队列肯定行不通 |
12
guoer 2017-12-06 22:31:41 +08:00
redis set 就行了
|
14
dilu 2017-12-07 09:02:43 +08:00
我的思路是这样的,使用 redis 的 list,因为它是双向链表实现的,读取两头特别快。
当有人点击匹配的时候,根据 id 来判断,单数扔左边,双数扔右边,然后有个定时任务,只要 list 不为空就把两头的取出来匹配。 具体能不能行楼主可以测试一下,只是个大概思路。 |
15
realpg 2017-12-07 09:04:48 +08:00 1
@arsom #13
N 年前写过一个基于 MYSQL 的简易匹配 点击匹配的 curgame 改成 0 取消的改成 1 insert into `games` (`time`) values ($time); 获取 insert_id (主键 game_id) update `user` set `curgame` = $game_id where curgame = 0 order by XXX limit 2 然后直接用 game_id 去检索 是否匹配成功 然后这个简易逻辑可以外挂一个当前排队人数量级判断 量级较大就一次性匹配多组 循环几次 量级比较小就一次执行的较少 |
17
iningmeng 2018-01-04 17:53:35 +08:00
把所有登录用户放进 redis,每次用户请求配对的时候,根据匹配规则去 redis 寻找对手,用户退出时从 redis 删除
|