Событие Laravel превышает допустимый предел Pusher - PullRequest
0 голосов
/ 03 июля 2018

В моем приложении Laravel есть событие, которое для определенных записей превышает максимально допустимый предел (10240 байт) Pusher. Правильно ли, что Laravel сериализует каждый открытый атрибут в классе Event? Если это так, я подозреваю, что сериализованная модель не должна превышать предел 10 КБ, но в любом случае это не удается. Есть ли какие-либо подходы для уменьшения размера содержимого данных?

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

Ответы [ 3 ]

0 голосов
/ 03 июля 2018

После долгих экспериментов мне удалось заставить его работать, просто сбросив некоторые ненужные значения массива, созданного $post->toArray().

Также я заметил, что метод broadcastWith() возвращает полезную нагрузку в виде массива и не сериализуется.

0 голосов
/ 03 июля 2018

Подход 1: разрешение на стороне клиента

Наиболее надежным подходом было бы то, что описал @ExohJosh: отправлять только тип события вместе с идентификатором, чтобы клиент (наиболее вероятный JavaScript) мог получить обновленную запись через отдельный REST (или любой другой) API.

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

Подход 2: Сокращение полезной нагрузки

Альтернативным (и более простым) подходом будет отправка только тех данных, которые требуются клиенту (те, которые вы выяснили сами @sarotnem). Однако этот подход безопасен только в том случае, если вы точно знаете, что отправляемые вами атрибуты ни в коем случае не могут превышать ограничение в 10 КБ. Это может быть обеспечено путем проверки входных данных, ограничений на столбцы БД или других средств.

При выборе этого подхода обязательно учитывайте размер любых отношений, которые могут быть загружены в модель, в ваши расчеты.

Хороший способ определить «внешнее представление» модели - это Ресурсы API Laravel. Они могут сделать ваш код похожим на это:

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,
        ];
    }
}
0 голосов
/ 03 июля 2018

Подход, который я использовал в прошлом при работе с большими объектами, состоит в том, чтобы рассмотреть сегрегацию большого объекта или передать ссылку на объект EG: идентификатор, а затем выполнить дополнительные функции в прослушивателе событий.

Подход в случае смены поста может быть следующим:

Сообщение изменено на клиенте 1.

Backend позволяет толкателю узнать, что сообщение изменилось, и получает идентификатор

Pusher передает клиенту 2

клиент 2 прослушивает и достигает конечной точки, чтобы получить клиента по идентификатору

Если этот подход не сработает для вас - вам нужно проверить, есть ли у сериализуемого объекта какие-либо избыточности в данных, если вы передаете слишком много, есть ли проблема там.

...