<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> 访问结果如下 ![](https://img.kancloud.cn/e8/ee/e8eea6cdc9f122ac7834cdddee3f7cf0_386x271.png)