从 Laravel 外部推送到 Laravel 队列 (NodeJS)

2024-02-13

我有一个 Laravel 5.3 安装作为纯 API 应用程序运行,需要从多个不同的应用程序进行连接。

一切都工作正常(毕竟我们谈论的是 Laravel :P),除了我不明白一件事:

我有一个 MQTT 服务器,它正在侦听来自多个设备的消息(无论是什么)。这些消息包含有关需要在后端调用的作业类和方法的信息。

我无法直接调用API,设备根本不支持这一点(他们支持,但这比使用MQTT传输数据要费力得多)。我的想法是将一个新作业推送到队列中,定义要调用哪个 Laravel 作业类(以及哪个方法)。问题是 JSON 序列化...

MQTT 服务器在 NodeJS 上运行,我的队列在 Redis 上运行。我记得 Taylor 在推文中提到,理论上可以序列化所需的 JSON 并从 Laravel 外部推送到队列,然后由 Laravel 处理作业。

有人知道如何解决这个问题吗?有没有关于 JSON 结构的文档?

我还应该提到这个解决方案NodeJS 推送队列,由 Laravel Worker 消耗 https://stackoverflow.com/questions/32720428/nodejs-push-queue-consumed-by-laravel-worker?rq=1不适合我。与上面的结果相同,作业被放置在队列中,但在没有被处理或抛出任何错误的情况下被丢弃。

Redis 中排队事件的示例数据结构如下所示:

"{\"job\":\"Illuminate\\\\Broadcasting\\\\BroadcastEvent\",\"data\":{\"event\":\"O:28:\\\"App\\\\Events\\\\NotificationEvent\\\":5:{s:7:\\\"\\u0000*\\u0000name\\\";s:12:\\\"notification\\\";s:4:\\\"data\\\";a:4:{s:4:\\\"testkey\\\";s:14:\\\"testval\\\";s:9:\\\"timestamp\\\";s:19:\\\"2017-02-24 11:07:48\\\";s:5:\\\"event\\\";s:12:\\\"notification\\\";s:5:\\\"class\\\";s:28:\\\"App\\\\Events\\\\NotificationEvent\\\";}s:10:\\\"\\u0000*\\u0000channel\\\";N;s:7:\\\"\\u0000*\\u0000user\\\";O:45:\\\"Illuminate\\\\Contracts\\\\Database\\\\ModelIdentifier\\\":2:{s:5:\\\"class\\\";s:8:\\\"App\\\\User\\\";s:2:\\\"id\\\";i:2;}s:6:\\\"socket\\\";N;}\"},\"id\":\"XuUKRTf8CTSdzaVgp2gRcvmxQqLcpBUG\",\"attempts\":1}"

基于该结构,我认为对象(需要序列化)应该类似于以下内容:

