z0mbieKale
z0mbieKale

Reputation: 1028

Laravel echo server not working in production server

I am having problem with socket.io as a broadcaster with laravel echo.

What have I tried:

php artisan cache:clear
php artisan config:clear

I can see users connecting within the logs:

0|Socket-Connection  | [11:17:00 AM] - ********** joined channel: test-channel
0|Socket-Connection  | [11:17:01 AM] - ********** authenticated for: private-user.1
0|Socket-Connection  | [11:17:01 AM] - ********** joined channel: private-user.1

My queue is running and is logging all the events properly.

I can see redis my events and database notifications perfectly in the redis console.

But no events are broadcasted and I am not seeing them in the laravel-echo-server console. Everything is working in my localhost, but not in the production and I losing my mind.

Here's my laravel echo JS:

if (typeof io !== 'undefined') {
    console.log(window.location.origin);
    window.Echo = new Echo({
        broadcaster: 'socket.io',
        host: window.location.origin + ':6001',
        auth: {
            headers: {
                Authorization: 'Bearer ' + bearerToken,
            },
        }
    });
    window.Echo.private('user.' + user_id).notification((notification) => {
        console.log(notification);
    });
}

On my user model I have defined this:

/**
* @return string
*/
public function receivesBroadcastNotificationsOn()
{
    return 'user.' . $this->id;
}

And in my channels I have this:

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

This is my echo server config where all the paths are correct. I tested the same file on my localhost and everything is working:

var echo = require('laravel-echo-server/dist');

echo.run({
    "appKey": "myappkey",
    "authHost": "https://url",
    "authEndpoint": "/broadcasting/auth",
    "database": "redis",
    "clients": [
        {
            "appId": "myappid",
            "key": "mykey"
        }
    ],
    "databaseConfig": {
        "redis": {
            "port": "6379",
            "host": "myhost",
            "password": "mysupersecretpassword"
        },
        "sqlite": {
            "databasePath": "/database/laravel-echo-server.sqlite"
        }
    },
    "devMode": true,
    "host": "url",
    "port": "6001",
    "protocol": "https",
    "referrers": [],
    "sslCertPath": "/path/to/certificate.pem",
    "sslKeyPath": "/path/to/key",
    "verifyAuthPath": true,
    "verifyAuthServer": false
});

My redis log shows this when published a database notification

1534840681.110359 [0 "IP ADDRESS HERE"] "PUBLISH" "private-user.2" "{\"event\":\"Illuminate\\\\Notifications\\\\Events\\\\BroadcastNotificationCreated\",\"data\":{\"title\":\"Ravim CONVULEX 50MG\\/ML  staatust muudeti\",\"notification_type\":\"element-soft-delete\",\"message\":\"Ravimi CONVULEX 50MG\\/ML  staatust muutis kasutaja Kalle \",\"url\":\"https:\\/\\/www.app.riskomed.com\\/admin\\/brands\\/all\",\"id\":\"30c37d0d-c39b-41bf-93fc-afa0c78ca9db\",\"type\":\"App\\\\Notifications\\\\API\\\\Management\\\\Medical\\\\Brands\\\\BrandSoftDeleteNotification\",\"socket\":null},\"socket\":null}"

EDIT

This is my notification

        /**
     * Get the notification's delivery channels.
     *
     * @param  mixed $notifiable
     * @return array
     */
    public function via($notifiable)
    {
        return ['mail', 'database', 'broadcast'];
    }

Upvotes: 11

Views: 6259

Answers (2)

JPark
JPark

Reputation: 789

If you are seeing users joining the channels, then it is most likely set up correctly. You just need to broadcast a notification for your console.log(notification) call to work, since you are specifically calling the notification function on the user channel. See https://laravel.com/docs/5.6/broadcasting#notifications for more details.

Broadcast with notification:

//Create a new notification with artisan, e.g. php artisan make:notification testNotification

class testNotification extends Notification {

    ...

    public function via($notifiable)
    {
        return ['broadcast'];
    }

    ...

    public function toBroadcast($notifiable) {
        return new BroadcastMessage([
            'message' => 'TEST',
        ]);
    }
}

Then when you are ready to broadcast your message, just notify the user:

$user->notify(new testNotification());

Edit:

Also, make sure you have the Notifiable trait in your user model:

class User extends Authenticatable
{
    use Notifiable;

    ...
}

Upvotes: 1

Denis Kuratovich
Denis Kuratovich

Reputation: 287

As I see you use 'https' protocol in prodaction server, so you need to define 'sslCertPath' and 'sslKeyPath':

From docs

Running with SSL

  • Your client side implementation must access the socket.io client from https.
  • The server configuration must set the server host to use https.
  • The server configuration should include paths to both your ssl certificate and key located on your server.

Upvotes: 2

Related Questions