TCP服务器
优质
小牛编辑
131浏览
2023-12-01
?> Swoole\Coroutine\Server
是一个完全协程化的类,用于创建协程TCP
服务器,支持TCP和unixSocket类型。
与Server模块不同之处:
- 动态创建销毁,在运行时可以动态监听端口,也可以动态关闭服务器
- 处理连接的过程是完全同步的,程序可以顺序处理
Connect
、Receive
、Close
事件
!> 在4.4以上版本中可用
短命名
可使用Co\Server
短名。
方法
__construct()
?> 构造方法。
Swoole\Coroutine\Server->__construct(string $host, int $port = 0, bool $ssl = false, bool $reuse_port);
参数
string $host
- 功能:监听的地址
- 默认值:无
- 其它值:无
int $port
- 功能:监听的端口【如果为0将由操作系统随机分配一个端口】
- 默认值:无
- 其它值:无
bool $ssl
- 功能:是否开启SSL加密
- 默认值:
false
- 其它值:
true
bool $reuse_port
- 功能:是否开启端口重用,效果和此节的配置一样
- 默认值:
false
- 其它值:
true
- 版本影响:Swoole >= v4.4.4
提示
$host 参数支持 3 种格式
0.0.0.0/127.0.0.1
: IPv4地址::/::1
: IPv6地址unix:/tmp/test.sock
: UnixSocket地址
异常
- 参数错误、绑定地址和端口失败、
listen
失败时将抛出Swoole\Exception
异常。
- 参数错误、绑定地址和端口失败、
set()
?> 设置协议处理参数。
Swoole\Coroutine\Server->set(array $options);
配置参数
- 参数
$options
必须为一维的关联索引数组,与 setprotocol 方法接受的配置项完全一致。
!> 必须在 start() 方法之前设置参数
长度协议
$server = new Swoole\Coroutine\Server('127.0.0.1', $port, $ssl); $server->set([ 'open_length_check' => true, 'package_max_length' => 1024 * 1024, 'package_length_type' => 'N', 'package_length_offset' => 0, 'package_body_offset' => 4, ]);
SSL证书设置
$server->set([ 'ssl_cert_file' => dirname(__DIR__) . '/ssl/server.crt', 'ssl_key_file' => dirname(__DIR__) . '/ssl/server.key', ]);
- 参数
handle()
?> 设置连接处理函数。
!> 必须在 start() 之前设置处理函数
Swoole\Coroutine\Server->handle(callable $fn);
参数
callable $fn
- 功能:设置连接处理函数
- 默认值:无
- 其它值:无
!> -服务器在
Accept
(建立连接)成功后,会自动创建协程并执行$fn
;
-$fn
是在新的子协程空间内执行,因此在函数内无需再次创建协程;
-$fn
接受一个参数,类型为Swoole\Coroutine\Server\Connection
对象。
-此对象提供了三个方法:
1.recv()
:接收数据,如果设置了协议处理,将每次返回完整的包
2.send($data)
:发送数据
3.close()
:关闭连接回调函数
function callback(Swoole\Coroutine\Server\Connection $conn) { while(true) { $data = $conn->recv(); } }
Socket 属性
可以读取
Connection::$socket
属性得到当前连接的Socket对象。可调用更多底层的方法,请参考 Swoole\Coroutine\Socket$socket = $conn->socket; $socket->getpeername();
shutdown()
?> 终止服务器。
?> 底层支持start
和shutdown
多次调用
Swoole\Coroutine\Server->shutdown(): bool;
start()
?> 启动服务器。
Swoole\Coroutine\Server->start(): bool;
返回值
- 启动失败会返回
false
,并设置errCode
属性 - 启动成功将进入循环,
Accept
连接 Accept
(建立连接)后会创建一个新的协程,并在协程中调用handle方法指定的函数
- 启动失败会返回
错误处理
- 当
Accept
(建立连接)发生Too many open file
错误、或者无法创建子协程时,将暂停1
秒然后再继续Accept
- 发生错误时,start()方法将返回,错误信息将会以
Warning
的形式报出。
- 当
完整示例
//多进程管理模块
$pool = new Swoole\Process\Pool(2);
//让每个OnWorkerStart回调都自动创建一个协程
$pool->set(['enable_coroutine' => true]);
$pool->on("workerStart", function ($pool, $id) {
//每个进程都监听9501端口
$server = new Swoole\Coroutine\Server('127.0.0.1', '9501' , false, true);
//收到15信号关闭服务
Swoole\Process::signal(SIGTERM, function () use ($server) {
$server->shutdown();
});
//接收到新的连接请求
$server->handle(function (Swoole\Coroutine\Server\Connection $conn) {
//接收数据
$data = $conn->recv();
if (empty($data)) {
//关闭连接
$conn->close();
}
//发送数据
$conn->send("hello");
});
//开始监听端口
$server->start();
});
$pool->start();
!> 如果在Cygwin环境下运行请修改为单进程。$pool = new Swoole\Process\Pool(1);