CMD命令:
php sw-x start http


默认控制器:
namespace app\http;
use x\controller\Http;

/**
 * @Controller(prefix="")
*/
class Index extends Http
{
    /**
     * @RequestMapping(route="/", method="get", title="主页")
    */
    public function index() {
        return $this->fetch('SW-X 欢迎你!');
    }
}


浏览器访问:
http://外网IP:9501/

CMD命令:
php sw-x start websocket


默认控制器:
namespace app\websocket;
use x\controller\WebSocket;
/**
 * @Controller(prefix="test")
*/
class Index extends WebSocket
{
    /**
     * @RequestMapping(route="/index", title="action为test/index访问这里")
     * @Param(name="id", type="string", value="1", empty="true", min="10")
     * @Param(name="pid", value="2")
     * @Ioc(class="\x\Db", name="Db")
    */
    public function index() {
        $list = $this->Db->name('user')->find();
        // $this->Db->return();
        return $this->fetch(200, '描述', []);
    }

    /**
     * @RequestMapping(route="/demo", title="action为test/demo访问这里")
    */
    public function demo() {
        return $this->fetch(301, '描述');
    }
}


客户端连接:
ws://外网IP:9501


测试数据包:
{
    "action":"test/demo",
    "data":{}
}

CMD命令:
php sw-x start mqtt


默认广播控制器:
namespace app\mqtt\system;
use x\controller\Mqtt;

class index extends Mqtt {
    
    public function run() {
        // 读取请求内容
        $data = $this->getData();
        // 读取某个主题下的全部设备
        $device_list = $this->select($data['topic']);
        // var_dump($device_list);
        // 获得当前请求的连接标识
        $fd = $this->getFd();
        // 循环广播消息
        foreach ($device_list as $v) {
            // 除了自己都广播
            if ($v['fd'] != $fd) {
                $this->send($v['fd'], [
                        'type' => $data['type'],
                        'topic' => $data['topic'],
                        'message' => $data['message'],
                        'dup' => $data['dup'],
                        'qos' => $data['qos'],
                        'retain' => $data['retain'],
                        'message_id' => $data['message_id'] ?? '',
                    ]
                );
            }
        }
    }
}


客户端连接:
mqtt://外网IP:9501


测试客户端:
推荐使用MQTTX,免费好用

RPC部署过程比较特殊,需要启用2套SW-X代码


RPC服务中心:
修改/config/rpc.php -> http_rpc_is 为 true
CMD命令(安装服务中心Web组件):
php sw-x rpc start
CMD命令(守护进程启动服务中心):
php sw-x rpc start -d
服务中心登陆地址:
http://外网IP:9501/HttpRpc/index
默认账号密码:
swoolex


RPC服务端:
修改/config/server.php -> port 为 9502
CMD命令(启动服务):
php sw-x start rpc 


默认示例RPC服务控制器:
namespace app\rpc\order;
// 新版本都应该继承系统基类
use \x\controller\Rpc;

class create extends Rpc{
    /**
     * 我是\order\create->run()服务
    */
    public function run() {
        // 可以这样获取请求头
        $headers = $this->headers();
        // 可以这样获取请求参数
        $param = $this->param();
        // 可以这样设置返回值说明
        $this->msg('缺少某些请求参数啦!');
        // 可以这样抛出返回值,并同时设置返回值说明
        return $this->fetch(false, '缺少某些请求参数啦!');

        // 当然,也支持直接设置返回值说明
        $this->msg = '缺少某些请求参数啦!';
        // 当然,也支持直接抛出返回值
        return false;
    }
}

服务调用测试:
服务中心先添加上面的order\create->run()服务,然后再参考文档RPC客服端的调用方法即可

// 获取一个默认的数据库连接实例
$Db = new \x\Db();
// 获取一个指定的数据库连接实例
$Db = new \x\Db('标识');
// 启用缓存并设置失效时间
$list = $Db->name('user')->cache()->expire(60)->select();
// 多条件数组查询
$where = [
    ['id' , '<>' , 1],
    ['money', '>=', 100],
    ['name', 'like', '%小黄牛%'],
];
$list = $Db->name('user')->where($where)->select();
// 新增一条数据
$res = $Db->name('user')->insert(['name' => '小黄牛', 'money' => 100]);
// 批量新增
$data = [
    ['name' => '小蓝牛', 'money' => 50],
    ['name' => '小红牛', 'money' => 70],
    ['name' => '小黄牛', 'money' => 100],
];
$res = $Db->name('user')->insert($data);
// 新增时获得ID
$id = $Db->name('user')->insertGetId(['name' => '小黄牛', 'money' => 100]);
// 修改数据
$res = $Db->name('user')->where('id', 1)->update(['name' => '小黄牛', 'money' => 100]);
// 删除数据
$res = $Db->name('user')->where('id', 1)->order('id DESC')->delete();
// 更多参考数据库-ORM相关文档
...

