Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Workerman

TinyPHP 兼容版 Workerman 风格网络框架。(以下内容仅供参考)

简介

tphp-Workerman 是为 TinyPHP(AOT 编译器)设计的网络应用框架,API 风格借鉴 PHP 生态成熟的 Workerman,但完全遵循 TinyPHP 的 AOT 编译约束。

支持的能力:

  • ✅ TCP 服务器(TcpServer)
  • ✅ HTTP/1.1 服务器(HttpServer)
  • ✅ WebSocket 服务器(WebSocketServer,RFC 6455)
  • ✅ SSL/TLS 服务器(SslServer,基于 mbedTLS)
  • ✅ 多进程模型(ProcessManager,基于 pcntl_fork)
  • ✅ 事件循环(EventLoop,基于 stream_select)
  • ✅ 定时器(Timer)
  • ✅ 线程池(ThreadPool,基于 TinyPHP 内置 Thread)

不支持(因 AOT 约束):

  • ❌ 协程(无 PHP Fiber/Swoole/Swow,用 Thread 替代)
  • ❌ 动态属性赋值(回调通过构造函数传入)
  • ❌ 静态属性配置(用实例方法替代)
  • ❌ 运行时协议切换(协议由类决定)
  • ❌ HTTP keep-alive(简化为 HTTP/1.0 短连接)
  • ❌ HTTP/2、HTTP/3

与 Workerman 原版的 API 差异

由于 AOT 约束,tphp-Workerman 的 API 与 Workerman 原版存在以下差异:

特性 Workerman 原版 tphp-Workerman
回调注册 $worker->onMessage = function() {...} new HttpServer($addr, $count, function() {...})
协程支持 Coroutine::create(function() {...}) ThreadPool::submit(function() {...})
协议切换 new Worker('http://0.0.0.0:8080') 字符串决定 new HttpServer("0.0.0.0:8080", ...) 类决定
事件循环切换 Worker::$eventLoopClass = Swoole::class 不需要(只有 stream_select 一种)
全局入口 Worker::runAll() 静态方法 $worker->runAll() 实例方法
自动加载 require_once 'vendor/autoload.php' #import ../all 编译期引入

安装与编译

前置要求

  • TinyPHP 编译器(php tphp.php)
  • PHP 8.1+ 语法(TinyPHP 支持的子集)
  • POSIX 系统(Linux/macOS)用于多进程(Windows 降级为单进程)
  • TinyPHP 扩展:pcntl、posix、stream、openssl(已内置)

编译示例

tphp .

运行

编译后生成可执行文件,直接运行:

./tcp_echo       # 监听 0.0.0.0:9000
./http_server    # 监听 0.0.0.0:8080

快速开始

TCP echo 服务器

<?php
#import ../all

use TphpWorker\Worker;
use TphpWorker\Server\TcpServer;
use TphpWorker\Connection\TcpConnection;

class Main {
    public function main(): void {
        $worker = new Worker();
        $server = new TcpServer(
            "0.0.0.0:9000",
            1,
            function(TcpConnection $conn, string $data) {
                $conn->send("echo: " . $data);
            }
        );
        $worker->addServer($server);
        $worker->runAll();
    }
}

HTTP 服务器

<?php
#import ../all

use TphpWorker\Worker;
use TphpWorker\Server\HttpServer;
use TphpWorker\Connection\HttpConnection;
use TphpWorker\Protocol\Request;

class Main {
    public function main(): void {
        $worker = new Worker();
        $server = new HttpServer(
            "0.0.0.0:8080",
            4,  // 4 个工作进程
            function(HttpConnection $conn, Request $req) {
                if ($req->path === "/") {
                    $conn->send("Hello World");
                } else {
                    $conn->sendStatus(404);
                    $conn->send("Not Found");
                }
            }
        );
        $worker->addServer($server);
        $worker->runAll();
    }
}

WebSocket 服务器

<?php
#import ../all

use TphpWorker\Worker;
use TphpWorker\Server\WebSocketServer;
use TphpWorker\Connection\HttpConnection;

class Main {
    public function main(): void {
        $worker = new Worker();
        $server = new WebSocketServer(
            "0.0.0.0:8081",
            2,
            function(HttpConnection $conn, string $msg) use ($worker) {
                // 广播给所有连接
                $server = $worker->servers[0];
                $server->pool->each(function(HttpConnection $client) use ($msg, $server) {
                    if (!$client->closed && $client->websocketMode) {
                        $server->wsSend($client, $msg);
                    }
                });
            }
        );
        $worker->addServer($server);
        $worker->runAll();
    }
}

API 速查

Worker

顶层入口,管理多个 Server 实例。

$worker = new Worker();
$worker->addServer(TcpServer $server): void
$worker->runAll(): void  // 启动所有服务器并进入事件循环
$worker->stop(): void    // 请求停止

TcpServer

TCP 服务器基础类。

$server = new TcpServer(
    string $address,        // "0.0.0.0:9000" 或 "tcp://0.0.0.0:9000"
    int $processCount,      // 工作进程数
    callable $onMessage     // function(TcpConnection $conn, string $data)
);

// 可选回调(通过 setter 设置,默认为空操作)
$server->setOnConnect(callable $cb);  // function(TcpConnection $conn)
$server->setOnClose(callable $cb);    // function(TcpConnection $conn)
$server->setOnError(callable $cb);    // function(TcpConnection $conn, string $msg)

注:TinyPHP 不允许 callable 参数有默认值,因此可选回调通过 setter 方法设置,而非构造函数默认参数。

HttpServer

HTTP 服务器,继承 TcpServer。

$server = new HttpServer(
    string $address,
    int $processCount,
    callable $onMessage,    // function(HttpConnection $conn, Request $req)
    ...
);

