通过 Swoole\Table 实现 Swoole 多进程数据共享
第三方存储媒介前面我们介绍了基于 Swoole 的?
但是这也会引入新的问题,多进程同时操作一条记录或一个文件存在并发访问问题,以数据库操作为例,两个进程可能会同时读取一条数据,或者一个进程对某条记录进行更新处理时,另一个进程也来读取这条记录并进行操作,会导致最终结果数据与预期不一致的情况,这个时候,我们就需要引入锁的概念,当一个进程(比如进程A)对某个记录进行写操作时,对该记录加锁,这样其它进程就无法操作该条记录, 直到进程 A 事务提交再释放这个锁,让其他进程可以进行操作。 内存共享PHP 相关扩展对于单机操作来说,除了这些第三方存储媒介之外,还可以通过共享内存的方式实现进程间数据读写操作,有多个 PHP 扩展可以支持共享内存数据操作:
Swoole Table但是上述扩展要么不支持锁,要么高并发时性能比较差,所以 Swoole 自己实现了一个共享内存读写工具 ——?
<?php // 初始化一个容量为 1024 的 Swoole Table $table = new SwooleTable(1024); // 在 Table 中新增 id 列 $table->column('id',SwooleTable::TYPE_INT); // 在 Table 中新增 name 列,长度为 50 $table->column('name',SwooleTable::TYPE_STRING,10); // 在 Table 中新泽 score 列 $table->column('score',SwooleTable::TYPE_FLOAT); // 创建这个 Swoole Table $table->create(); // 设置 Key-Value 值 $table->set('student-1',['id' => 1,'name' => '学小君','score' => 80]); $table->set('student-2',['id' => 2,'name' => '学院君','score' => 90]); // 如果指定 Key 值存在则打印对应 Value 值 if ($table->exist('student-1')) { echo "Student-" . $table->get('student-1','id') . ':' . $table->get('student-1','name').":". $table->get('student-1','score') . "n"; } // 自增操作 $table->incr('student-2','score',5); // 自减操作 $table->decr('student-2',5); // 表中总记录数 $count = $table->count(); // 删除指定表记录 $table->del('student-1');
此外? 在 Laravel 中使用 SwooleTable如果要在 Laravel 中集成 Swoole 使用? 'swoole_tables' => [ 'ws' => [ // 表名,会加上 Table 后缀,比如这里是 wsTable 'size' => 102400,// 表容量 'column' => [ // 表字段,字段名为 value ['name' => 'value','type' => SwooleTable::TYPE_INT,'size' => 8],],... // 还可以定义其它表 ],
然后我们可以在代码中通过 class WebSocketService implements WebSocketHandlerInterface { ... // 连接建立时触发 public function onOpen(Server $server,Request $request) { // 在触发 WebSocket 连接建立事件之前,Laravel 应用初始化的生命周期已经结束,你可以在这里获取 Laravel 请求和会话数据 // 调用 push 方法向客户端推送数据,fd 是客户端连接标识字段 Log::info('WebSocket 连接建立:' . $request->fd); app('swoole')->wsTable->set('fd:' . $request->fd,['value' => $request->fd]); $server->push($request->fd,'Welcome to WebSocket Server built on LaravelS'); } // 收到消息时触发 public function onMessage(Server $server,Frame $frame) { foreach (app('swoole')->wsTable as $key => $row) { if (strpos($key,'fd:') === 0 && $server->exist($row['value'])) { Log::info('Receive message from client: ' . $row['value']); // 调用 push 方法向客户端推送数据 $server->push($frame->fd,'This is a message sent from WebSocket Server at ' . date('Y-m-d H:i:s')); } } } ... }
然后我们参考在 Laravel 中集成 Swoole 实现 WebSocket 服务器这篇教程从客户端向 WebSocket 服务器发起请求,即可在最新日志文件中看到相应的日志信息: [2020-04-24 19:39:03] local.INFO: WebSocket 连接建立:1 [2020-04-24 19:39:07] local.INFO: Receive message from client: 1
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |