首页
下载
文档
问答社区
视频
捐赠
源代码
AI 助理
赞助商
CRMEB
Apipost
腾讯云
微擎
禅道
51Talk
商业产品
Swoole AI 智能文档翻译器
Swoole-Compiler PHP 代码加密器
CRMEB 新零售社交电商系统
登录
注册
全部
提问
分享
讨论
建议
公告
开发框架
CodeGalaxy
发表新帖
关于websocket 等 fd和业务uid的绑定的疑问
### 问题描述 目前在做一个简单的IM,一个用户聊天页面,一个客服获取发送信息的用户列表页面,一个是客服聊天页面,客服聊天页面是从列表页面超链接跳转的,这样就导致了客服在列表有一个fd,跳转到聊天页面又有一个fd,导致业务判断太过于冗杂,请问能根据自定义的业务uid绑定在会话周期内唯一的fd吗 ### Swoole版本,PHP版本,以及操作系统版本信息 swoole:2.2.0 php:7.0.33 操作系统: Ubuntu16.04 ### 相关代码 ```php <?php /** * */ require_once "./PDO.php"; class WSServer { private $serv; //private $redis; public $pdo; public function __construct() { # code... $this->serv = new Swoole\WebSocket\Server('0.0.0.0', 9601); //$this->redis = new Redis(); //$this->redis->connect('127.0.0.1', 6379); $this->pdo = new PDOModel(); /*$this->serv->set(array( 'daemonize' => 1, // 作为守护进程运行,需同时设置log_file 'log_file' => '/var/log/swoole_kf.log', // 指定标准输出和错误日志文件 ));*/ $this->serv->on('open', [$this, 'onOpen']); $this->serv->on('message', [$this, 'onMessage']); $this->serv->on('close', [$this, 'onClose']); $this->serv->start(); } public function onOpen($serv, $request){ echo "handshake success with $request->fd \n"; } public function onMessage($serv, $frame){ $recv = $frame->data; //根据tag划分 $data = json_decode($recv, true); switch ($data['tag']) { case 'handshakesuccess': # code... $this->userPush($data['type'], $data['uid'], $frame); break; case 'sendmsg': if($data['issingly'] == 'yes'){ $resp = [ 'tag' => 'recvmsg', 'fromfd' => $data['fromfd'], 'msg' => $data['msg'], 'type' => $data['type'] ]; $this->serv->push($data['tofd'], json_encode($resp)); }else{ //获取所有的连接池(用户第一次群发给客服) $kf = $this->pdo->findAll('bindinfo',['type' => 3],'fd'); print_r($kf); if($kf){ foreach($kf as $v){ $resp = [ 'tag' => 'recvmsg', 'fromfd' => $data['fromfd'], 'msg' => $data['msg'], 'type' => $data['type'], 'uid' => $data['uid'] ]; $this->serv->push($v['fd'], json_encode($resp)); } } } break; default: # code... break; } } public function onClose($serv, $fd){ $this->unbindAll($fd); echo "client {$fd} closed\n"; //这边必须要删除数据库 } /** * 用户信息存入数据库(init) */ private function userPush($type, $uid, $frame){ //因swoole存在fd的问题,因此还是根据uid来比对 $unBool = $this->unbindAll($frame->fd, $uid, $type); if($unBool){ $this->pdo->add('bindinfo',['uid' => $uid, 'fd' => $frame->fd, 'type' => $type]); $resp = json_encode(['tag' => 'redispushsuccess','type' => $type, 'swoole_fd' => $frame->fd, 'uid' => $uid]); $this->serv->push($frame->fd, $resp); } } /** * 清空用户信息和msg(先不考虑),以防fd影响 */ private function unbindAll($fd, $uid = null, $type = null){ try{ if($uid && $type){ $this->pdo->del('bindinfo',['uid' => $uid, 'type' => $type, 'fd' => $fd]); }else{ $this->pdo->del('bindinfo',['fd' => $fd]); } return true; }catch(PDOException $e){ echo 'pdoerror '.$e->getMessage().' file is '.$e->getFile().' line on '.$e->getLine(); return false; } } } new WSServer(); //uid是业务登录的id,客服列表页面和客服聊天页面都是公用一个js,每次跳转都是两个客服的fd ``` ### 你期待的结果是什么?实际看到的错误信息又是什么?
发布于4年前 · 17 次浏览 · 来自
提问
likecat
### 问题描述 目前在做一个简单的IM,一个用户聊天页面,一个客服获取发送信息的用户列表页面,一个是客服聊天页面,客服聊天页面是从列表页面超链接跳转的,这样就导致了客服在列表有一个fd,跳转到聊天页面又有一个fd,导致业务判断太过于冗杂,请问能根据自定义的业务uid绑定在会话周期内唯一的fd吗 ### Swoole版本,PHP版本,以及操作系统版本信息 swoole:2.2.0 php:7.0.33 操作系统: Ubuntu16.04 ### 相关代码 ```php <?php /** * */ require_once "./PDO.php"; class WSServer { private $serv; //private $redis; public $pdo; public function __construct() { # code... $this->serv = new Swoole\WebSocket\Server('0.0.0.0', 9601); //$this->redis = new Redis(); //$this->redis->connect('127.0.0.1', 6379); $this->pdo = new PDOModel(); /*$this->serv->set(array( 'daemonize' => 1, // 作为守护进程运行,需同时设置log_file 'log_file' => '/var/log/swoole_kf.log', // 指定标准输出和错误日志文件 ));*/ $this->serv->on('open', [$this, 'onOpen']); $this->serv->on('message', [$this, 'onMessage']); $this->serv->on('close', [$this, 'onClose']); $this->serv->start(); } public function onOpen($serv, $request){ echo "handshake success with $request->fd \n"; } public function onMessage($serv, $frame){ $recv = $frame->data; //根据tag划分 $data = json_decode($recv, true); switch ($data['tag']) { case 'handshakesuccess': # code... $this->userPush($data['type'], $data['uid'], $frame); break; case 'sendmsg': if($data['issingly'] == 'yes'){ $resp = [ 'tag' => 'recvmsg', 'fromfd' => $data['fromfd'], 'msg' => $data['msg'], 'type' => $data['type'] ]; $this->serv->push($data['tofd'], json_encode($resp)); }else{ //获取所有的连接池(用户第一次群发给客服) $kf = $this->pdo->findAll('bindinfo',['type' => 3],'fd'); print_r($kf); if($kf){ foreach($kf as $v){ $resp = [ 'tag' => 'recvmsg', 'fromfd' => $data['fromfd'], 'msg' => $data['msg'], 'type' => $data['type'], 'uid' => $data['uid'] ]; $this->serv->push($v['fd'], json_encode($resp)); } } } break; default: # code... break; } } public function onClose($serv, $fd){ $this->unbindAll($fd); echo "client {$fd} closed\n"; //这边必须要删除数据库 } /** * 用户信息存入数据库(init) */ private function userPush($type, $uid, $frame){ //因swoole存在fd的问题,因此还是根据uid来比对 $unBool = $this->unbindAll($frame->fd, $uid, $type); if($unBool){ $this->pdo->add('bindinfo',['uid' => $uid, 'fd' => $frame->fd, 'type' => $type]); $resp = json_encode(['tag' => 'redispushsuccess','type' => $type, 'swoole_fd' => $frame->fd, 'uid' => $uid]); $this->serv->push($frame->fd, $resp); } } /** * 清空用户信息和msg(先不考虑),以防fd影响 */ private function unbindAll($fd, $uid = null, $type = null){ try{ if($uid && $type){ $this->pdo->del('bindinfo',['uid' => $uid, 'type' => $type, 'fd' => $fd]); }else{ $this->pdo->del('bindinfo',['fd' => $fd]); } return true; }catch(PDOException $e){ echo 'pdoerror '.$e->getMessage().' file is '.$e->getFile().' line on '.$e->getLine(); return false; } } } new WSServer(); //uid是业务登录的id,客服列表页面和客服聊天页面都是公用一个js,每次跳转都是两个客服的fd ``` ### 你期待的结果是什么?实际看到的错误信息又是什么?
赞
0
分享
收藏
提问
分享
讨论
建议
公告
开发框架
CodeGalaxy
评论
2020-07-30
鲁飞
找个开源的im项目学习一下就知道了
赞
0
回复
微信公众号
热门内容
暂无回复的问答
- CodeGalaxy K3s 轻量集群节点之间如何实现负载均衡
- 关于openssl CURL WARNING swSSL_connect: SSL_connect(fd=69) failed. Error: error:141A318A:SSL routines:tls_process_ske_dhe:dh key too small[1|394]
- 多个模型如何进行事务异常回退?
- websocket开启wss报错
- 协程tcp服务器如何使用多进程?recv()方法接收信息,打印出来的pid一直是同一个。没用使用到多进程啊。