首页
下载
文档
社区
视频
捐赠
源代码
赞助商
AOT 编译器
AI 助理
商业产品
PHP AOT 原生编译器
Swoole-Compiler 代码加密器
CRMEB 新零售社交电商系统
登录
注册
全部
提问
分享
讨论
建议
公告
开发框架
CodeGalaxy
发表新帖
swoole_table的应用场景是什么?我现在做一个视频弹幕功能,能否用到swoole_table?
### 问题描述 swoole_table的应用场景是什么?我现在做一个视频弹幕功能,能否用到swoole_table? ### Swoole版本,PHP版本,以及操作系统版本信息 php7.1 centos7 ### 相关代码 ```php 请将代码粘贴至此处(请勿用截图) ``` /** * 建立连接 * @method onOpen * @author chengzhigang<1256699215@qq.com> */ public function onOpen($serv, $request) { Log::info('onOpen'); $param = $request->get; $room_id = $param['room_id']; $result = $this->getRoomSpeck($serv,$room_id); $this->addRoom($room_id,$request->fd);//加入房间 return ['status'=>1,'msg'=>'请求成功','data'=>['active'=>'connect','data'=>$result]]; } public function onMessage($serv, $frame) { $data = json_decode($frame->data,true); $room_id = $data['room_id']; $result = []; if($data['active']=='speck'){ $result = $this->addSpeck($room_id,$frame->fd,$data); } return ['status'=>1,'msg'=>'请求成功','data'=>['active'=>$data['active'],'data'=>$result]]; } //加入房间 public function addRoom($room_id,$fd){ $roomInfo = [ 'room_id' => $room_id, 'fd' => $fd, 'nick_name' => createNickname() ]; Redis::hSet('Room:'.$room_id,$fd,json_encode($roomInfo)); } //删除弹幕 public function clearRoomSpeck($serv,$room_id){ $fds = Redis::hKeys('Room:'.$room_id); foreach ($fds as $fd) { Redis::del('Speck:' . $room_id.':'.$fd); } } //获取历史弹幕 public function getRoomSpeck($serv,$room_id){ $historySpeck = []; $fds = Redis::hKeys('Room:'.$room_id); foreach ($fds as $fd) { $speckData = Redis::lRange('Speck:' . $room_id.':'.$fd,0,-1); foreach($speckData as $v){ $historySpeck[] = $v; } } return $historySpeck; } //存储弹幕 public function addSpeck($room_id,$fd,$data){ $speckInfo = [ 'room_id' => $room_id, 'fd' => $fd, 'msg' => $data['msg'], 'time' => $data['time'], 'speed' => $data['speed'], 'color' => $data['color'] ]; Redis::rPush('Speck:'.$room_id.':'.$fd,json_encode($speckInfo)); return $speckInfo; } ### 你期待的结果是什么?实际看到的错误信息又是什么? 上面的代码我其实已经实现了弹幕功能,建立连接时将用户加入房间,发送弹幕时存储弹幕信息,用了两个redis分别存储用户信息和弹幕信息,即使重启websocket,数据也是不会丢失的。 但是我想用swoole_table,不知道重启websocket后,table中的数据是否会丢失,而且table存储数据方式是key-value形式的,无法像redis的list方法存储弹幕信息。不知道用swoole_table能否实现上述的弹幕功能,能实现的话具体怎么实现?不能实现的话,swoole_table的应用场景在哪?
发布于6年前 · 5 次浏览 · 来自
提问
观海听潮·
### 问题描述 swoole_table的应用场景是什么?我现在做一个视频弹幕功能,能否用到swoole_table? ### Swoole版本,PHP版本,以及操作系统版本信息 php7.1 centos7 ### 相关代码 ```php 请将代码粘贴至此处(请勿用截图) ``` /** * 建立连接 * @method onOpen * @author chengzhigang<1256699215@qq.com> */ public function onOpen($serv, $request) { Log::info('onOpen'); $param = $request->get; $room_id = $param['room_id']; $result = $this->getRoomSpeck($serv,$room_id); $this->addRoom($room_id,$request->fd);//加入房间 return ['status'=>1,'msg'=>'请求成功','data'=>['active'=>'connect','data'=>$result]]; } public function onMessage($serv, $frame) { $data = json_decode($frame->data,true); $room_id = $data['room_id']; $result = []; if($data['active']=='speck'){ $result = $this->addSpeck($room_id,$frame->fd,$data); } return ['status'=>1,'msg'=>'请求成功','data'=>['active'=>$data['active'],'data'=>$result]]; } //加入房间 public function addRoom($room_id,$fd){ $roomInfo = [ 'room_id' => $room_id, 'fd' => $fd, 'nick_name' => createNickname() ]; Redis::hSet('Room:'.$room_id,$fd,json_encode($roomInfo)); } //删除弹幕 public function clearRoomSpeck($serv,$room_id){ $fds = Redis::hKeys('Room:'.$room_id); foreach ($fds as $fd) { Redis::del('Speck:' . $room_id.':'.$fd); } } //获取历史弹幕 public function getRoomSpeck($serv,$room_id){ $historySpeck = []; $fds = Redis::hKeys('Room:'.$room_id); foreach ($fds as $fd) { $speckData = Redis::lRange('Speck:' . $room_id.':'.$fd,0,-1); foreach($speckData as $v){ $historySpeck[] = $v; } } return $historySpeck; } //存储弹幕 public function addSpeck($room_id,$fd,$data){ $speckInfo = [ 'room_id' => $room_id, 'fd' => $fd, 'msg' => $data['msg'], 'time' => $data['time'], 'speed' => $data['speed'], 'color' => $data['color'] ]; Redis::rPush('Speck:'.$room_id.':'.$fd,json_encode($speckInfo)); return $speckInfo; } ### 你期待的结果是什么?实际看到的错误信息又是什么? 上面的代码我其实已经实现了弹幕功能,建立连接时将用户加入房间,发送弹幕时存储弹幕信息,用了两个redis分别存储用户信息和弹幕信息,即使重启websocket,数据也是不会丢失的。 但是我想用swoole_table,不知道重启websocket后,table中的数据是否会丢失,而且table存储数据方式是key-value形式的,无法像redis的list方法存储弹幕信息。不知道用swoole_table能否实现上述的弹幕功能,能实现的话具体怎么实现?不能实现的话,swoole_table的应用场景在哪?
赞
0
收藏
提问
分享
讨论
建议
公告
开发框架
CodeGalaxy
登录
后参与评论
评论
2020-06-10
序冢
swoole table 基于共享内存mmap 做的,linux多进程是写时复制,多个进程之间无法共享内存使用,使用swoole_table可以在多个进程中共享数据,比如说接入弹幕的用户信息,可以做一个用户信息池,存储用户信息和连接fd的映射关系
赞
0
回复
2020-06-11
观海听潮·
回复
序冢
刚看了swoole_table的优势,多进程存储信息用redis也是有IO消耗的,swoole_table是没有消耗的。初学swoole,问题有点多... 1、swoole_table是key-value形式的,存储用户信息是可以的,但是如果存储弹幕信息的话,好像又实现不了,感觉有点鸡肋,还得用redis实现存储弹幕。 2、重启websocket服务后,swoole_table中存储的信息会不会丢失? 3、不管信息是存储在redis中还是swoole_table中,数据最后都要写入数据库的,是什么时候写入数据库比较合适,或者是异步task写入?
赞
0
回复
2020-10-31
易清风同学
回复
观海听潮·
重启后会消失
赞
0
回复
2020-06-12
Rango
你可以将`Swoole\Table`理解为是一个二维的`PHP Array`
赞
0
回复
2020-06-15
序冢
针对您的第二个问题,swoole_table既然能实现共享内存肯定是基于mmap做的,mmap有一种匿名共享内存,重启进程后会丢失的
赞
0
回复