如何在Apache中配置wss socket传输,解决PHP找不到该协议的报错
报错核心原因
PHP 原生 socket 流不存在wss传输协议,wss是WebSocket协议运行在TLS加密传输之上的统称,底层实际依赖的是tcp+ssl传输层能力,你代码中直接在stream_socket_server里填写wss://前缀,PHP无法识别对应的传输层实现,所以抛出该错误。
根据你的使用场景,可以选择以下两种方案解决:
场景1:用PHP自建WSS服务,不依赖Apache
- 第一步修正代码错误:
- 删掉
stream_context_create重复传入的第二个$opts参数,该参数仅在需要添加额外参数时使用,不需要重复传配置 - 将监听地址前缀从
wss://改为ssl://,同时指定监听端口
修正后的示例代码如下:
$opts = [ 'ssl' => [ 'cafile' => 'core/certs/root.pem', 'local_cert' => 'core/certs/client.pem', 'local_pk' => 'core/certs/client_key.pem', 'allow_self_signed' => true, // 自签证书测试时可以加这个参数,生产环境建议关闭 'verify_peer' => false // 测试环境可以关闭,生产环境建议开启 ] ]; $context = stream_context_create($opts); $socket = stream_socket_server( "ssl://$host:9501", // 替换为你要监听的端口 $errno, $errstr, STREAM_SERVER_BIND|STREAM_SERVER_LISTEN, $context ); - 删掉
- 第二步实现WebSocket协议逻辑:
上述代码仅能创建加密的TCP socket连接,你还需要自行实现WebSocket的握手、帧封装/解析逻辑,才能正常和WebSocket客户端通信。如果不想自行实现底层逻辑,可以直接使用Swoole、Workerman等成熟的PHP生态组件,二者都原生支持WSS服务,只需要简单配置证书即可启动,不需要手动处理socket底层逻辑。
场景2:用Apache做WSS反向代理,转发请求到PHP服务
如果你不想在PHP代码里处理SSL加密,可以用Apache做SSL卸载,对外提供WSS接口,内部转发到PHP运行的普通WS服务,配置步骤如下:
- 首先启用Apache所需模块:
如果你是Linux环境,执行如下命令启用模块:
如果你是Windows环境,修改Apache的a2enmod proxy proxy_wstunnel ssl rewrite systemctl restart apache2httpd.conf文件,去掉以下配置前的注释符号,之后重启Apache:LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so LoadModule ssl_module modules/mod_ssl.so LoadModule rewrite_module modules/mod_rewrite.so - 然后在Apache的SSL站点配置文件中添加反向代理规则:
假设你的PHP WebSocket服务监听在本机9501端口,对外暴露的路径为/ws,添加以下配置:ProxyPass "/ws" "ws://127.0.0.1:9501" ProxyPassReverse "/ws" "ws://127.0.0.1:9501" - 配置完成后重启Apache,客户端即可通过
wss://你的域名/ws访问到你的PHP WebSocket服务,SSL证书校验由Apache处理,不需要在PHP代码中配置证书参数。
内容的提问来源于stack exchange,提问作者mdBender
相关产品推荐
相关产品推荐

