Csf
tcp framework based on swoole
Install / Use
/learn @ErosZy/CsfREADME
csf v0.11
a tcp server framework base on swoole
csf是一个参考了Codeigniter后基于swoole而编写的tcp框架,她定义了一套数据流规范,使得开发tcp服务像http服务一样简单
1. 基于AACM的数据流
为了让开发tcp像一般的http服务一样简单,csf参考了轻量级MVC框架Codeigniter并结合自身的需求规定了一套AACM(Analysis --> Action --> Controller --> Model)的数据流,其具体含义为:
- Analysis: 采用类似中间件的方式进行数据的解析操作
- Action: 对数据进行简单的处理,并分发给一个或多个Controller进行处理
- Controller: 控制层,作为业务相关逻辑的处理,与MVC中的Controller概念一致
- Model: 模型层,与MVC中的Model概念一致
2. 准备使用
在一般的tcp服务开发过程中,我们需要像编写http一样与前端确定接口,这些接口在tcp服务中我们称为协议,协议一般包含标识码与数据,例如,我们为了简便我们可以定义一个这样的协议:
标志号*用户ID*JSON数据
例如:
10001*1*{"data":{}}
确定下协议格式后我们就可以进行tcp服务的开发了
3. Analysis层
Analysis的作用主要是解析数据协议,其代码如下:
<?php
class DefaultAnalysis extends CoreAnalysis
{
// 必须实现process方法
public function process($data, &$stop)
{
$stop = true;
return [
"router" => 10001, //标志号,唯一区分
"data" => $data, //其余数据
];
}
}
?>
编写完成后你需要在application/config/router.php里面注册这个解析类
<?php
$config["analysis_routes"] = [
"DefaultAnalysis"
];
?>
analysis_routes允许注册多个解析类,csf会按照你的注册循序进行调用,若需要在某个调用后停止后续解析类的解析,只需将process方法里的$stop设置为true即可
4. Action层
Action的作用主要是获取Analysis解析的最终数据,并做简单处理后分发给一个或多个Controller,其代码如下:
<?php
class DefaultAction extends CoreAction
{
private $_actions = [
"receives/Welcome"
];
public function __construct()
{
foreach ($this->_actions as $val) {
$this->addTarget($val);
}
}
public function distribute(Array $params)
{
foreach ($this->_actions as $val) {
$this->setParams($val, $params);
}
$this->pub();
}
}
?>
同样的,action需要在application/config/router.php中的进行注册,格式为按照标志号=>调用类名的方式进行注册, 如下所示:
<?php
$config["receive_routes"] = [
10001 => "DefaultAction"
]
?>
5. Controller层
Controller层与传统的MVC中的Controller相同,用于业务逻辑的编写,一个Controller的代码大抵如下:
<?php
class Welcome extends CoreController
{
private $serv = null;
private $fd = null;
public function __construct()
{
parent::__construct();
$this->load->model('DefaultModel', 'defaultModel');
$this->load->library('Mcurl', 'mcurl');
}
public function process(Array $params)
{
$this->serv = $params["serv"];
$this->fd = $params["fd"];
// model load
$this->defaultModel->sayHello();
// library load
$this->mcurl->isEnable();
$this->serv->send($this->fd, "success\r\n");
}
}
由于csf参考了Codeigniter的实现,因此集成了Codeigniter的一些加载的常用方法:
- $this->load->library($name,$nickname,$params): $name:加载的库路径,$nickname:使用时的别名, $params:构造函数参(你可以参考CI文档library部分)
- $this->load->model($name,$nickname): $name: 模型路径(你可以参考CI文档model部分)
- $this->load->helper($name): $name: helper路径(你可以参考CI文档helper部分)
除此之外,csf也集成了swoole的task和taskawait方法创建了asyncTask和syncTask方法,其使用如下:
<?php
class Welcome extends CoreController
{
private $serv = null;
private $fd = null;
public function __construct()
{
parent::__construct();
}
public function process($data)
{
// 异步任务
$this->serv->task([
"data" => "async task",
"controller" => "AsyncTask",
"method" => "process"
]);
// 同步任务
$this->serv->taskwait([
"data" => "sync task",
"controller" => "SyncTask",
"method" => "process"
]);
$this->serv->send($this->fd,"success");
}
}
?>
关于task和taskawait的相关内容可以参考swoole的文档
6. Model层
Model层与传统的MVC中的Model相同,用来抽象模型,一个Model的实现大致如下:
<?php
class UserModel extends CoreModel
{
protected $_tableName = "tablexxx";
public function __construct()
{
parent::__construct();
}
public function findTokenById($id)
{
//something...
}
}
?>
具体的使用与Codeigniter一致,你可以参考CI文档Model的相关内容,但值得注意的是,Model也提供了load等相关方法,相关细节可以参考system/CoreModel和CoreController的实现
7. Composer与Library
csf会自动加载composer,大部分csf存在的library都只是composer相关库的wrapper而已,例如:
<?php
require_once BASEPATH . 'CoreHelper.php';
class Database
{
protected $_connection = null;
protected $_db = null;
public function __construct()
{
$database = CoreHelper::loadConfig("database", "database");
$dsn = "mysql:host=" . $database["host"] . ";dbname=" . $database["dbname"];
$user = $database["user"];
$password = $database["password"];
$this->_connection = new Nette\Database\Connection($dsn, $user, $password, ["lazy" => true]);
$cacheMemoryStorage = new Nette\Caching\Storages\MemoryStorage;
$structure = new Nette\Database\Structure($this->_connection, $cacheMemoryStorage);
$conventions = new Nette\Database\Conventions\DiscoveredConventions($structure);
$this->_db = new Nette\Database\Context($this->_connection, $structure, $conventions, $cacheMemoryStorage);
}
public function __destruct()
{
CoreHelper::logMessage('info', 'database destruct...');
$this->_connection->disconnect();
}
public function __call($method, $args)
{
$callable = array($this->_db, $method);
return call_user_func_array($callable, $args);
}
}
?>
若需要关闭自动的composer,你可以在config/config.php中找到相关配置进行关闭
8. 连接池的使用
csf自身不支持连接池,但推荐使用 https://github.com/swoole/php-cp
9. 压力测试
benchmark里面存放了压力测试相关的代码,你可以通过阅读并修改config.php相关数据后启动php run.php执行压力测试,测试结果如下:
#1核1G机器上 10worker 10task 上线操作压测
concurrency: 10000
request num: 50000
lost num: 0
success num: 50000
total time: 132.0
req per second: 378
one req use(ms): 2.641
Related Skills
node-connect
354.0kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
112.2kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
354.0kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
354.0kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
