Laravel Reverb не транслирует REST API с помощью Docker

Мое приложение Laravel 11 ничего не транслирует с помощью Laravel Reverb. Я использую специальную конфигурацию Docker для развертывания своей среды, а Laravel действует как REST API, взаимодействующий с автономным интерфейсом React.

Мой файл reverb.php в каталоге config/ нетронут, поскольку я только что обновил файл .env.

BROADCAST_CONNECTION=reverb
    
REVERB_APP_ID=12345
REVERB_APP_KEY=MYVERYSECRETKEY
REVERB_APP_SECRET=SUPERSECRET
REVERB_HOST = "localhost"
REVERB_PORT=9090
REVERB_SCHEME=http

В файле broadcasting.php этот драйвер установлен в качестве драйвера, насколько я понимаю, Laravel Reverb запускает собственную конфигурацию reverb.php.

'default' => env('BROADCAST_DRIVER', 'null'),

При запуске php artisan queue:listen в контейнере Docker я вижу, как запускаются события и все работает как надо...

Когда я бегу php artisan channel:list, я вижу channel_for_everyone

При работе в контейнере Docker php artisan reverb:start --debug я вижу некоторые журналы ping.

Connection Established ............ 310096377.635725104  
Message Handled ................... 475763427.215883647  
Message Received .................. 726544741.227378338  
      
{ 
 "event": "pusher:ping", 
 "data": [] 
}

С интерфейсом на вкладке «Сеть» снова все выглядит нормально, он пингует /broadcasting/auth и мою настройку ws://localhost:9090/app/

Request URL: http://localhost:8000/broadcasting/auth
Request Method: POST
Status Code: 200 OK
Remote Address: [::1]:8000
Referrer Policy: strict-origin-when-cross-origin

Request URL: ws://localhost:9090/app/MYVERYSECRETKEY?protocol=7&client=js&version=8.4.0-rc2&flash=false
Request Method: GET OK
Status Code: 101 Switching Protocols

Само соединение вроде в порядке? Следует отметить одну вещь: если я доберусь до конечной точки, чтобы запустить событие, я не увижу журналов широковещательной рассылки php artisan reverb:start --debug

Мое событие, которое на данный момент является действительно простым и перехватывается и регистрируется при запуске queue:listen, но никогда не транслируется, хотя метод broadcastOn() срабатывает, и я могу его поймать с помощью dd()

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

    public function __construct(
    ) {
    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return \Illuminate\Broadcasting\Channel|array
     */
    public function broadcastOn()
    {
        //dd('inside broadcaseOn() in Event'); <- Gets here
        return [
            new PrivateChannel('channel_for_everyone'), // can see value of channel
        ];
    }
}

Даже если я сделаю канал не приватным, я все равно ничего не получу!

public function broadcastOn()
{
    return [
        new Channel('channel_for_everyone'),
    ];
}

