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');
}
}
这个算法还有许多不足之处,如果大家发现,希望大家指出错误,及时改正。