Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/watish/watishweb
一个Swoole驱动的多进程协程Web MVC框架
https://github.com/watish/watishweb
php php-framework php8 swoole-framework swoole-http swoole-websocket
Last synced: about 2 months ago
JSON representation
一个Swoole驱动的多进程协程Web MVC框架
- Host: GitHub
- URL: https://github.com/watish/watishweb
- Owner: Watish
- License: mit
- Created: 2022-12-17T12:24:20.000Z (about 2 years ago)
- Default Branch: master
- Last Pushed: 2023-11-19T06:51:13.000Z (about 1 year ago)
- Last Synced: 2024-11-18T19:02:15.225Z (about 2 months ago)
- Topics: php, php-framework, php8, swoole-framework, swoole-http, swoole-websocket
- Language: PHP
- Homepage:
- Size: 20.8 MB
- Stars: 4
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Watish WEB
### 一个swoole驱动的多进程全协程的轻量Web框架
#### 技术栈
Swoole,PHP
#### 框架特点
+ 支持websocket
+ 通过UnixSocket异步实现多进程间的全局变量一致
+ 支持独立进程Process
+ 可动态添加,修改,删除的Crontab定时任务
+ 基于协程且生产可用的优雅异步回调Promise
+ 支持Task异步投递闭包任务
+ 支持路由注解,中间件注解,全局中间件注解,CLI命令注解
+ 支持AOP面向切片开发
+ 基于Swoole\Table的分块存储KV内存表#### 环境要求
+ PHP 8+
+ Swoole v5.0+### 快速开始
#### 使用Git
```shell
git clone https://github.com/Watish/WatishWEB
```#### 使用Composer
```shell
composer create-project watish/watishweb:dev-master
```### 启动项目
**项目的入口文件为 项目/bin/CoServer.php**
#### 使用[swoole-cli](https://github.com/swoole/swoole-cli) (推荐)
```shell
swoole-cli ./bin/CoServer.php
```#### 使用php(需安装swoole拓展)
```
php ./bin/CoServer.php
```### 目录结构
- bin/ 入口文件
- config/ 配置文件目录
- src/ 业务逻辑目录
- opt/ 项目工具类目录
- storage/ 存储目录
- Framework/ 用于存放项目生成文件,如代理类缓存
- View/ 用于存放视图文件(挖坑)
- vendor/ 组件目录
- tools/
- php-cs-fixer/
- vendor-bin/
- box/### 编写一个Hello World
在 **src/Controller**目录下新建一个类,这里我们定义为**HelloController**
```php
"hello world"
];
}
}
```保存后,启动项目,访问 http://127.0.0.1:9502/ 便能看到
```json
{"msg":"hello world"}
```是不是很简单 😜
### 注解 Attribute
- Inject 依赖注入,属性注解 Inject(string $class)
- Middleware 局部中间件,方法注解,类注解 Middleware(array $middlewares)
- GlobalMidlleware 全局中间件,类注解 GlobalMidlleware 无参数
- Asyc 异步执行,方法注解 Async 无参数
- Aspect 切片,方法注解 Aspect(string $class)
- Command 命令,类注解 Command(string $command , string $prefix)
- Crontab 定时任务,类注解 Crontab(string $rule)
- Process 独立进程,类注解 Process(string $name , int $worker_num =1)### 上下文管理 Context
不同于传统的php-fpm形式,**多进程之间存在内存隔离**,这意味着在进程A设定的变量进程B是无法获取的,此外,**请求与请求之间并不是隔离的**,也就是说,在同一进程下的两个请求,尽管在不同的协程中处理逻辑,如果都对全局变量A修改,那么全局变量会被修改两次
具体可查阅swoole文档中的 [**编程须知**#严重错误](https://wiki.swoole.com/#/coroutine/notice?id=%e4%b8%a5%e9%87%8d%e9%94%99%e8%af%af)
使用 **Watish\Components\Includes\Context** 可以有效规避上述问题
**Context**是一个静态类,不仅提供了简单的**Get**,**Set**方法,还通过进程通信提供了**多worker进程**全局变量的GlobalSet,GlobalGet等方法
注:多worker进程全局变量设定(Context::Global_Set等方法)是基于UnixSocket异步实现的,不能保证某一时刻的数据一致,这里可以使用 **Watish\Components\Utils\Table** ,一个对 **Swoole\Table** 的封装KV内存表,可以充分利用每一行资源,并支持闭包序列化
### 请求 Request
当浏览器发送请求至服务器,服务器会调用handle方法,随后通过路由调度器判断请求路由是否存在,存在解析路由参数,封装至 **Watish\Components\Struct\Request**,传入 **全局中间件 -> 局部中间件 -> 控制器**
### 路由 Route
注册路由的两种方式
##### 通过Prefix,Path注解注册
注:需要在 **/config/server.php **中修改 **register_route_auto **为 **true**
```php
...
"register_route_auto" => true
...
```**Prefix**是**类注解**,定义该类下路由的前缀
```php
#[Prefix(string $prefix)]
```**Path**是**方法注解**,定义路由路径
```php
#[Path(string $path,array $methods)]
```举个栗子:
```php
"hello world"
];
}#[Path('/user/{name}',['GET','POST'])]
#[Middleware([TestMiddleware::class])]
public function msg(Request $request) :array
{
return [
"msg" => "hello ".$request->route('name')
];
}
}
```上述代码的路由如下
| 路径 | 控制器 | 方法 | 中间件 |
|--------------------|-----------------------|----------|----------------|
| /hello/index | HelloController@index | ANY | 无 |
| /hello/user/{name} | HelloController@msg | GET,POST | TestMiddleware |##### 通过配置文件注册路由
路由配置文件路径为:项目/config/route.php
复用上面的栗子,则上述路由配置应如下
```php
register_global_middleware(CorsMiddleware::class);
*/
}function do_register_routes(Route $route): void
{
$route->register('/hello/index',[HelloController::class,'index'],[],[]);
$route->register('/hello/user/{name}',[HelloController::class,'msg'],[TestMiddleware:class],['GET','POST']);
}
```register方法传参如下
```php
Watish\Components\Includes\Route->register(string $path , array $callback , array $before_middlewares , array $methods )
```### 中间件 Middleware
注:中间件都要implement MiddlewareInterface接口
#### 全局中间件
**通过注解注册**
可以通过使用 **GlobalMiddleware** 的 **类注解** 实现全局中间件的注册
举个例子:
```php
header("Access-Control-Allow-Origin", "*");
$response->header("Access-Control-Allow-Credentials", true);
}
}
```**通过路由注册**
配置文件路径为:项目/config/route.php
```php
register_global_middleware(CorsMiddleware::class);
}function do_register_routes(Route $route): void
{
$route->register('/hello/index',[HelloController::class,'index'],[],[]);
$route->register('/hello/user/{name}',[HelloController::class,'msg'],[],['GET','POST']);
}
```#### 局部中间件
**通过注解注册**
可以使用 **Middleware** 来对**控制器**或者某个**方法**进行注解
```php
#[Middleware(array $middlewares)]
```先创建一个 **TestMiddleware**
```php
header("test","test");
}
}
```然后修改 **HelloController**
```php
"hello world"
];
}#[Path('/user/{name}',['GET','POST'])]
#[Middleware([TestMiddleware::class])]
public function msg(Request $request) :array
{
return [
"msg" => "hello ".$request->route('name')
];
}
}
```如上,index方法和msg方法都有了局部中间件 **TestMiddleware**
当然,上述代码还能一下这样写,直接给HelloController添加 **Middleware** 注解
```php
"hello world"
];
}#[Path('/user/{name}',['GET','POST'])]
public function msg(Request $request) :array
{
return [
"msg" => "hello ".$request->route('name')
];
}
}
```**通过配置文件注册**
参考路由章节中的配置文件路由注册方法 register 传参 ,此处不做赘述
### 控制器 Controller
控制器是整个业务项目的核心,负责处理请求,调用服务,返回数据
比较简单,不多描述
配合**依赖注入**,举个栗子:
```php
$this->baseService->toArray(["Hello",'World'])
];
}#[Path('/user/{name}',['GET','POST'])]
public function msg(Request $request) :array
{
return [
"msg" => "hello ".$request->route('name')
];
}
}
```注:暂不支持构造方法注入,后续会完善(挖坑)
### 服务 Service
直接贴代码
```php
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/Benchmarking 127.0.0.1 (be patient)
Server Software: swoole-http-server
Server Hostname: 127.0.0.1
Server Port: 9502Document Path: /hello/user/test
Document Length: 20 bytesConcurrency Level: 3000
Time taken for tests: 2.040 seconds
Complete requests: 30000
Failed requests: 0
Total transferred: 7680000 bytes
HTML transferred: 600000 bytes
Requests per second: 14708.19 [#/sec] (mean)
Time per request: 203.968 [ms] (mean)
Time per request: 0.068 [ms] (mean, across all concurrent requests)
Transfer rate: 3677.05 [Kbytes/sec] receivedConnection Times (ms)
min mean[+/-sd] median max
Connect: 0 83 17.3 85 125
Processing: 32 109 41.6 102 380
Waiting: 0 79 40.0 71 362
Total: 107 193 37.8 189 457Percentage of the requests served within a certain time (ms)
50% 189
66% 200
75% 205
80% 208
90% 224
95% 236
98% 344
99% 389
100% 457 (longest request)```
注:不要太在意性能,真正的业务逻辑往往是复杂的,对demo进行压测并不能表明什么(图个乐)
> 如果好用可以点个star,如果有问题请提issue,作者会积极维护
>
> 更新于2022-12-28 16:01### 常见问题
##### git clone下来之后怎么跑不了?
请先运行一遍composer install