/** * 发送数据 * * @param string $type 类型: task | msg * @param mixed $data * @param string $workerName 当前进程对应的名称 * @param \Closure $callback 需要回调的信息, $type = task 时支持 * @return bool */ public function sendData($type, $data, $workerName, $callback = null) { $resource = $this->resource(); if (!$resource) { return false; } $id = Host::$taskIdAtomic->add(); $obj = new \stdClass(); $obj->type = $type; $obj->id = $id; $obj->sid = $this->serverId; $obj->wid = $this->workerId; $obj->wname = $workerName; $obj->data = $data; if ($obj->id > 4000000000) { # 重置序号 Host::$taskIdAtomic->set(0); $obj->id = 0; } if ($callback && $type === 'task') { # 设置一个回调 $this->taskCallbackList[$id] = $callback; } $str = ($this->key ? \MyQEE\Server\RPC\Server::encrypt($obj, $this->key) : msgpack_pack($obj)) . \MyQEE\Server\RPC\Server::$EOF; $len = strlen($str); $wLen = @fwrite($resource, $str); if ($len !== $wLen) { # 发送失败 $this->close(); return false; } else { $this->lastTaskId = $obj->id; return true; } }
/** * @param $type * @param $name * @param null $v * @return mixed */ protected function __send($type, $name, $args = null) { if (!$this->__client) { return false; } $obj = new \stdClass(); $obj->id = microtime(1); $obj->type = $type; $obj->name = $name; if ($args) { $obj->args = $args; } /** * @var RPC $rpc */ $rpc = $this->__rpc; $key = $rpc::_getRpcKey(); $str = Server::encrypt($obj, $key, $this->__rpc) . Server::$EOF; $len = strlen($str); $sock = fopen("php://fd/{$this->__client->sock}", 'w'); $wLen = fwrite($sock, $str, $len); if ($wLen !== $len) { return false; } $rs = fread($sock, 1048576); fclose($sock); if ($rs[0] === '{') { $rs = @json_decode($rs); } else { $rs = msgpack_unpack($rs); if ($key) { $rs = Server::decryption($rs, $key); } } if (is_object($rs) && $rs instanceof \stdClass) { switch ($rs->type) { case 'error': # 系统返回了一个错误 throw new \Exception($rs->msg, $rs->code); break; case 'close': $this->__closeByServer = true; throw new \Exception($rs->msg, $rs->code); break; } } return $rs; }
public function onReceive($server, $fd, $fromId, $data) { /** * @var \Swoole\Server $server */ $tmp = @msgpack_unpack($data); if ($tmp && is_object($tmp)) { $data = $tmp; unset($tmp); if ($data instanceof \stdClass) { if ($data->bind) { # 绑定进程ID $server->bind($fd, $data->id); return; } if ($key = \MyQEE\Server\Register\Client::$host->key) { # 需要解密 $data = \MyQEE\Server\RPC\Server::decryption($data, $key); # 解密失败 if (!$data) { return; } } $eof = \MyQEE\Server\RPC\Server::$EOF; switch ($data->type) { case 'task': case 'taskWait': $rs = Server::$workerTask->onTask($server, $data->id, $data->wid, $data->data, $data->sid); if ($rs !== null || $data->type === 'taskWait') { # 执行 Finish $rsData = new \stdClass(); $rsData->id = $data->id; $rsData->data = $rs; $rsData->wname = $data->wname; if ($key) { # 加密数据 $rsData = \MyQEE\Server\RPC\Server::encrypt($rsData, $key) . $eof; } else { # 格式化数据 $rsData = msgpack_pack($rsData) . $eof; } $server->send($fd, $rsData, $fromId); } break; } } } else { Server::$instance->warn("task server get error msgpack data length: " . strlen($data)); Server::$instance->debug($data); $this->server->close($fd); } }