多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
**需求**:用户发表了某篇文章,其他人阅读后发表评论,评论经过后台审核,审核后通知作者。 ### **方案一:** 审核操作改为ajax操作,success回调内再new一个websocket客户端,然后send?可以,但是这显然不是一个很好的操作。 要想与websocket server通信,客户端只能是websocket客户端!既然我们刚刚否决了new一个websocket客户端,那是要怎么做呢? ### **方案二:** 首先我们要想让web应用同server进行“互撩”,swoole\_client少不了,既然有swoole\_client,swoole\_server肯定也少不了。但是目前server正在跑websocket,难不成我们在单独跑一个tcp server?对,我们就是要在websocket server的基础之上,想办法再跑一个tcp server。 为了使用多端口复合协议,swoole为server提供了listen方法,可以让当前server监听新的端口。 比如我们可以让刚刚创建的websocket server额外监听9502端口,这个端口主要负责tcp的工作。 $this->tcp = $this->server->listen('127.0.0.1', 9502, SWOOLE_SOCK_TCP); //关闭websocket模式 $this->server->set([ 'open_websocket_protocol' => false, ]); $this->tcp->set([ 'open_eof_check' => true, //打开EOF检测 'package_eof' => "\r\n", //设置EOF 'open_eof_split' => true, // 自动分包 ]); $this->_tcp->on('Receive', [$this, 'onReceive']); listen函数返回的是swoole\_server\_port对象,需要注意的是swoole\_server\_port的set函数只能设置一些特定的参数,比如socket参数、协议相关等,像worker\_num、log\_file、max\_request等等这些都是不支持的。就tcp服务器而言,swoole\_server\_port对象也仅仅对onConnect\\onReceive\\onClose这三个回调支持,其他的一律不可用,详细可翻阅swoole手册查看。 **再来看下我们现在的流程** 1、用户发表评论 => 评论进入审核状态 ;很明显这个过程我们不需要做什么 2、管理员审核该评论 => 通知文章作者; server端除了刚刚设置的$this->tcp一段代码之外,我们单独绑定了onReceive回调,下面看onReceive回调的实现 public function onReceive($serv, $fd, $fromId, $data) { try { $data = json_decode($data, true); if (!isset($data['event'])) { throw new \Exception("params error, needs event param.", 1); } $method = $data['event']; // 调起对应的方法 if(!method_exists($this, $method)) { throw new \Exception("params error, not support method.", 1); } $this->$method($fd, $data); return true; } catch (\Exception $e) { $msg = $e->getMessage(); throw new \Exception("{$msg}", 1); } } 我们再来看websocket客户端的代码,改代码是管理员审核之后调用。 class Client { private $client; public function __construct () { $this->client = new Swoole\\Client(SWOOLE_SOCK_TCP); if (!$this->client->connect('127.0.0.1', 9502)) { $msg = 'swoole client connect failed.'; throw new \Exception("Error: {$msg}."); } } public function sendData ($data) { $data = $this->togetherDataByEof($data); $this->client->send($data); } public function togetherDataByEof($data) { if (!is_array($data)) { return false; } return json_encode($data) . "\r\n"; } } $client = new Client; $client->sendData([ 'event' => 'alertTip', 'toUid' => 100, ]); 注意:发送数据的末尾需要拼接EOF标记