先创建定义任务对应的业务代码,统一存放在 /box/crontab/ 目录下


定时任务业务代码示例:
namespace box\crontab;
use x\Crontab;

class demo2 extends Crontab{

    /**
     * 统一入口
     * @todo 无
     * @author 小黄牛
     * @version v2.5.0 + 2021.07.20
     * @deprecated 暂不启用
     * @global 无
     * @return void
    */
    public function run() {
        echo date('Y-m-d H:i:s', time())."\n";
    }
}


定时器挂载:
路径:/config/crontab.php


示例配置如下:
/*
 * 格式 :二维数组
 * 
 * 字段如下:
 * 
 * rule    :定时器规则,若为int类型则是自定义毫秒,字符串则为linux的crontab规则
 * use     :定时器的命名空间地址
 * status  :是否启用 true.开启  false.关闭  默认.true 
 * bin_log :是否记录日志  true.开启  false.关闭  默认.false 
 * 
 * crontab规则(6):
 * 秒分时天月星期
 * * * * * * 要执行的命令
 - - - - - - 
 | | | | | |
 | | | | | ----- 星期几 (0 - 7) (星期天=0 或者 7)
 | | | | ------ 月份 (1 - 12)
 | | | ------- 天数 (1 - 31)
 | | -------- 小时 (0 - 23)
 | --------- 分钟 (0 - 59)
 ----------- 秒   (0 - 59)
*/
return [
    [
        'rule' => 2000,
        'use' => '\box\crontab\demo',
        'status' => false,
    ],
    [
        'rule' => '3 1 * * * *',
        'use' => '\box\crontab\demo2',
        'status' => false,
        'bin_log' => false,
    ]
];

// 下面以HTTP控制器为例

namespace app\http;
use x\controller\Http;

/**
 * Ioc注入需要是public类型的,否则无法正常注入
 * @Ioc(class="x\Db", name="Db")
 * @AopBefore(class="app\aop\Demo", function="before")
 * @AopAfter(class="app\aop\Demo", function="after")
 * @AopAround(class="app\aop\Demo", function="around")
 * @AopThrows(class="app\aop\Demo", function="throws")
 * @Controller(prefix="index")
*/
class Index extends Http
{
    /**
     * 这是一个允许被外部访问的控制器,路由为:index/index
     * @RequestMapping(route="/index", method="GET", title="主页控制器")
     * @Param(name="username", type="string", empty="true", tips="请输入用户名")
     * @Param(name="password", value="123456", type="string", empty="true", tips="请输入登录密码")
     * @Param(name="id", type="int|string", value="1", empty="true", min="10", max="20", chinese="true", tips="这是一条全参数支持的Param注解", callback="\lifecycle\annotate_param")
     * @Ioc(class="\x\Db", name="Db")
     * @TestCase(class="\box\testcase\index\test", title="用例一")
     * @TestCase(class="\box\testcase\index\test2", title="用例二")
     * @Test(msg="我是自定义的注解,你可以自己定义注解支持哦")
    */
    public function index() {
        return $this->fetch('SW-X:Hello Word!');
    }
    
    /**
     * 这是一个不允许被外部访问的控制器
     * @onRoute
    */
    public function test() {
        return $this->fetch('No Route');
    }
}
协程框架 SW-X 是基于 Swoole 原生协程的注解式框架,自带常驻内存以及 Swoole 其它功能的封装。
注解编程 框架实现了逻辑层的注解绑定,支持Ioc、AOP、Route等多种注解,并支持开发者实现自定义注解标签,可以在不改变实例内部的情况下,对实例的行为和初始化进行控制。
单元测试 SW-X内置的注解式单元测试,可以有效的将DAO数据隔离,实现了DAO无污染的细化单元测试用例。
数据库 数据提供ORM支持,数据库的封装高度兼容 PHP各类框架语法,方便Phper 快速切换到 SW-X。
连接池 框架自带 Mysql/Redis 高效连接池,且实现所有连接断线重连。开发者不用关心连接池,相应组件已经实现。
RPC服务 SW-X的RPC服务分为RpcServer、RpcClient和RpcWeb服务中心三大组件。框架提供了完整的RPC服务,并封装了FPM模式下可直接使用的RpcClient客户端,可以优雅高效的使用Rpc服务。