启动镜像
# docker 启动进入 Swoft 镜像
docker run -it --name swoft_rpc -p 8308:18307 \
-v /data/php/test/swoft/Swoft_rpc/:/swoft \
-w /swoft rpc/swoft:2.0.6 sh
# 查看 PHP 版本
php bin/swoft -V
# 返回:PHP: 7.3.4, Swoft: 2.0.8, Swoole: 4.4.5
# 启动 Swoft rpc
swoftcli run -c rpc:start -b bin/swoft
创建数据表
-- 数据库: `myreader`
CREATE TABLE `course_kinds` (
`item_id` int(11) NOT NULL,
`kind_name` varchar(50) DEFAULT NULL COMMENT '类别名称',
`pid` int(11) DEFAULT '0' COMMENT '父级ID',
`pids` text COMMENT '所有父级ID',
`ext1` varchar(1000) DEFAULT NULL COMMENT '扩展字段1',
`ext2` varchar(1000) DEFAULT NULL COMMENT '扩展字段2'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `course_main` (
`item_id` int(11) NOT NULL,
`course_title` varchar(200) DEFAULT NULL,
`course_ltitle` varchar(200) DEFAULT NULL,
`course_price` decimal(10,2) DEFAULT '0.00',
`course_disc` tinyint(4) DEFAULT '10' COMMENT '默认10',
`course_status` tinyint(4) DEFAULT '0' COMMENT '0审核中 1已发布 2已下架',
`course_intr` text,
`course_body` longtext,
`course_pubtime` datetime DEFAULT NULL,
`course_edittime` datetime DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `course_metas` (
`item_id` int(11) NOT NULL COMMENT '主键',
`course_id` int(11) DEFAULT NULL COMMENT '课程ID',
`meta_name` varchar(100) DEFAULT NULL COMMENT '元信息名称 ',
`meta_value` text COMMENT '元信息内容'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='包含了课程点击量、收藏数、附件名或其他自定义等等';
ALTER TABLE `course_kinds` ADD PRIMARY KEY (`item_id`);
ALTER TABLE `course_main` ADD PRIMARY KEY (`item_id`);
ALTER TABLE `course_metas` ADD PRIMARY KEY (`item_id`),
ADD UNIQUE KEY `AK_uniquekey` (`course_id`,`meta_name`);
ALTER TABLE `course_kinds` MODIFY `item_id` int(11) NOT NULL AUTO_INCREMENT;
ALTER TABLE `course_main` MODIFY `item_id` int(11) NOT NULL AUTO_INCREMENT;
ALTER TABLE `course_metas` MODIFY `item_id` int(11) NOT NULL AUTO_INCREMENT;
INSERT INTO `course_main` (`item_id`, `course_title`, `course_ltitle`, `course_price`, `course_disc`, `course_status`, `course_intr`, `course_body`, `course_pubtime`, `course_edittime`) VALUES
(1, 'test', 'test', 40.00, 10, 0, 'intr', 'body', NULL, NULL);
INSERT INTO `course_metas` (`item_id`, `course_id`, `meta_name`, `meta_value`) VALUES
(1, 1, 'click', '10');
COMMIT;
部署代码
Swoft_rpc\App\Rpc\Service\ICourceService.php
<?php
namespace App\Rpc\Lib;
interface ICourse {
public function list($size);
public function get($id);
}
Swoft_rpc\App\Rpc\Lib\ICource.php
<?php
namespace App\Rpc\Service;
use App\Models\CourseMain;
use App\Models\CourseMetas;
use App\Models\CourseModel;
use App\Rpc\Lib\ICourse;
use Swoft\Rpc\Server\Annotation\Mapping\Service;
/**
* Class CourseService
* @package App\Rpc\Service
* @Service()
*/
class CourseService implements ICourse {
public function list($size) {
return ["list"];
}
public function get($id) {
// 测试
// return ["get"];
$main = CourseMain::find($id);
$metas = CourseMetas::where("course_id", $id)->get();
$model = new CourseModel();
$model->setCourseMain($main);
$model->setCourseMetas($metas);
return $model->toArray();
}
}
test.php
<?php
# 参考:https://www.swoft.org/documents/v2/core-components/rpc-server/#-swoft-
const RPC_EOL = "\r\n\r\n";
function request($host, $class, $method, $param, $version = '1.0', $ext = []) {
$fp = stream_socket_client($host, $errno, $errstr);
if (!$fp) {
throw new Exception("stream_socket_client fail errno={$errno} errstr={$errstr}");
}
$req = [
"jsonrpc" => '2.0',
"method" => sprintf("%s::%s::%s", $version, $class, $method),
'params' => $param,
'id' => '',
'ext' => $ext,
];
$data = json_encode($req) . RPC_EOL;
fwrite($fp, $data);
$result = '';
while (!feof($fp)) {
$tmp = stream_socket_recvfrom($fp, 1024);
if ($pos = strpos($tmp, RPC_EOL)) {
$result .= substr($tmp, 0, $pos);
break;
} else {
$result .= $tmp;
}
}
fclose($fp);
return json_decode($result, true);
}
// 修改为主机地址和端口号
$ret = request('tcp://192.168.60.221:8308', \App\Rpc\Lib\ICourse::class, 'get', [1], "1.0");
var_dump($ret);
// 容器内启动 RPC 服务,本地终端运行 php test.php
// 如下返回,说明接口已经测试通
array(2) {
["jsonrpc"]=>
string(3) "2.0"
["result"]=>
array(1) {
[0]=>
string(3) "get"
}
}
// 连接数据库查询后返回数据
Swoft_rpc\App\bean.php
<?php
// 修改数据库配置
'db' => [
'class' => Database::class,
'dsn' => 'mysql:dbname=myreader;host=192.168.60.221;port=3306',
'username' => 'root',
'password' => 'asdf',
'charset' => 'utf8mb4',
'config' => [
'collation' => 'utf8mb4_general_ci',
'strict' => false,
'timezone' => '+8:00',
'modes' => 'NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES',
'fetchMode' => PDO::FETCH_ASSOC,
],
],
# 进入容器
docker exec -it swoft_rpc sh
# 生成模型(或者可以本地直接运行生成)
php bin/swoft entity:create --table=course_kinds,course_main,course_metas --path=@app/Models
Swoft_rpc\App\Models\CourseModel.php
<?php
namespace App\Models;
class CourseModel {
// 定义好变量后 Alt + Ins 生成 get 和 set 方法
/** @var $course_main CourseMain */
protected $course_main;
/** @var $course_metas CourseMetas */
protected $course_metas;
// 返回数组
public function toArray(){
return [
"course" => $this->course_main->toArray(),
"metas" => $this->course_metas->toArray()
];
}
/**
* @return mixed
*/
public function getCourseMain()
{
return $this->course_main;
}
/**
* @param mixed $course_main
*/
public function setCourseMain($course_main): void
{
$this->course_main = $course_main;
}
/**
* @return mixed
*/
public function getCourseMetas()
{
return $this->course_metas;
}
/**
* @param mixed $course_metas
*/
public function setCourseMetas($course_metas): void
{
$this->course_metas = $course_metas;
}
}
需要做一个定制化的网关