Codeigniter集成Firebase通知CURL代码偶发SSL连接错误求助
解决CodeIgniter中FCM推送偶发SSL_ERROR_SYSCALL问题
我碰到过不少类似的FCM推送偶发SSL连接故障,这种SSL_ERROR_SYSCALL通常和网络波动、CURL配置缺失或者服务器SSL环境有关,结合你的CodeIgniter场景,给你几个实用的排查和解决方向:
1. 优化CURL的SSL与超时配置
默认的CURL配置可能没有适配FCM的要求,你可以在请求中添加这些关键配置来提升稳定性:
// 初始化CURL $ch = curl_init('https://fcm.googleapis.com/fcm/send'); // 设置请求头(记得替换成你的FCM服务器密钥) $headers = [ 'Authorization: key=YOUR_FCM_SERVER_KEY', 'Content-Type: application/json' ]; curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); // 基础配置 curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($res)); // 关键SSL配置 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); // *生产环境请勿关闭,确保证书验证* curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2); // FCM要求TLS 1.2及以上版本 // 超时与重试(如果CURL版本支持) curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); // 连接超时10秒 curl_setopt($ch, CURLOPT_TIMEOUT, 20); // 总请求超时20秒 if (defined('CURLOPT_RETRY')) { curl_setopt($ch, CURLOPT_RETRY, 3); // 最多重试3次 curl_setopt($ch, CURLOPT_RETRY_DELAY, 1000); // 每次重试间隔1秒 } // 执行请求并捕获错误 $response = curl_exec($ch); if(curl_errno($ch)){ $error_msg = curl_error($ch); // 记录错误日志到CodeIgniter日志,方便后续排查 log_message('error', 'FCM推送CURL错误: ' . $error_msg); } curl_close($ch);
2. 检查服务器网络与SSL环境
偶发的连接错误可能是服务器网络不稳定导致的:
- 用
telnet fcm.googleapis.com 443或者curl -v https://fcm.googleapis.com测试服务器到FCM服务器的连通性,排查是否有防火墙临时拦截或路由波动 - 更新服务器的SSL证书库:
- CentOS系统执行:
yum update ca-certificates - Ubuntu/Debian系统执行:
apt-get install --reinstall ca-certificates
- CentOS系统执行:
3. 实现重试机制应对偶发故障
因为偶发的连接错误可以通过重试解决,你可以封装一个带重试逻辑的函数:
function send_fcm_with_retry($notification_data, $retry_times = 3) { $headers = [ 'Authorization: key=YOUR_FCM_SERVER_KEY', 'Content-Type: application/json' ]; $ch = curl_init('https://fcm.googleapis.com/fcm/send'); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($notification_data)); $response = curl_exec($ch); $error = curl_error($ch); curl_close($ch); // 如果有错误且还有重试次数,间隔1秒后重试 if ($error && $retry_times > 0) { log_message('warning', "FCM推送重试({$retry_times}),错误原因: {$error}"); sleep(1); return send_fcm_with_retry($notification_data, $retry_times - 1); } return $response; }
4. 验证JSON格式正确性
偶尔的错误也可能是JSON编码失败导致的,你可以添加编码验证:
$json_payload = json_encode($res); if (json_last_error() !== JSON_ERROR_NONE) { log_message('error', 'FCM推送JSON编码错误: ' . json_last_error_msg()); return; // 提前终止,避免无效请求 }
这些方法基本上能覆盖大部分偶发的SSL_ERROR_SYSCALL场景,核心是让CURL配置更适配FCM的要求,同时通过重试机制应对临时的网络故障。
内容的提问来源于stack exchange,提问作者Karthick Anbazhagan
相关产品推荐
相关产品推荐

