Laravel Echo не слушает - PullRequest
0 голосов
/ 02 мая 2019

Я пытаюсь создать пост в реальном времени, используя Laravel с ReactJS и Pusher.Я был в состоянии создать события толкателя, и я мог видеть события, показывающие на сайте толкателя.Однако эхо Laravel не слушает событие, когда оно создается, и я не могу понять, почему или как заставить его слушать.

App \ Events \ PostCreated

<?php

namespace App\Events;

use App\Post;
use App\User;
use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;

class PostCreated implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public $post;
    public $user;

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

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

    /**
     * @return array
     */
    public function broadcastWith() {
        return [
            'post' => array_merge($this->post->toArray(), [
                'user' => $this->post->user,
            ]),
            'user' => $this->user,
        ];
    }
}

broadcasting.php

/*
    |--------------------------------------------------------------------------
    | Broadcast Connections
    |--------------------------------------------------------------------------
    |
    | Here you may define all of the broadcast connections that will be used
    | to broadcast events to other systems or over websockets. Samples of
    | each available type of connection are provided inside this array.
    |
    */

    'connections' => [

        'pusher' => [
            'driver' => 'pusher',
            'key' => getenv('PUSHER_APP_KEY'),
            'secret' => getenv('PUSHER_APP_SECRET'),
            'app_id' => getenv('PUSHER_APP_ID'),
            'options' => [
                'cluster' => getenv('PUSHER_APP_CLUSTER'),
                'encrypted' => true,
            ],
        ],

        'redis' => [
            'driver' => 'redis',
            'connection' => 'default',
        ],

        'log' => [
            'driver' => 'log',
        ],

        'null' => [
            'driver' => 'null',
        ],

    ],

.env

BROADCAST_DRIVER=pusher
CACHE_DRIVER=file
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120

PUSHER_APP_ID=757605
PUSHER_APP_KEY=4100ca8b118192fd01b2
PUSHER_APP_SECRET=41f43d23204a3c7ae2a7
PUSHER_APP_CLUSTER=ap1

bootstrap.js

/**
 * Echo exposes an expressive API for subscribing to channels and listening
 * for events that are broadcast by Laravel. Echo and event broadcasting
 * allows your team to easily build robust real-time web applications.
 */

import Echo from 'laravel-echo'

window.Pusher = require('pusher-js');

//const client = require('pusher-js');

//import 'pusher-js/node';

window.Echo = new Echo({
    broadcaster: 'pusher',
    key: '4100ca8b118192fd01b2',
    cluster: 'ap1',
    encrypted: true
});

channel.php

<?php

/*
|--------------------------------------------------------------------------
| Broadcast Channels
|--------------------------------------------------------------------------
|
| Here you may register all of the event broadcasting channels that your
| application supports. The given channel authorization callbacks are
| used to check if an authenticated user can listen to the channel.
|
*/

use Illuminate\Support\Facades\Auth;

Broadcast::channel('App.User.{id}', function ($user, $id) {
    return (int) $user->id === (int) $id;
});

Broadcast::channel('new-post', function ($user) {
    return Auth::check();
});

PostController

public function create(Request $request, Post $post) {
        $data = [];
        $video_data = [];
        if ($request->get('file')) {
            foreach ($request->get('file') as $file) {
                $name = md5(uniqid()) . '.' . explode('/', explode(':', substr($file, 0, strpos($file, ';')))[1])[1];
                $upload = Uploader::upload($file, array('public_id' => $name));
                array_push($data, $upload['secure_url']);
            }
        }
        if ($request->get('video')) {
            foreach ($request->get('video') as $file) {
                $name = md5(uniqid() . '.' . explode('/', explode(':', substr($file, 0, strpos($file, ';')))[1]))[1];
                $upload = Uploader::upload($file, array('public_id' => $name, 'resource_type' => 'video'));
                array_push($video_data, $upload['secure_url']);
            }
        }
        $image = !empty($data) ? json_encode($data) : null;
        $video = !empty($video_data) ? json_encode($video_data) : null;
        $body = $this->test_data($request->body);
        // create post
        $createdPost = $request->user()->posts()->create([
            'body' => $body,
            'image' => $image,
            'video' => $video
        ]);
        // broadcast
        broadcast(new PostCreated($createdPost, $request->user()))->toOthers();
        // return the response
        return response()->json($post->with('user')->find($createdPost->id));
    }

app.blade.php (Макет приложения)

<script>
        window.Laravel = <?php echo json_encode([
            'csrfToken' => csrf_token(),
            'user' => [
                'id' => Auth::check() ? Auth::user()->id : null,
                'following' => Auth::check() ? Auth::user()->following()->pluck('users.id') : null
            ],
        ]);
        ?>
    </script>

ReactJS (Frontend)

componentDidMount() {
        Echo.private('new-post').listen('PostCreated', (e) => {
            if (window.Laravel.user.following.includes(e.post.user_id)) {
                this.setState({ posts: [e.post, ...this.state.posts] });
            }
        });
        // this.interval = setInterval(()=>this.getPosts(), 10000);
    }

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

Событие создано, но оно не прослушивается.Что я делаю не так?

Ответы [ 2 ]

0 голосов
/ 05 мая 2019

Я смог понять это и заметил, что мне нужно продолжать выполнять следующую команду:

php artisan queue:listen
0 голосов
/ 03 мая 2019

попробуйте установить broadcastAs в своем классе событий и явно указать имя широковещания в ответной части.

App \ Events \ PostCreated

<?php

namespace App\Events;

class PostCreated implements ShouldBroadcast
{
    // other code
    public function broadcastAs()
    {
        return 'PostCreated';
    }
}

ReactJS (интерфейс)

componentDidMount() {
        Echo.private('new-post').listen('.PostCreated', (e) => {
            if (window.Laravel.user.following.includes(e.post.user_id)) {
                this.setState({ posts: [e.post, ...this.state.posts] });
            }
        });
        // this.interval = setInterval(()=>this.getPosts(), 10000);
    }

обратите внимание, что я использую .PostCreated (а не PostCreated ).По умолчанию, laravel имеет соглашение по имени трансляции.Я предпочитаю явный стиль программирования, поэтому я обычно устанавливаю broadcastAs для всех своих событий.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...