我的Laravel应用程序中有一个事件,对于特定记录,该事件超出Pusher允许的最大限制(10240字节)。 Laravel序列化Event类上的每个公共属性是否正确?如果是这样,我怀疑序列化模型不应超过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
答案 0 :(得分:2)
方法1:在客户端解决
@ExohJosh描述的是最可靠的方法:仅发送事件类型和ID,以便客户端(很可能是JavaScript)可以通过单独的REST(或其他)API来获取更新的记录。
public function broadcastWith()
{
return [
'id' => $this->post->id,
];
}
方法2:减少有效负载
另一种(更简单)的方法是仅发送客户端所需的数据(您自己发现的@sarotnem)。但是,只有在您绝对知道所提交的属性在任何情况下都不能超过10KiB限制的情况下,这种方法才是安全的。可以通过输入验证,数据库列限制或其他方式来确保这一点。
选择这种方法时,请确保在计算中也包括所有可能载入模型的关系的大小。
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,
];
}
}
答案 1 :(得分:1)
我过去在处理大型对象时采用的一种方法是考虑隔离大型对象或传递对象EG的引用:id,然后在事件侦听器中执行其他功能。
如果要更改帖子,可以采用以下方法:
该帖子已在客户端1上更改。
后端使推送程序知道帖子已更改并接收ID
推播到客户端2
客户端2正在监听并点击端点以按ID获取客户端
如果这种方法对您不起作用–您需要检查要序列化的对象在数据中是否存在任何冗余,如果传递的过多,则存在问题。
答案 2 :(得分:0)
经过大量的实验,我设法通过简单地取消$post->toArray()
产生的数组的一些不必要的值来使其工作。
我还注意到broadcastWith()
方法将有效载荷作为数组而不是序列化返回。