javascript - JavaScript EventSource 监听 Webhook 推送到 PHP 脚本
问题描述
我一直在寻找和试验,但我似乎无法弄清楚这一点。我将不胜感激。谢谢!
所以我有一个 Shopify 商店,我有一个 Webhook,当我进行销售时触发,这意味着它将销售的 JSON 数据推送到我服务器上的 PHP 脚本。现在,我正在让那个 PHP 脚本将相关数据插入数据库,并将该销售标记为“未读”。然后,我将有一个单独的 HTML/JavaScript 页面,我将单独运行该页面,每隔 10 秒左右轮询服务器以检查未读销售情况。还有一点,但这是一般的想法。它很笨重,我想对其进行现代化改造。
这是我一直在尝试但似乎无法正常工作的方法。
- 设置一个监听单独 PHP 脚本的 EventSource 页面。
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Sales Notification!</title>
</head>
<body>
<div id="widget">
<div id="notification_box"></div>
</div>
<script type="text/javascript">
if (!!window.EventSource) {
var source = new EventSource('alert_listener.php');
} else {
console.log("Window.EventSource fail!");
}
source.addEventListener('message', function(e) {
console.log(e.data);
}, false);
source.addEventListener('open', function(e) {
// Connection was opened.
}, false);
source.addEventListener('error', function(e) {
if (e.readyState == EventSource.CLOSED) {
// Connection was closed.
}
}, false);
</script>
</body>
</html>
当我做一些像这个例子这样简单的事情时,这实际上效果很好。无论如何,这是我的 PHP 代码,用于监听从 Websocket 发送的 JSON(其中一些代码由 Shopify 提供):
<?php
header("Content-Type: text/event-stream");
header("Cache-Control: no-cache");
error_reporting(0);
define('SHOPIFY_APP_SECRET', 'NOT_PUBLIC_HAR_HAR');
function verify_webhook($data, $hmac_header) {
$calculated_hmac = base64_encode(hash_hmac('sha256', $data, SHOPIFY_APP_SECRET, true));
return ($hmac_header == $calculated_hmac);
}
function sendMsg($id, $msg) {
echo "id: $id" . PHP_EOL;
echo "data: $msg" . PHP_EOL;
echo PHP_EOL;
ob_flush();
flush();
}
$hmac_header = $_SERVER['HTTP_X_SHOPIFY_HMAC_SHA256'];
$data = file_get_contents('php://input');
$verified = verify_webhook($data, $hmac_header);
while (1) {
if ($data !== "") {
sendMsg("test id", "Data: " . $data);
}
sleep(1);
}
?>
当我将数据从 Shopify 推送到这个 PHP 脚本时,第一个 JavaScript 示例应该正在监听这些数据,但没有任何反应。不是一回事。我不知道为什么。我不知道如何告诉 PHP 脚本说:“嘿!有订单进来了!Yo JavaScript,做点什么!” 然后 JavaScript 运行,“收到新订单!让我们做点什么!”
TLDR:
- Shopify 将 JSON 推送到 PHP 脚本(通过 webhook)
- 单独的 JavaScript 文件通过 EventSource 对象监听这个 PHP 脚本并做出相应的反应
- 我不能让它工作。请帮忙。
就这些。谢谢你。
解决方案
我在 Twitter 上看到了这个——不,这个可以回答。
首先,我必须承认我对 EventSource 不太熟悉 - 但据我所知,您正在使用一个脚本同时做两件事;获取 Shopify 数据并立即将其导出到 JS。但是,每个运行的 PHP 脚本都只有一个请求和响应上下文 - 在这种情况下,您一直在将数据回显到 Shopify。
您将需要两个端点:
- 第一个端点充当 Shopify 的 webhook (
shopify_webhook.php
) 的接收者。每次它接收到数据时,您都可以将其存储在数据库中以用于像 Redis 这样的即发即弃的操作,您可以在其中设置一个可能较低的 TTL。据我所知,Redis 也有队列——所以这可能是一个更好的方法。 - 第二个端点是您的事件源,它将传入队列条目流式传输到您的请求 JavaScript(即
shopify_eventsource.php
)。
这里的 Redis 只是一个建议 - 但无论如何,您必须使用中间存储才能将传入数据移动到另一个输出通道。您可以将所有这些写在一个 PHP 文件中,您可以在其中验证传入请求,以查看它是 Shopify 请求(和流)还是请求输出的 JavaScript 代码。但是,如果 Shopify 更改 API 或您自己的 JavaScript 接收者,使用两个端点并因此分离代码可能会使其更具可读性和可调整性。
TL;博士:
Shopify -> Your endpoint -> intermediate storage.
Intermediate storage -> your endpoint -(stream)> your javascript.
推荐阅读
- php - 如何使用 PHP 代码验证引导模式?
- javascript - 动态控制器未启动
- asp.net-mvc - 删除并上传新图像后显示旧图像
- ruby - 捕获 table_print 的输出
- reactjs - 如何使用 React 禁用 Tab 组件(Carbon 设计系统)
- excel - 有没有办法“真正”动态验证 VBA 中的两个不同的单元格值?
- c++ - 与在头文件中声明并在源文件中定义的外部数组链接时出现问题
- sql - 使用连接获取记录
- powershell - 为什么 PowerShell ISE 中的控制台不使用最新安装的 PowerShell 版本?
- apache-spark - apache-spark 中的交叉验证。如何创建参数网格?