Workerman Manual
Workerman 不依赖于 php-fpm、apache、nginx 容器,这些容器做不到与客户端保持长连接。
Workerman 单个进程可以支持上万的并发连接,多进程则支持数十万的,甚至百万并发连接。
简单实例:http://doc3.workerman.net/getting-started/simple-example.html
一 使用 HTTP 协议对外提供 Web 服务;
二 使用 WebSocket 协议
三 直接使用 TCP 传输数据(不使用任何应用层协议)
测试:telnet 127.0.0.1 2347
curl -Ss http://www.workerman.net/check.php | php
PHP Version >= 5.3.3 [OK]
Extension pcntl check [OK]
Extension posix check [OK]
debug mode: php start.php start
daemon: php start.php start -d
stop: php start.php stop
restart: php start.php restart
reload: php start.php reload
status: php start.php status
kill: php start.php kill (version >= 3.2.2)
平滑重启,进程中最好不要保存用户相关的状态信息,即业务进程最好是无状态的,避免由于进程退出导致信息丢失。
主进程会向其中一个子进程发送安全退出(让对应进程处理完毕当前请求后才退出)信号,当这个进程退出后,主进程会重新创建一个新的子进程(这个子进程载入了新的PHP代码),然后主进程再次向另外一个旧的进程发送停止命令,这样一个进程一个进程的重启,直到所有旧的进程全部被置换为止。
请求周期差异
PHP在Web应用中一次请求过后会释放所有的变量与资源
WorkerMan开发的应用程序在第一次载入解析后便常驻内存,使得类的定义、全局对象、类的静态成员不会释放,便于后续重复利用
Workerman 目录结构
Workerman // workerman 内核代码
| — Connection // socket 连接相关
| | — ConnectionInterface.php // socket 连接接口
| | — TcpConnection.php // Tcp 连接类
| | — AsyncTcpConnection.php // 异步 Tcp 连接类
| | — UdpConnection.php // Udp 连接类
|
| — Events
| | — EventInterface.php // 网络事件库接口
| | — Libevent.php // Libevent 网络事件库
| | — Ev.php // libel 网络事件库
| | — Select.php // Select 网络事件库
|
| — Lib // 常用的类库
| | — Constants.php // 常量定义
| | — Timer.php // 定时器
|
| — Protocols // 协议相关
| | — ProtocolInterface.php // 协议接口类
| | — Http // http 协议相关
| | | — mime.types // mime 类型
| | — Http.php // http 协议实现
| | — Text.php // Text 协议实现
| | — Frame.php // Frame 协议实现
| | — Websocket.php // web socket 协议的实现
|
| — Worker.php // worker
|
| — WebServer.php // WebServer
|
| — Autoloader.php // 自动加载类
命名空间名字与目录路径对应,并以开发者的项目根目录为基准
普通函数及变量名采用小写加下划线方式
类成员及类的方法采用首字母小写的驼峰形式
函数及类的参数采用小写加下划线方式
<****监听地址****> ****可以为以下格式:
如果是unix套接字,地址为本地一个磁盘路径
非unix套接字,地址格式为 <本机ip>:<端口号>
<本机ip>可以为0.0.0.0表示监听本机所有网卡,包括内网ip和外网ip及本地回环127.0.0.1
<本机ip>如果以为127.0.0.1表示监听本地回环,只能本机访问,外部无法访问
<本机ip>如果为内网ip,类似192.168.xx.xx,表示只监听内网ip,则外网用户无法访问
<本机ip>设置的值不属于本机ip则无法执行监听,并且提示Cannot assign requested address错误
注意:<端口号>不能大于65535。<端口号>如果小于1024则需要root权限才能监听。监听的端口必须是本机未被占用的端口,否则无法监听,并且提示Address already in use错误
void Worker::listen(void)
用于实例化Worker后执行监听。
此方法主要用于在Worker进程启动后动态创建新的Worker实例,能够实现同一个进程监听多个端口,支持多种协议。
例如一个http Worker启动后实例化一个websocket Worker,那么这个进程即能通过http协议访问,又能通过websocket协议访问。由于websocket Worker和http Worker在同一个进程中,所以它们可以访问共同的内存变量,共享所有socket连接。可以做到接收http请求,然后操作websocket客户端完成向客户端推送数据类似的效果。
Workerman 两个重要类 Worker 与 Connection。
每个客户端连接对应一个 Connection 对象,可以设置对象的 onMessage、onClose 等回调。
也提供了向客户端发送数据 send 接口,关闭连接 close 接口,以及其他必要接口。
可以理解成,Worker 是一个监听容器,负责接收客户端连接,并把连接包装成 connection 对象,提供给开发者操作。
Workerman 是多进程的,每个进程内部维护一个自增的 connection_id,所以多进程之间的 connection_id 会有重复。
如果想要不重复的 connection_id,可以根据给 connection->id 重新赋值,如;加上 worker 前缀。
Connection 类
string Connectin::$protocol
设置当连接的协议类
use Workerman\Worker;
require_once ‘./Workerman/Autoload.php’;
$worker = new Worker(’tcp://0.0.0.0:8484’);
$worker->onConnect = function($connection)
{
$connection->protocol = ‘Workerman\Protocols\Https’;
};
$worker->onMessage = function($connection, $data)
{
// send 时会自动调用$connection->protocol::encode(),打包数据后再发送
$connection->send(“hello”);
};
Worker::runAll();
Connection::$worker,此属性为只读属性,即当前connection对象所属的worker实例
Connection::$maxSendBufferSize, 设置当前链接的应用层发送缓冲区大小。不设置默认为 Connection::$defaultMaxSendBufferSize (1 MB)
Connection::$defaultmaxSendBufferSize, 全局静态属性,设置所有链接的默认应用层发送缓冲区大小。默认为 1 M
Connection::$maxPackageSize, 全局静态属性,设置每个链接能够接收的最大包包长。默认为 10 M
回调属性
Connection::$onMessage
作用与 Worker::$onMessage 回调相同,区别是只针对当前链接有效。
$worker->onConnection = function($conncection)
{
$connection->onMessage = function($connection, $data)
{
$connection->send(‘receive success’);
}
}
// 一样的代码
$worker->onMessage = function($connection, $data)
{
$connection->send(‘receive success’);
}
Connection::$onclose
作用与 Worker::$onClose 回调相同,区别是只针对当前链接有效。
$worker->onConnect = function($connection)
{
$connection->onClose = function($connection)
{
echo “connection closed \n”;
};
};