必须显式传入ssl上下文参数并确保证书路径绝对、私钥无密码、verify_peer设为false,否则监听443端口也会触发err_ssl_protocol_error;需启用openssl扩展、workerman≥3.3.7,证书须为pem格式且fullchain.pem含私钥→域名证书→中间证书顺序。

Workerman配置SSL实现安全通信,必须显式传入SSL上下文参数并确保证书路径绝对、私钥无密码、verify_peer设为false,否则即使监听443端口也会触发ERR_SSL_PROTOCOL_ERROR,浏览器直接断连。
确认前提条件
检查PHP是否启用openssl扩展:运行php -m | grep openssl,无输出则需启用;确认Workerman版本≥3.3.7,低于此版本不支持原生SSL;证书文件(.pem或.crt + .key)必须已准备好,且为PEM格式。
【私钥不能带密码】,否则Workerman启动时静默卡死无报错。可用openssl rsa -in server.key -out server-no-pass.key去密。
生成自签名证书(开发测试用)
执行以下三条命令生成server.key和server.crt:
openssl genrsa -out server.key 2048
openssl req -new -key server.key -out server.csr(Common Name填localhost或测试域名)
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
注意:server.crt只含证书,不含私钥;生产环境请用Let's Encrypt等CA签发的fullchain.pem(含域名证书+中间证书),且务必把私钥合并进同一PEM文件或单独提供local_pk。
配置HTTPS服务
方法一:使用WebServer类(推荐,语义清晰)
第一步:引入Autoloader并实例化WebServer,协议写ssl://,端口建议443
第二步:构造时直接传入ssl_context数组,键名必须是ssl_context,不是context或ssl
第三步:指定local_cert为绝对路径的全链证书文件(含私钥+证书+中间证书),local_pk可省略——若私钥已包含在local_cert中;否则必须同时提供且路径为绝对路径
【verify_peer => false是硬性要求】,设为true会导致TLS握手失败,客户端连接立即重置。
示例代码:
$web = new WebServer('ssl://0.0.0.0:443', [
'ssl_context' => [
'local_cert' => '/var/www/ssl/fullchain.pem',
'local_pk' => '/var/www/ssl/privkey.pem',
'verify_peer' => false
]
]);
配置WSS服务(WebSocket over SSL)
方法一:Worker构造时传context + transport='ssl'
创建Worker实例时协议写websocket://0.0.0.0:443,同时传入context数组,其中ssl子数组与HTTPS配置一致
必须手动设置$worker->transport = 'ssl',否则仍是ws协议
方法二:直接用ssl://协议前缀(更简洁)
将协议改为ssl://0.0.0.0:443,再通过$worker->onMessage处理WebSocket帧即可,无需额外设transport
注意:微信小程序等客户端必须用wss://域名访问,且证书域名需匹配,localhost不可用自签名证书直连。
验证与排错
启动后执行php start.php start,无报错不代表成功。用curl验证:curl -I https://your-domain.com,返回200 OK且Header含HTTP/2或HTTP/1.1即通
若浏览器报ERR_CONNECTION_RESET,立刻检查:① local_cert路径是否绝对;② PHP进程用户(如www-data)对证书文件是否有读权限(ls -l看);③ 私钥是否被加密;④ fullchain.pem里私钥是否在最开头、顺序是否为私钥→域名证书→中间证书
用openssl x509 -in fullchain.pem -text -noout | head -20确认证书内容可读;用openssl rsa -in privkey.pem -check -noout验证私钥有效性。