{
"job":"EventClass@method", //<-- Just a name
"data":{
    "event":"EventClass", //<-- Just a name
    "name":"EventName", //<-- Just a name
    "data":{
    "key":"value"
    "event":"EventName" //<-- Same as data.name
    "class":"EventClass@method" //<-- This is actually being called
    }
}

Laravel 实际放入队列的内容中还包含其他信息(例如时间戳、用户模型标识符等),但我认为这对于触发作业来说不是必需的。

数据需要在 JS 中序列化才能达到与 php 类似的输出连载() http://php.net/manual/en/function.serialize.php(或者更好的是,获得一个可以被 php 反序列化的字符串反序列化() http://php.net/manual/en/function.unserialize.php.

我通过 php-serialization NPM 模块实现了这一点(感谢西蒙·斯文森 https://stackoverflow.com/users/73744/simon-svensson),但 Laravel 仍然没有消耗该作业(已丢弃但未执行)

预先感谢您的任何帮助:)

编辑解决方案

感谢 Simon 的回答,这里是关于如何在 Javascript 中序列化作业数据并推送到 Laravel 队列(并让 Laravel 自动处理整个事情)的解决方案。

请注意,这是将队列与 Redis 一起使用的示例。当使用 Beanstalkd 或基于数据库的队列时,这可能看起来不同(或没有)。

这是我成功使用的代码:

var serialize,Class,job,jobUser,jobData,serialized,result;

serialize = require('php-serialization').serialize;
Class = require('php-serialization').Class;

job = new Class("App\\Events\\NotificationEvent");

job.__addAttr__("name","string","notification","string","protected");

jobData = new Class();
jobData.__addAttr__("testkey","string","testval","string");
jobData.__addAttr__("timestamp","string","2017-02-24 11:07:48","string");
jobData.__addAttr__("event","string","notification","string");
jobData.__addAttr__("class","string","App\\Events\\NotificationEvent","string");
job.__addAttr__("data","string",jobData,"array","public");

job.__addAttr__("channel","string",null,"null","protected");

jobUser = new Class("Illuminate\\Contracts\\Database\\ModelIdentifier")
jobUser.__addAttr__("class","string","App\\User","string","public");
jobUser.__addAttr__("id","string",2,"integer","public");
job.__addAttr__("user","string",jobUser,"object","protected");

job.__addAttr__("socket","string",null,"null","public");

serialized = serialize(job,"object");

result = {
    job:"Illuminate\\Broadcasting\\BroadcastEvent",
    data:{
        event:serialized
    },
    id:"XuUKRTf8CTSdzaVgp2gRcvmxQqLcpBUG",
    attempts:1
};

queue.rpush('queues:default',JSON.stringify(result));

我还没有弄清楚这个 ID 的确切用途,我成功地将作业推送到队列中,并且始终使用相同的 ID。我想如果你快速推送作业并且同时存储它们,这可能是一个问题。由于它是一个字符串,您可以将其替换为您喜欢的任何随机 ID(Laravel 生成的随机 ID 是 32 个字符,我认为保持这个长度是一个好主意)。

最初推送作业时,尝试次数应设置为 1。如果 Laravel 无法处理该作业,它会将其推回队列并增加尝试值。


首先,请注意,这是 Laravel 5.3 中基于数据库的队列中作业的格式。 Laravel 的新版本包含更改。

有效负载列应包含以下格式的 json 对象。工作 (...\\CallQueuedHandler@call) 在这种情况下可以进行硬编码。我相信 commandName 键仅用于显示目的。然而,命令键是更难的部分,它应该是一个有效的对象,反序列化() https://secure.php.net/manual/en/function.unserialize.php支持。看起来 npm 上有可用的软件包用于此目的,快速搜索出现php 序列化 https://www.npmjs.com/package/php-serialization.

{
    "job": "Illuminate\\Queue\\CallQueuedHandler@call",
    "data": {
        "commandName": "App\\Jobs\\MyJobClass",
        "command": "O:19:\"App\\Jobs\\MyJobClass\"... /* stuff */"
    }
}

您提供的 json 负载会产生以下对象。作业和数据密钥都很重要。

{
  "job": "Illuminate\\Broadcasting\\BroadcastEvent",
  "data": {
    "event": "O:28:\"App\\Events\\NotificationEvent\":5:{s:7:\"\u0000*\u0000name\";s:12:\"notification\";s:4:\"data\";a:4:{s:4:\"testkey\";s:14:\"testval\";s:9:\"timestamp\";s:19:\"2017-02-24 11:07:48\";s:5:\"event\";s:12:\"notification\";s:5:\"class\";s:28:\"App\\Events\\NotificationEvent\";}s:10:\"\u0000*\u0000channel\";N;s:7:\"\u0000*\u0000user\";O:45:\"Illuminate\\Contracts\\Database\\ModelIdentifier\":2:{s:5:\"class\";s:8:\"App\\User\";s:2:\"id\";i:2;}s:6:\"socket\";N;}"
  },
  "id": "XuUKRTf8CTSdzaVgp2gRcvmxQqLcpBUG",
  "attempts": 1
}

我认为有问题的部分是序列化对象。以更易于阅读的方式重新格式化(但完全破坏了它)......

O:28:"App\Events\NotificationEvent":5:{
    // protected $name = 'notification'
    s:7:" * name";s:12:"notification";

    // public $data = array(...)
    s:4:"data";a:4:{
        // 'testkey => 'testval'
        s:4:"testkey";s:14:"testval";

        // 'timestamp' => '2017-02-24 11:07:48';
        s:9:"timestamp";s:19:"2017-02-24 11:07:48";

        // 'event' => 'notification';
        s:5:"event";s:12:"notification";

        // 'class' => App\Events\NotificationEvent::class;
        s:5:"class";s:28:"App\Events\NotificationEvent";
    }

    // protected $channel = null;
    s:10:"\0*\0channel";N;

    // protected $user = (instance of ModelIdentifier)
    s:7:"\0*\0user";O:45:"Illuminate\Contracts\Database\ModelIdentifier":2:{
        // public $class = App\User::class;
        s:5:"class";s:8:"App\User";

        // public $id = 2;
        s:2:"id";i:2;
    }

    // public $socket = null;
    s:6:"socket";N;
}

这种格式揭示了这样一个事实:您的作业使用 SerializesModels 特征,它将模型的引用替换为包含类+标识符的简单条目,并将在 __wakeup 期间恢复它们。

我相信你的问题在于 json 和序列化格式的心理解析;你猜测的结构是......错误的。

接下来的步骤不会是猜测任何事情。 1. 复制您已拥有有效负载的此测试通知。只需复制粘贴即可。 (你可能需要更改id,我猜它是用于重复数据删除的。) 2. 使用 php-serialization 构建事件数据,并旨在构建与原始事件负载相同的内容。完全没有变化。 3. 如果到目前为止一切正常,请随意更改序列化事件数据以查看会发生什么。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从 Laravel 外部推送到 Laravel 队列 (NodeJS) 的相关文章

随机推荐

  • CSS如何修复元素随页面水平滚动而不是垂直滚动?

    我创建了一个示例来帮助解释 http jsfiddle net 9AUbj 1 http jsfiddle net 9AUbj 1 div Hello World div div div div div 我想要 你好世界 当用户水平滚动时随
  • 服务器端 Push in Rails

    我想使用 AJAX 在 Rails 中实现一个可扩展的聊天室 我从研究中得知 唯一的可扩展性是通过服务器端推送实现的 我的两个问题是 1 在一个相当高效的聊天服务器中 什么时候轮询会变得禁止 2 我真的不想使用Juggernaut 我不太了
  • ANCS 是否支持向多个 BLE 设备发送通知?

    多台设备与同一台 iPhone 配对 但只有一台设备收到 ANCS 通知 在装有 iOS 9 3 2 的 iPhone 6 上进行测试 我可以确认 ANCS 会向所有订阅它的设备发送通知 也就是说 当通过控制点请求通知属性时 iOS 并不关
  • 如何检查 uri 字符串是否有效

    如何检查 uri 字符串是否有效 可以将其提供给 Uri 构造函数 到目前为止 我只有以下内容 但出于明显的原因 我更喜欢一种不那么粗暴的方式 Boolean IsValidUri String uri try new Uri uri re
  • ngx-datatable动态设置列宽

    我将 ngx datatable 的列宽度存储在数据库中 我使用 AJAX 调用获取这些值 如何为数据表设置这些值 我尝试过的 设置 width 属性
  • php中的foreach循环问题

    这是我的一些代码 p 只是回显并添加换行符 foreach vanSteps as k gt reqInfo p k if van k p The key is the van continue continue continue if w
  • 在 python 张量流中打印生成器

    我正在尝试遵循tensor flow教程如此描述link https github com random forests tutorials blob master ep7 ipynb 我正在尝试按描述打印预测结果 print Predic
  • 样式输入类型=文件未按预期工作

    我正在为表单类型创建一个 css 模板 并希望为表单输入提供圆形边框 这适用于 type text 但不适用于 type file 用于文件上传 我究竟做错了什么 tempform input type text moz border ra
  • Sharepoint 维基

    好吧 我看过几个帖子mention其他一些关于不使用 SP wiki 的帖子 因为它们很糟糕 因为我们正在考虑创建我们的维基inSP 我需要知道为什么我们不应该让 6 名自动化开发人员组成的小组来记录各种自动化流程中的步骤以及必须不时进行的
  • 如何在图表中添加大括号?

    我想在R中制作如下图 如何绘制水平支撑 像这样的事情怎么样 plot c 0 1 c 0 1 text x 0 5 y 0 5 srt 90 cex 8 family Helvetica Neue UltraLight 根据您的目的进行调整
  • Socket.io + PhoneGap

    当我尝试使用时套接字IO https socket io with PhoneGap https phonegap com 我收到此错误 在 iOS 上应该支持 socket io Access Control Allow Origin 不
  • NSArray 填充 bool

    我正在尝试创建一个布尔值的 NSArray 请问我有多少人这样做 NSArray array NSArray alloc init array 0 YES 这对我不起作用 Thanks NSArray 不是 c 数组 您无法使用以下方式访问
  • ModelEntity.从 url 加载

    我有一个带有 AR 的屏幕 目前 usdz 3D 模型存储在应用程序本地 我们需要确保使用 get 请求接收它们 这是要检查的网址 https developer apple com augmented reality quick look
  • SQL 选择用字符串替换整数

    目标是将 SQL 查询中返回的整数值替换为该数字表示的 char 值 例如 标记为 Sport 的表属性被定义为 1 4 之间的整数值 1 篮球 2 曲棍球等 下面是数据库表 然后是所需的输出 数据库表 Player Team Sport
  • -webkit-transform 的替代方案:transformY?

    我正在创建一个 chrome 扩展 它在特定页面的顶部显示 iframe 该 iframe 被固定并放置在打开 body 标签之前 为了给这个 iframe 预留一个位置 我使用 CSS 向下移动主体 包括固定元素 webkit trans
  • AngularJS 中 !$pristine 与 $dirty 之间有什么区别

    最近我读了一些关于 angularJS 表单验证的教程 如下所示 p p 但我觉得 pristine and dirty是相等的 那么我可以使用下面的吗 p p 我认为这两个属性之间存在细微差别 这取决于您的用例 setDirty 将表单设
  • 如何获取node.js中的所有memcached数据?

    首先 我的目的是当用户关闭浏览器时用户会话数据应该过期 现在的问题是 我的服务器需要 memcached 才能正常工作 因此 我想从已关闭浏览器的 memcached 中删除该特定用户会话 我不想清除所有内存缓存 以便剩余用户的会话仍然存在
  • nvcc 和 NVIDIA-smi 显示的不同 CUDA 版本

    我对运行时显示的不同 CUDA 版本感到非常困惑which nvcc and nvidia smi 我在 ubuntu 16 04 上安装了 cuda9 2 和 cuda10 现在我将PATH设置为指向cuda9 2 所以当我跑步时 whi
  • 如何在 ASP.NET 应用程序中实现多语言服务器错误?

    我的 ASP NET Web 应用程序在 web config 中有以下部分
  • 从 Laravel 外部推送到 Laravel 队列 (NodeJS)

    我有一个 Laravel 5 3 安装作为纯 API 应用程序运行 需要从多个不同的应用程序进行连接 一切都工作正常 毕竟我们谈论的是 Laravel P 除了我不明白一件事 我有一个 MQTT 服务器 它正在侦听来自多个设备的消息 无论是