我试图在PHP中实现Fire and Forget,我使用以下代码(发现here):
$parts = parse_url($url);
try {
$socket = $this->openSocket($parts['host'], ($parts['port'] ?? $parts['scheme'] === 'https' ? 443 : 80));
} catch (Exception $e) {
$socket = null;
}
if (!$socket) {
return false;
}
$jsPostData = json_encode($postData, JSON_THROW_ON_ERROR);
$contentLength = strlen($jsPostData);
$request = "POST {$parts['path']} HTTP/1.1\r\n";
$request .= "Host: {$parts['host']}\r\n";
$request .= "Authorization: Bearer " . $bearerToken . "\r\n";
$request .= "Content-Length: {$contentLength}\r\n";
$request .= "Content-Type: application/json\r\n\r\n";
$request .= $jsPostData;
fwrite($socket, $request);
fclose($socket);
它的结果是这样一个请求:
POST /my_path HTTP/1.1
Host: my_url
Authorization: Bearer my_bearer_token
Content-Length: 263
Content-Type: application/json
{"event":"...."}
我得到的错误:
HTTP/1.1 400 Bad Request
Server: awselb/2.0
Date: Fri, 06 Oct 2023 09:43:17 GMT
Content-Type: text/html
Content-Length: 220
我不知道这是一个非常糟糕的请求还是权限失败。
更新
如果我使用这段代码与Guzzle它的作品:
try {
$guzzle = new Client();
$guzzle->post($url, [
'timeout' => 1,
'headers' => [
'Authorization' => "Authorization: Bearer " . $bearerToken,
],
'form_params' => $postData
]);
} catch (\GuzzleHttp\Exception\ConnectException $e) {
// do nothing, the timeout exception is intended
}
1条答案
按热度按时间disho6za1#
在套接字版本中,您显然发送了2个额外的头,这在Guzzle版本中不存在。同样在Guzzle中,您使用
form_params
选项来设置数据,根据文档,该选项将数据以form-url-encoded格式发送到服务器。然而在socket版本中,你发送的是JSON。您应该使基于套接字的查询发送form-url-encoded数据。这应该是可行的:
这将生成如下请求:
模拟:https://3v4l.org/SY6cp
其他参考材料: