Laravel echo server not working in production server
Asked Answered
R

2

11

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'];
    }
Redpencil answered 21/8, 2018 at 8:42 Comment(12)
Can you check if you are calling echo under an opened ob_start() buffer?Heparin
@Heparin where can i do that?Redpencil
May be it is not the best approach to tackle the problem, but I would check inside the lavarel modules you are using if there is some point where is being used this buffer. Because that functionality is fetching the standard output to then retrieved it afterwardsHeparin
When you tested locally did you use the same authHost, host and port settings in echo.run() as prod? I'm wondering if this is a firewall or similar access issue...Mace
@Mace port and authost are the same, host is different due to the domain name. I don't know if it is the firewall issue, since I can do plain socket server just fine and connect and receive data from the client.Redpencil
@raqulka I suppose your queue server is not running on production. Run artisan queue:restart and check if it solves your problem...Damp
@Damp Already did that. The queue is running, I get all the info in redis and queue logsRedpencil
@raqulka so what is in logs of your servers?Damp
How is your public function toBroadcast($notifiable) at your notification class? It took me some hours to realize that my issue was there, it should be like public function toBroadcast($notifiable){ return new BroadcastMessage(['message' => 'some message']); }Daredevil
Did you ever get a solutions to this problem? I'm currently having a similar issue. Although I'm using SQLite for the DB and not Redis, but none of the suggestion in this thread worked so far. All the clients are able to connect to the private channel I have setup, as I could see on the laravel-echo-server logs, but the clients are not receiving notifications. While the same setup is working on my development machine but not in production . Although my dev machine is Windows based while my production machine is ubuntu. I have also tried on a Mac with same results as the ubuntu machine.Brei
@Brei im sorry but no. I had to switch from laravel echo to plain socket connection. There are multiple tutorials available online which you can follow.Redpencil
@raqulka After abandoning it for some few days and revisiting the issue, I discovered I had made two silly mistakes in my own case. The broadcast driver in the .env file was set to 'log' and I forgot to install sqlite3 on both the Mac & the Ubuntu Machines. Thanks for the response and suggestions though, I really appreciate it.Brei
M
2

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.
Monomolecular answered 28/8, 2018 at 15:42 Comment(3)
It is all done. Over SSL. I just wrote "path/to" since I dont want to expose my server pathRedpencil
Ok, also as I see in logs you listen 'private-user.1' channel, but redis in logs broadcast to "PUBLISH" "private-user.2", can problem be here?Monomolecular
just copied and example: two users were online. thats why user 2.Redpencil
L
1

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;

    ...
}
Lookeron answered 29/8, 2018 at 20:54 Comment(3)
Make sure you are defining the toBroadcast($notifiable) function in your notification class and returning a BroadcastMessage, as I am not seeing it in your edit. You will need to log in as the user you want to test and navigate to the page where you have the Echo notification call, then set up a test route to call $user->notify(new testNotification()); on the user you are logged in as and visit that page in a separate window/tab.Lookeron
Also, make sure your user model has the Notifiable trait.Lookeron
It has Notifiable trait!Redpencil

© 2022 - 2024 — McMap. All rights reserved.