<blockquote class="danger">由于無法參悟各worker間如何共享一個class或者全局變量(如channel不在全局變量上就無法進行消息投遞),故用Swoole\Table代替.若有人知道如何共享,請不吝告知,謝謝!</blockquote>
<blockquote class="danger">每個worker都是擁有獨立的App實體,所以instance到App內是無效的.</blockquote>
<blockquote class="danger">service也是無效的,雖然在啟動的時候共用了一個,但是在worker啟動后就會被私有化,因此數據也是不通的.</blockquote>
`app\service`目錄下新建
<details>
<summary>Atomic.php</summary>
~~~
<?php
namespace app\service;
use think\swoole\Table;
/**
* Class Atomic
* @package app\service
* Waring 數據存于內存中,如果服務重啟數據會丟失,注意離線存儲,僅做示例參考.
*/
class Atomic
{
private $atomoc;
public function __construct(Table $table)
{
//取得table
$this->atomoc = $table->get('vote');
}
//檢查是否存在
private function check(string $uid): void
{
if ($this->atomoc->exist($uid) == false) {
$this->set($uid);
}
}
//創建一個參與者
public function set(string $uid): void
{
// $this->atomoc->set($uid, ['poll' => 0,'icon'=>'']);
$this->atomoc->set($uid, ['poll' => 0]);
}
//票數自增-Table->incr屬于原子操作,并發安全.
public function add(string $uid, int $step = 1): int
{
$this->check($uid);
return $this->atomoc->incr($uid, 'poll', $step);
}
//票數自減
public function sub(string $uid, int $step = 1): int
{
$this->check($uid);
return $this->atomoc->decr($uid, 'poll', $step);
}
//獲取票數
public function get(string $uid): int
{
$this->check($uid);
return $this->atomoc->get($uid, 'poll');
}
//移除參與者
public function cancelled(string $uid): void
{
if ($this->atomoc->exist($uid)) {
$this->atomoc->del($uid);
}
}
//獲取所有參與者,并降序.
public function all(): array
{
$data = [];
foreach ($this->atomoc as $uid => $item) {
$data[$uid] = $this->atomoc->get($uid);
}
arsort($data);
return $data;
}
}
~~~
</details>
在`controller`中使用
~~~
public function index(Atomic $atomic)
{
if ($this->request->param('vote')) {
$atomic->add((string)rand(1, 5));
$atomic->add((string)rand(1, 5), 2);
$atomic->add((string)rand(1, 5), rand(1, 10));
dump($atomic->all());
}
}
~~~
<blockquote class="danger">服務重啟數據會丟失,注意離線存儲!!!</blockquote>
訪問結果如下
