异步风格

方便的创建一个异步服务器程序,支持 TCPUDPunixSocket 3 种 socket 类型,支持 IPv4 和 IPv6,支持 SSL/TLS 单向双向证书的隧道加密。使用者无需关注底层实现细节,仅需要设置网络事件的回调函数即可。

只是 Server 端的风格是异步的 (即所有事件都需要设置回调函数),但同时也是支持协程的,开启了 enable_coroutine 之后就支持协程了 (默认开启),协程下所有的业务代码都是同步写法。

TCP/UDP服务器

Swoole\Server 类是所有异步风格服务器的基类,Http\ServerWebSocket\ServerRedis\Server 都继承于它。

HTTP服务器

  • Http\Server 继承自 Server,所以 Server 提供的所有 API 和配置项都可以使用,进程模型也是一致的。
  • 内置 HTTP 服务器的支持,通过几行代码即可写出一个高并发,高性能,异步 IO 的多进程 HTTP 服务器。
  • 通过使用 Apache bench 工具进行压力测试,在 Inter Core-I5 4核 + 8G内存的普通 PC 机器上,Http\Server 可以达到近 11万QPS
  • 远远超过 PHP-FPMGolangNode.js 自带 Http 服务器。性能几乎接近与 Nginx 的静态文件处理。

使用 HTTP2 协议

  • 使用 SSL 下的 HTTP2 协议必须安装 openssl, 且需要高版本 openssl 必须支持 TLS1.2ALPNNPN
  • 编译时需要使用 –enable-http2 开启
./configure --enable-openssl --enable-http2

设置 HTTP 服务器的 open_http2_protocol 为 true

$server = new Swoole\Http\Server("127.0.0.1", 9501, SWOOLE_PROCESS, SWOOLE_SOCK_TCP | SWOOLE_SSL);
$server->set([
    'ssl_cert_file' => $ssl_dir . '/ssl.crt',
    'ssl_key_file' => $ssl_dir . '/ssl.key',
    'open_http2_protocol' => true,
]);

Nginx + Swoole 配置

由于 Http\Server 对 HTTP 协议的支持并不完整,建议仅作为应用服务器,用于处理动态请求,并且在前端增加 Nginx 作为代理。

server {
    root /data/wwwroot/;
    server_name local.swoole.com;

    location / {
        proxy_http_version 1.1;
        proxy_set_header Connection "keep-alive";
        proxy_set_header X-Real-IP $remote_addr; //通过读取 $request->header['x-real-ip'] 来获取客户端的真实 IP
        if (!-e $request_filename) {
             proxy_pass http://127.0.0.1:9501;
        }
    }
}

WebSocket服务器

WebSocket\Server通过内置的 WebSocket 服务器支持,通过几行 PHP 代码就可以写出一个异步 IO 的多进程的 WebSocket 服务器。

客户端

  • Chrome/Firefox/ 高版本 IE/Safari 等浏览器内置了 JS 语言的 WebSocket 客户端
  • 微信小程序开发框架内置的 WebSocket 客户端
  • 异步 IO 的 PHP 程序中可以使用 Swoole\Coroutine\Http 作为 WebSocket 客户端
  • Apache/PHP-FPM 或其他同步阻塞的 PHP 程序中可以使用 swoole/framework 提供的同步 WebSocket 客户端
  • 非 WebSocket 客户端不能与 WebSocket 服务器通信

如何判断连接是否为 WebSocket 客户端

通过使用 $server->connection_info($fd) 获取连接信息,返回的数组中有一项为 websocket_status,根据此状态可以判断是否为 WebSocket 客户端。

Redis服务器

Redis\Server,一个兼容 Redis 服务器端协议的 Server 类,可基于此类实现 Redis 协议的服务器程序。 Swoole\Redis\Server 继承自 Server,所以 Server 提供的所有 API 和配置项都可以使用,进程模型也是一致的。

可用的客户端

  • 任意编程语言的 redis 客户端,包括 PHP 的 redis 扩展和 phpredis 库
  • Swoole\Coroutine\Redis 协程客户端
  • Redis 提供的命令行工具,包括 redis-cliredis-benchmark

端口监听

Server 可以监听多个端口,每个端口都可以设置不同的协议处理方式,例如 80 端口处理 HTTP 协议,9507 端口处理 TCP 协议。SSL/TLS 传输加密也可以只对特定的端口启用。 ( 例如主服务器是 WebSocket 或 HTTP 协议,新监听的 TCP 端口(listen 的返回值,即 Swoole\Server\Port 对象,以下简称 port)默认会继承主 Server 的协议设置,必须单独调用 port 对象的 set 方法和 on 方法设置新的协议才会启用新协议。port 对象的 set 和 on 方法,使用方法与基类 Swoole\Server 完全一致。 )

协程风格

服务端协程风格

Swoole\Coroutine\Server 与 异步风格 的服务端不同之处在于,Swoole\Coroutine\Server 是完全协程化实现的服务器。

优点:

  • 不需要设置事件回调函数。建立连接、接收数据、发送数据、关闭连接都是顺序的,没有 异步风格 的并发问题。
  • 可以动态的开启关闭服务,异步风格的服务在 start() 被调用之后就什么也干不了了,而协程风格的可以动态开启关闭服务。

缺点:

  • 协程风格的服务不会自动创建多个进程,需要配合 Process\Pool 模块使用才能利用多核。
  • 协程风格服务其实是对 Co\Socket 模块的封装,所以用协程风格的需要对 socket 编程有一定经验。
  • 目前封装层级没有异步风格服务器那么高,有些东西需要自己手动实现,比如 reload 功能需要自己监听信号来做逻辑。

TCP服务器(在 4.4 以上版本中可用 )

Swoole\Coroutine\Server 是一个完全协程化的类,用于创建协程 TCP 服务器,支持 TCP 和 unixSocket 类型。 与 Server 模块不同之处:

  • 动态创建销毁,在运行时可以动态监听端口,也可以动态关闭服务器
  • 处理连接的过程是完全同步的,程序可以顺序处理 ConnectReceiveClose 事件

HTTP服务器(在v4.4.0 或更高版本可用 )

完全协程化的 HTTP 服务器实现,Co\Http\Server 由于 HTTP 解析性能原因使用 C++ 编写,因此并非由 PHP 编写的 Co\Server 的子类。与 Http\Server 的不同之处:

  • 可以在运行时动态地创建、销毁
  • 对连接的处理是在单独的子协程中完成,客户端连接的 ConnectRequestResponseClose 是完全串行的

WebSocket服务器( 在 v4.4.13 后可用 )

完全协程化的 WebSocket 服务器实现,继承自 Coroutine\Http\Server,底层提供了对 WebSocket 协议的支持。

最后修改日期:2021年5月29日

作者

留言

撰写回覆或留言

发布留言必须填写的电子邮件地址不会公开。