в моем channels.phpdd() внутри channel_for_everyone никогда не попадает, но файл загружается на 100%, как когда я dd() выше, это будет dd('it will hit here!);

dd('it will hit here!);
    
Broadcast::channel('channel_for_everyone', function ($user) {
  dd('callback hit for channel_for_everyone', $user); // Will not hit
  return true;
});

Мой код React очень простой, я создал перехватчик для выполнения, и он регистрирует успешное соединение, просто ни одно событие не регистрируется.

const useLaravelEcho = () => {
    useEffect(() => {
        console.info('Initialising Echo...');

        const pusher = Pusher; // we need to make an instance

        const echoConfig = new Echo({
            broadcaster: 'reverb',
            key: import.meta.env.VITE_REVERB_APP_KEY,
            wsHost: import.meta.env.VITE_REVERB_HOST,
            wsPort: import.meta.env.VITE_REVERB_PORT,
            forceTLS: (import.meta.env.VITE_REVERB_SCHEME ?? 'https') === 'https',
            enabledTransports: ['ws', 'wss'],
            authEndpoint: import.meta.env.VITE_AUTH_ENDPOINT,
        });

        // Listen for successful connection
        echoConfig.connector.pusher.connection.bind('connected', () => {
            console.info('Successfully connected to Echo server.');
        });

        // Listen for connection errors
        echoConfig.connector.pusher.connection.bind('error', (error: any) => {
            console.error('Error connecting to Echo server:', error);
        });

        console.info('Subscribing to channel...');
        echoConfig.private('channel_for_everyone')
            .listen('CommentCreatedEvent', (event: any) => {
                console.info('Event received:', event);
            });
    }, []);
};

export default useLaravelEcho;

Когда я проверяю консоль в браузере:

Initialising Echo...
useLaravelEcho.ts:32 Subscribing to channel...
useLaravelEcho.ts:24 Successfully connected to Echo server.

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

Есть ли у кого-нибудь идеи?

Отредактировали ли вы allowed_origins в файле конфигурации реверберации, чтобы добавить свой хост, или вы можете разрешить все источники, используя *?

Maraboc 21.06.2024 10:54

что вы получите, если запустите эту команду php artisan channel:list?

Maraboc 21.06.2024 11:22

У меня установлен * в allowed_origins, и channel_for_everyone отображается при беге php artisan channel:list

Nick Howarth 24.06.2024 09:20
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
3
375
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Зафиксированный! В конце концов возникло несколько проблем.

Бэкэнд REST API:

  1. Broading.php, гарантируя, что для BROADCAST_DRIVER установлено значение reverb, а для BROADCAST_CONNECTION установлено значение reverb:

Это было неясно, и параметры по умолчанию в комментариях Supported: "pusher", "ably", "redis", "log", "null" не указаны reverb как вариант. Я думал, что установка null проигнорирует это, и мой файл конфигурации реверберации будет контролировать это.

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

Код:

public function reverb(ReverbRequest $request): Response
{
    $socketId = $request->input('socket_id');
    $channelName = $request->input('channel_name');

    // this generates the required format for the response
    $stringToAuth = $socketId . ':' . $channelName;
    $hashed = hash_hmac('sha256', $stringToAuth, env('REVERB_APP_SECRET'));
    
    try {
        // Generate the required format for the response
        $stringToAuth = $socketId . ':' . $channelName;
        $hashed = hash_hmac('sha256', $stringToAuth, env('REVERB_APP_SECRET'));

        return response(['auth' => env('REVERB_APP_KEY') . ':' . $hashed]);
    } catch (Exception $e) {
        return response(['code' => 403, 'message' => 'Cannot authenticate reverb'], 403);
    }
}

Внешний интерфейс

  1. Передайте токен носителя в вызов для аутентификации пользователя. Я также добавил несколько улучшений в код.

Код:

const useLaravelEcho = () => {
    const [{ user }] = useUserContext();
    const { showNotificationToast } = useShowToast();
    const echoInstance = useRef<Echo | null>(null);

    useEffect(() => {
        if (!user) return;

        // Ensure only one Echo instance is created
        if (!echoInstance.current) {
            // eslint-disable-next-line @typescript-eslint/no-unused-vars
            const pusher = Pusher; // Needed for the Echo configuration to work

            echoInstance.current = new Echo({
                broadcaster: 'reverb',
                key: import.meta.env.VITE_REVERB_APP_KEY,
                wsHost: import.meta.env.VITE_REVERB_HOST,
                wsPort: import.meta.env.VITE_REVERB_PORT,
                forceTLS: (import.meta.env.VITE_REVERB_SCHEME ?? 'https') === 'https',
                enabledTransports: ['ws', 'wss'],
                authEndpoint: import.meta.env.VITE_AUTH_ENDPOINT,
                auth: {
                    headers: {
                        'Authorization': 'Bearer ' + user?.access_token
                    }
                }
            });

            // Listen for successful connection
            echoInstance.current.connector.pusher.connection.bind('connected', () => {
                console.info('Successfully connected to Echo server.');
            });

            // Listen for connection errors
            echoInstance.current.connector.pusher.connection.bind('error', (error: any) => {
                console.error('Error connecting to Echo server:', error);
            });
        }

        const channel = echoInstance.current.private('channel_for_everyone')
            .listen(CommentCreatedEvent', (event: any) => {
                showNotificationToast({text: `You have received a new message from ${event?.user?.name}`);
            });

        // Cleanup function to remove listeners and Echo instance on unmount or dependency change
        return () => {
            if (echoInstance.current) {
                channel.stopListening('CommentCreatedEvent');
                echoInstance.current.disconnect();
                echoInstance.current = null;
            }
        };
    }, [user, showNotificationToast]);

    return null;
};

Другие вопросы по теме