微信面对面建群机制浅析



  • 相信大家都使用过微信或者QQ上的面对面建群吧。这个建群方式十分简单,快捷,能够很快的邀请面前、附近的同学同事加入进来。那么这个简单方便的应用的实现逻辑是什么呢?下面由小编给大家分析一把吧。

    面对面建群

    原理解析

    1 用户位置

    一般大家使用的时候是直接进入建群页面的,但是小编尝试着关闭了微信的定位许可之后,再次进入面对面建群时,就会弹出一个提示框,要求我们提供访问当前位置的请求。
    0_1572324426415_访问权限.png
    如果你不允许的话,就无法使用这个面对面建群的功能了。那么我们可以这么猜测:微信面对面建群是需要用户当前位置信息的。

    2 建群验证码

    在我们要建群的时候,群主需要填写 4 位数来建立一个新群。对面的成员需要填写同样的 4 位数字来获取到这个新创建的群。我们都知道这些创建的过程是需要通过 HTTP 连接请求的,而不是通过 BlueTooth。

    面对面建群

    3. 服务器处理

    用户输入了 4 位数字之后,为什么其他人输入相同的数字就可以进入同一个群呢?有没有想过如果输入的数字一样的时候,可能并没有得到其他人建立的群呢?服务器不光光需要处理数字组合匹配的问题,也需要处理数字冲突的问题。这里是整个机制的核心,大家请耐心理解。

    据我理解,服务器得到用户的请求至少需要两个东西:4 位数字验证码、用户的位置信息。有这两个东西就足够了。接下来我将使用一段伪代码来阐述一下流程:

    groupTable // 一张建群的表
    while (真) {
        userData = 得到用户数据 //有 code 验证码字段和 position 位置字段
        if (userData.code 在建群的 groupTable 表内) {
            if (userData.position 在群主所在的范围内) {
                  group = 获得该群的信息
                  返回 加入 group 群 的信息
            } else {
                  在 groupTable 表中添加该群和时间期限
                  返回 新建群 信息
            }
        } else {
            在 groupTable 表中添加该群和时间期限
            返回 新建群 信息
        }
    }
    

    通过上述的逻辑,我们大概已经知道面对面建群的基本机制了。但是里面还有很多问题需要去解决,接下来小编带你一个一个地去攻破这些技术难点,我们出发吧。

    3.1 groupTable 数据结构

    数据结构是我们程序的核心。我们都知道 程序 = 数据结构 + 算法,有好的数据结构能够编写出更加高效的代码。但是能够想到好的数据结构并不是十分容易,小编在这个提出的方案还都是自己想出来的,网上都还没有现成的代码。那么我先提出以下我所认为的“好”的数据吧。

    typedef struct Group {
      POSITION position;                      // 所在位置
      USER *founder;                          // 建群者
      vector<USER*> members;                  // 成员数组
    } Group;
    
    typedef struct GroupTableItem
    {
      int code[4];                            // 验证码
      Group *group;                           // 指向新建群 
      Time expire;                            // 过期时间
    } GroupTableItem;
    
    typedef struct GroupTable
    {
      queue<GroupTableItem*> bucket[10000];     // 桶表    
      int group_number;                         // 当前新群的数量
      queue<GroupTableItem*> expire_queue;      // 过期时间队列
    } GroupTable;
    

    这个数据结构事实上非常简单,就是一个把 code 当作数组索引,数组元素中存放的是群节点构成的链表,看上去就是 hash 的链式一样,而 hash 函数就是 code 本身。有了这个数据结构,配合以下的图,我们将能够更加清楚地理解其中的运行流程:

    0_1572326597140_面对面建群.JPG

    如图所示,区域 P、Q 都传了相同的验证码 C,但是每两个人所在的位置是不一样的。当 Founder 发送了验证码 C 后,服务器会去 GroupTable 中查找是否有群。这时没有,那么就返回建群信息,在数据库中存下该群的信息。如果区域 Q 发出了相同的验证码 C,服务器获得了验证码后在数据库中查找。这时会查找到一个群 P 的数据,但是由于区域不同,而且没有更多的群了,所以返回建立新群Q的信息,并且在这个 P 后面添加 新群 Q。

    接着系统会不断的检测是否某个群到了到期时间,如果过期了,就会在 GroupTable 中销毁该群的信息,但是这个群依然存在在用户手中,表示创建完成。这时我们可以维护一个队列,新创建的群在队尾添加,前创建的群在开头。系统每回轮询队头的群,如果到了到期时间可以第一时间清除掉,再轮询接下来的新群。


 

Copyright © 2018 bbs.dian.org.cn All rights reserved.

与 Dian 的连接断开,我们正在尝试重连,请耐心等待