用 PHP 实现 1v1 匹配机制,求思路 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
arsom
V2EX    PHP

用 PHP 实现 1v1 匹配机制,求思路

  •  
  •   arsom 2017-12-06 19:08:20 +08:00 5443 次点击
    这是一个创建于 2942 天前的主题,其中的信息可能已经有所发展或是发生改变。

    语言:php

    框架:workerman

    需求: 用户点击匹配,然后从匹配大厅里选取一名玩家与该用户对战

    请教一下各路大神“匹配大厅”该用什么思路来实现?

    18 条回复    2018-01-23 14:37:40 +08:00
    arsom
        1
    arsom  
    OP
       2017-12-06 19:11:11 +08:00
    google 无果,知乎上有两个问题跟我类似,但是下面没人回答
    ovear
        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
    rick09
        3
    rick09  
       2017-12-06 19:20:50 +08:00
    没得其它条件的话,从匹配的人中 rand 一个,然后把它从匹配从群中踢出去。
    arsom
        4
    arsom  
    OP
       2017-12-06 19:23:36 +08:00
    @ovear redis 可以嘛
    chairuosen
        5
    chairuosen  
       2017-12-06 19:24:42 +08:00
    没写过,纯想的。
    开始匹配与匹配到结果是异步的。
    一个队列,新来的放队尾。
    定时从队首拿一个人出来遍历队列找到与他相匹配的人抽走。
    如果玩家有 rank 值就不用遍历,排队的人可以维护一个以 rank 分段的小组,从小组里选就行。
    ovear
        6
    ovear  
       2017-12-06 19:29:05 +08:00
    @arsom 可以的
    gouchaoer
        7
    gouchaoer  
       2017-12-06 19:48:20 +08:00 via Android
    workerman 里面你用了集群了么? 2 个人是 2 条 tcp,找个地方存连接不难
    arsom
        8
    arsom  
    OP
       2017-12-06 21:05:23 +08:00
    @gouchaoer 才玩 workerman,打算写个小游戏。走的 websocket 协议,没有用集群
    arsom
        9
    arsom  
    OP
       2017-12-06 21:31:34 +08:00
    @ovear 用队列的话,假如我有 1000 个人在等待匹配,一个一个出队是不是太慢了
    ovear
        10
    ovear  
       2017-12-06 21:44:12 +08:00
    @arsom 这个队列不可能这么大的呀,这个队列一般只可能<2
    逻辑如下

    1)队列为空,加入自身,等待
    2)队列不为空,出队一个,匹配成功
    zhx1991
        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 的人

    单一队列肯定行不通
    guoer
        12
    guoer  
       2017-12-06 22:31:41 +08:00
    redis set 就行了
    arsom
        13
    arsom  
    OP
       2017-12-06 23:29:37 +08:00 via iPhone
    @ovear 假如有 50 个人同时点击匹配,而且这中间有可能会出现取消匹配或者掉线,也能这么做么
    dilu
        14
    dilu  
       2017-12-07 09:02:43 +08:00
    我的思路是这样的,使用 redis 的 list,因为它是双向链表实现的,读取两头特别快。

    当有人点击匹配的时候,根据 id 来判断,单数扔左边,双数扔右边,然后有个定时任务,只要 list 不为空就把两头的取出来匹配。

    具体能不能行楼主可以测试一下,只是个大概思路。
    realpg
        15
    realpg  
    PRO
       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 去检索 是否匹配成功

    然后这个简易逻辑可以外挂一个当前排队人数量级判断 量级较大就一次性匹配多组 循环几次 量级比较小就一次执行的较少
    arsom
        16
    arsom  
    OP
       2017-12-07 09:44:20 +08:00 via iPhone
    @dilu 好的,谢谢
    iningmeng
        17
    iningmeng  
       2018-01-04 17:53:35 +08:00
    把所有登录用户放进 redis,每次用户请求配对的时候,根据匹配规则去 redis 寻找对手,用户退出时从 redis 删除
    364739377
        18
    364739377  
       2018-01-23 14:37:40 +08:00
    @arsom 这个你做好了吗,,怎么做的???能告诉我吗??谢谢
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1327 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 17:00 PVG 01:00 LAX 09:00 JFK 12:00
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86