Search code examples
laravelnext.jschatlaravel-reverb

Laravel reverb / NextJs. not getting any response from private channel after the authorizate


i am having a problem with receiving messages in realtime by using laravel reverb and nextjs After successfully authorization on privateChannel im not geting any event as response.

Event class MessageSent: here im using privateChannel to send messages to a specific user

<?php

namespace App\Events;

use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

class MessageSent implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;**your text**

    public $message;
    public $userId;

    /**
     * Create a new event instance.
     */
    public function __construct($userId,$message)
    {
        $this->userId = $userId;
        $this->message = $message;
    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return array<int, \Illuminate\Broadcasting\Channel>
     */
    public function broadcastOn(): array
    {
        return [
            new PrivateChannel('chat.'.$this->userId),
        ];
    }

    public function broadcastAs(){
        return 'message-sent';
    }

    public function broadcastWith() : array{
        return [
            'message' => $this->message,
        ];
    }
}

Channel Route:

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

Bootstrap/app.php:

return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        api: [__DIR__.'/../routes/api.php',__DIR__.'/../routes/auth.php'],
        commands: __DIR__.'/../routes/console.php',
        // channels: __DIR__.'/../routes/channels.php',
        health: '/up',
    )
    ->withBroadcasting(
        __DIR__.'/../routes/channels.php',
        ['prefix'=>'api','middleware'=>['auth:sanctum']],
    )
    ->withMiddleware(function (Middleware $middleware) {
        $middleware->api(prepend: [
            \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
        ]);

        $middleware->alias([
            'verified' => \App\Http\Middleware\EnsureEmailIsVerified::class,
        ]);

        //
    })
    ->withExceptions(function (Exceptions $exceptions) {
        //
    })->create();

MessageController:

public function sendMessage(Request $request,string $receiverId){
        
        $authUserId = Auth::user()->id;
        $request->validate([
            'message'=>['required']
        ]);
        
        $message = new Message();
        $message->sender_id = $authUserId;
        $message->receiver_id = $receiverId;
        $message->message = $request->message;
        $message->save();

        event(new MessageSent($receiverId,$request->message));

        return response()->json([
            'message'=>'Message has sent successfully'
        ]);
    }

Nextjs ** Echo Configuration for communicte with the Laravel Reverb server:**

import { useEffect, useState } from 'react';
import axios from './axios';
import Echo from 'laravel-echo';
import Pusher from 'pusher-js';
import Cookies from 'js-cookie'; // Import the js-cookie library


const useEcho = () => {
  const [echoInstance, setEchoInstance] = useState(null);

  useEffect(() => {
    // Get the Bearer token from cookies
    const token = Cookies.get('token');

    // Create the Echo instance here
    const echo = new Echo({
      broadcaster: 'reverb',
      key: process.env.NEXT_PUBLIC_REVERB_APP_KEY,
      authorizer: (channel) => {
        return {
          authorize: (socketId, callback) => {
            axios
              .post(
                '/api/broadcasting/auth',
                {
                  socket_id: socketId,
                  channel_name: channel.name,
                },
                {
                  headers: {
                    Authorization: `Bearer ${token}`,
                  },
                }
              )
              .then((response) => {
                callback(false, response.data);
              })
              .catch((error) => {
                callback(true, error);
              });
          },
        };
      },
      wsHost: process.env.NEXT_PUBLIC_REVERB_HOST,
      wsPort: process.env.NEXT_PUBLIC_REVERB_PORT,
      wssPort: process.env.NEXT_PUBLIC_REVERB_PORT,
      forceTLS: (process.env.NEXT_PUBLIC_REVERB_SCHEME ?? 'https') === 'https',
      enabledTransports: ['ws', 'wss'],
    });
    
    setEchoInstance(echo);
  }, []);

  return echoInstance;
};

export default useEcho;

listen to private channel:

echo.private(`chat.${user.id}`)
                .listen('message-sent', (event) => {
                    console.log(event)
                });
            }

i got success response of the authenticate to private channel. Image

but after a sending Message to a specific user there isnt any response from the event

i tired to run and queue job command and the reverb server but didnt work


Solution

  • This setup fixed my issue with it :

    const setEcho = () => {
    window.Echo = new Echo({
      broadcaster: 'reverb',
      key: process.env.NEXT_PUBLIC_REVERB_APP_KEY,
      wsHost: process.env.NEXT_PUBLIC_REVERB_HOST,
      wsPort: process.env.NEXT_PUBLIC_REVERB_PORT ?? 80,
      wssPort: process.env.NEXT_PUBLIC_REVERB_PORT ?? 443,
      cluster: 'us2',
      forceTLS: (process.env.NEXT_PUBLIC_REVERB_SCHEME ?? 'https') === 'https',
      enabledTransports: ['ws'],
      logToConsole: true,
      authEndpoint: '/broadcasting/auth',
      auth: {
        headers: {
          Authorization: `Bearer ${cookies.get(COOKIE_KEYS.token)}`,
        },
      },
    });