客服分配算法(加入文件读写保护,更新2019/9/30)

本文介绍了一种客服系统中用于动态分配在线客服人员的算法。该算法通过维护客服人员和在线用户列表,根据预设的阈值动态调整客服人员的工作负荷,确保服务效率和用户体验。在客服登录和登出时,算法会更新状态并重新计算分配策略。
摘要由CSDN通过智能技术生成
class serverController extends Controller
{
    private $onlineList = []; //客服id数组
    private $distributeList = []; // 已分配用户数
    private $onlineUser = [];
    private $flagValue = 1; // 阈值

    private function initList($id)
    {
        // init List
        array_push($this->onlineList, $id);
        for ($i = 0; $i < count($this->onlineList); $i++) {
            array_push($this->distributeList, 0);
        }

        if (!$this->getAttributes()) {
            $this->setAttributes();
        }
    }

    // when server login and websocket established
    public function serverLogin(Request $request)
    {
        $id = $request->get('id');

        $type = $this->gettype($id);

        if ($type != null && (int)$type != 0 && is_numeric((int)$type)) {
            if ($this->getAttributes()) {
                array_push($this->onlineList, (int)$id);
                array_push($this->distributeList, 0);
                $this->setAttributes();
            } else {
                $this->initList((int)$id);
            }
        } else {
            $this->getAttributes();
            array_push($this->onlineUser, (int)$id);
            $this->setAttributes();
        }
    }

    // when server logout
    public function Logout(Request $request)
    {
        $id = $request->get('id');

        $tmp = null;
        $this->getAttributes();
        $type = $this->gettype($id);

        if ($type != null && (int)$type != 0 && is_numeric((int)$type)) {
            foreach ($this->onlineList as $key => $item) {
                if ($item == (int)$id) {
                    $tmp = $key;
                }
            }
            unset($this->onlineList[$tmp]);
            unset($this->distributeList[$tmp]);
            if (count($this->onlineList) > 0) {
                $this->flagValue = ceil(count($this->onlineUser) / count($this->onlineList));
            } else {
                $this->flagValue = 1;
            }
            $this->setAttributes();
        } else {
            foreach ($this->onlineUser as $key => $item) {
                if ($item == (int)$id) {
                    $tmp = $key;
                }
            }
            unset($this->onlineUser[$tmp]);
            $this->setAttributes();
        }
    }


    // distribute server id
    public function getServerId()
    {
        $this->getAttributes();
        if (count($this->onlineList) > 0) {
            $serverID = array_rand($this->onlineList, 1);
            if ($this->distributeList[$serverID] < $this->flagValue) {
                ++$this->distributeList[$serverID];
                $this->setAttributes();
                return $this->onlineList[$serverID];
            } else {
                return $this->addFlagValue();
            }
        }
        // not online

    }

    private function addFlagValue()
    {
        foreach ($this->distributeList as $key => $item) {
            if ($item >= $this->flagValue) {
                continue;
            } else {
                ++$this->distributeList[$key];
                $this->setAttributes();
                return $this->onlineList[$key];
            }
        }
        $this->flagValue++;
        $this->setAttributes();
        return $this->onlineList[0];
    }

    private function getContents($path)
    {
        $fp = fopen($path, 'r');
        flock($fp, LOCK_SH);
        $buffer = '';
        while (!feof($fp)) {
            $buffer .= fread($fp, 1024);
        }
        flock($fp, LOCK_UN);
        fclose($fp);
        return $buffer;
    }

    // read file
    private function getAttributes()
    {

        if (Storage::disk('local')->exists('/app/onlineList.txt')
            && Storage::disk('local')->exists('/app/distribute.txt')
            && Storage::disk('local')->exists('/app/flagValue.txt')
            && Storage::disk('local')->exists('/app/onlineUser.txt')) {
            $this->onlineList = json_decode($this->getContents(storage_path('/app/onlineList.txt')), true);
            $this->distributeList = json_decode($this->getContents(storage_path('/app/distribute.txt')), true);
            $this->onlineUser = json_decode($this->getContents(storage_path('/app/onlineUser.txt')), true);
            $this->flagValue = (int)$this->getContents(storage_path('/app/flagValue.txt'));

            return true;
        }
        return false;
    }

    private function setAttributes()
    {
        return $this->setContents(storage_path('/app/distribute.txt'), json_encode($this->distributeList))
            && $this->setContents(storage_path('/app/onlineList.txt'), json_encode($this->onlineList))
            && $this->setContents(storage_path('/app/flagValue.txt'), $this->flagValue)
            && $this->setContents(storage_path('/app/onlineUser.txt'), json_encode($this->onlineUser));
    }

    private function setContents($path, $data)
    {
        $fp = fopen($path, 'w');
        do {
            $isLock = flocK($fp, LOCK_EX);
        } while (!$isLock);
        fwrite($fp, $data);
        flock($fp, LOCK_UN);
        fclose($fp);
        return true;
    }

    // padding isServer
    private function gettype($id)
    {
        return DB::table('user')->where('id', $id)->value('type');
    }
}

这个算法还有许多不足之处,如果大家发现,希望大家指出错误,及时改正。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值