Laravel 事件超出 Pusher 允许的限制

Laravel Event exceeds Pusher allowed limit

我的 Laravel 应用程序中有一个事件,对于特定记录,它超过了 Pusher 允许的最大限制(10240 字节)。 Laravel 序列化事件 class 上的每个 public 属性是否正确?如果是这样,我怀疑序列化模型不应超过 10kb 的限制,但无论如何它都会失败。有什么方法可以减少数据内容的大小吗?

class PostChanged implements ShouldBroadcast
{

 use Dispatchable, InteractsWithSockets, SerializesModels;

 public $post;

 /**
  * Create a new event instance.
  *
  * @return void
  */
  public function __construct(Post $post)
  {
    $this->post = $post;
  }

  /**
  * Get the channels the event should broadcast on.
  *
  * @return \Illuminate\Broadcasting\Channel|array
  */
  public function broadcastOn()
  {
    return new Channel('post-channel.'.$this->post->id);
  }

  public function broadcastWith()
  {
    $extra = [
      'data' => $this->post->data,
    ];

    return array_merge($this->post->toArray(), $extra);
  }
}

产生:

The data content of this event exceeds the allowed maximum (10240 bytes). 
See http://pusher.com/docs/server_api_guide/server_publishing_events for more info

我过去在处理大对象时采用的一种方法是考虑隔离大对象或传递对象 EG 的引用:id,然后在事件侦听器中执行附加功能。

post 更改的方法可能是:

客户端 1 上的 post 已更改。

后端让推送器知道 post 已更改并接收 id

Pusher 向客户端 2 广播

客户端 2 正在侦听并点击端点以通过 id

获取客户端

如果这种方法对你不起作用 – 你需要检查你正在序列化的对象是否有任何数据冗余,如果你传递的太多,就会有问题。

经过大量试验后,我设法通过简单地取消设置由 $post->toArray() 生成的数组的一些不必要的值来使其工作。

我还注意到 broadcastWith() 方法 returns 有效载荷作为数组而不是序列化。

方法一:在客户端解决

最可靠的方法是@ExohJosh 所描述的:仅发送事件类型和 ID,以便客户端(很可能 JavaScript)可以通过单独的 REST(或其他)获取更新的记录API.

public function broadcastWith()
{
    return [
        'id' => $this->post->id,
    ];
}

方法 2:减少负载

另一种(更简单的)方法是仅发送客户端所需的数据(您自己弄清楚的数据@sarotnem)。然而,这种方法只是安全的,前提是您明确知道您提交的属性在任何情况下都不能超过 10KiB 的限制。这可以通过输入验证、数据库列限制或其他方式来确保。

选择此方法时,请务必将可能加载到模型上的任何关系的大小也包括在您的计算中。

定义模型 "external representation" 的一种巧妙方法是 Laravel 的 API Resources。他们可以让您的代码看起来像这样:

public function broadcastWith()
{
    return [
        'post' => new \App\Http\Resources\PostResource($this->post),
    ];
}

其中 App\Http\Resources\PostResource 可能是:

class PostResource extends JsonResource
{
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'title' => $this->title,
            'body' => $this->body,
        ];
    }
}