WebSocketServer

WebSocket 服务器,继承 HttpServer。

$server = new WebSocketServer(
    string $address,
    int $processCount,
    callable $onMessage,    // function(HttpConnection $conn, string $msg)
    ...
);
$server->wsSend($conn, string $msg): void  // 发送 WebSocket 帧

SslServer

SSL/TLS 服务器,继承 TcpServer。

$server = new SslServer(
    string $address,
    int $processCount,
    callable $onMessage,
    ...
);
$server->setCertificate(string $certPath, string $keyPath): void

EventLoop

事件循环,基于 stream_select。

$loop = new EventLoop();
$loop->onReadable(int $fd, callable $cb): void
$loop->offReadable(int $fd): void
$loop->onWritable(int $fd, callable $cb): void
$loop->offWritable(int $fd): void
$loop->addTimer(float $interval, callable $cb): int       // 一次性
$loop->addRepeatTimer(float $interval, callable $cb): int  // 重复
$loop->delTimer(int $id): void
$loop->run(): void
$loop->stop(): void

Timer

高级定时器 API。

Timer::add(EventLoop $loop, float $interval, callable $cb): int      // 一次性
Timer::tick(EventLoop $loop, float $interval, callable $cb): int     // 重复
Timer::del(EventLoop $loop, int $id): void

TcpConnection / HttpConnection

$conn->send(string $data): int
$conn->close(): void
$conn->getRemoteAddress(): string  // "addr:port"

// HttpConnection 额外方法:
$conn->sendStatus(int $code): void
$conn->sendHeader(string $name, string $value): void

ConnectionPool

$pool->add(TcpConnection $conn): void
$pool->remove(TcpConnection $conn): void
$pool->count(): int
$pool->each(callable $cb): void  // 遍历所有连接,用于广播

Request

$req->method   // "GET"、"POST" 等
$req->path     // "/foo/bar"
$req->uri      // "/foo/bar?baz=1"
$req->headers  // array, key 小写
$req->query    // array,查询字符串
$req->post     // array,表单 body
$req->json     // mixed,JSON body
$req->body     // string,原始 body
$req->header(string $name): string  // 大小写不敏感取头
$req->isMethod(string $method): bool

ProcessManager

$pm = new ProcessManager();
$pm->fork(int $count, callable $worker): void  // function(int $index)
$pm->wait(callable $onChildExit): void   // function(int $index, int $status),必传(无需处理异常退出时传空闭包)
$pm->terminateAll(): void
$pm->childCount(): int

ThreadPool

$pool = new ThreadPool(int $size = 4);
$pool->submit(callable $task): void
$pool->shutdown(): void

已知限制

  1. 无协程支持:TinyPHP 无 PHP Fiber/Swoole/Swow,用 ThreadPool 替代并发场景
  2. HTTP/1.0 短连接:每个请求响应后关闭连接,不支持 keep-alive
  3. Windows 降级模式:Windows 无 pcntl,多进程降级为单进程 + Thread
  4. 信号处理简化:由于 ext/pcntl 无 pcntl_signal,采用 EventLoop 周期性检查停止标志(延迟 ≤ 1 秒)
  5. WebSocket 分片重组简化:MVP 版本每帧都触发回调,非 RFC 6455 标准的 fin=1 时才合并
  6. SSL 握手阻塞:TLS 握手采用临时阻塞模式,握手期间阻塞当前进程
  7. 无运行时协议切换:协议由类决定(HttpServer/WebSocketServer/SslServer)
  8. 无文件监控自动 reload:需手动重启进程

目录结构

tphp-src/
├── README.md                 # 本文件
├── bootstrap.php             # 框架引导文件(扩展依赖)
├── all.php                   # 聚合文件(引入所有组件)
├── Worker.php                # 顶层入口
├── Server/
│   ├── TcpServer.php
│   ├── HttpServer.php
│   ├── WebSocketServer.php
│   └── SslServer.php
├── Event/
│   ├── EventLoop.php
│   └── Timer.php
├── Connection/
│   ├── TcpConnection.php
│   ├── ConnectionPool.php
│   └── HttpConnection.php
├── Protocol/
│   ├── Request.php
│   ├── Http.php
│   ├── Frame.php
│   └── WebSocket.php
├── Process/
│   ├── ProcessManager.php
│   └── SignalHandler.php
├── Concurrent/
│   └── ThreadPool.php
└── examples/
    ├── tcp_echo.php
    ├── http_server.php
    ├── websocket_chat.php
    ├── ssl_https.php
    └── certs/
        └── README.md         # 证书生成说明

AOT 约束

tphp-Workerman 严格遵循 TinyPHP AOT 编译约束:

  • ✅ 无动态属性(回调通过构造函数传入)
  • ✅ 无 static 属性存储状态(用实例属性或常量)
  • ✅ 无 ?Type 可空类型(用 mixed + null 检查)
  • ✅ 无 ...$args 可变参数(用 array 替代)
  • ✅ 无 call_user_func(用 $cb(...) 直接调用)
  • ✅ 无 __call/__get/__set 魔术方法
  • ✅ 无 include/require(用 #import 替代)
  • ✅ 无 eval$$var、动态属性
  • ✅ 无 WeakMap(用 array + 显式 unset)
  • ✅ 无 Closure::fromCallable/bind/call
  • ✅ 无 protected 可见性(只用 publicprivate)
  • catch 仅捕获 Exception(不捕获 Throwable)
  • ✅ 所有属性显式声明类型并有默认值
  • ✅ 所有方法显式声明返回类型
  • ✅ 协议分发用 match 表达式或具体类继承(非接口多态)

License

MIT

About

workerman 功能模拟项目,仅做功能模拟。

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages