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'];
    }
z0mbieKale
  • 905
  • 13
  • 37
  • Can you check if you are calling echo under an opened ob_start() buffer? – Miguel Aug 23 '18 at 11:17
  • @Miguel where can i do that? – z0mbieKale Aug 23 '18 at 12:18
  • 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 afterwards – Miguel Aug 23 '18 at 14:01
  • 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... – Rich Aug 26 '18 at 15:26
  • @Rich 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. – z0mbieKale Aug 27 '18 at 06:03
  • @raqulka I suppose your queue server is not running on production. Run `artisan queue:restart` and check if it solves your problem... – Bart Aug 29 '18 at 21:22
  • @Bart Already did that. The queue is running, I get all the info in redis and queue logs – z0mbieKale Aug 30 '18 at 07:52
  • @raqulka so what is in logs of your servers? – Bart Sep 10 '18 at 02:17
  • 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']); }` – cawecoy Oct 09 '18 at 04:51
  • 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. – Dev Oct 17 '18 at 12:47
  • @Dev 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. – z0mbieKale Oct 18 '18 at 11:50
  • @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. – Dev Nov 01 '18 at 10:00

2 Answers2

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.
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;

    ...
}
JPark
  • 709
  • 4
  • 6
  • 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. – JPark Aug 31 '18 at 15:17
  • Also, make sure your user model has the `Notifiable` trait. – JPark Aug 31 '18 at 15:25
  • It has Notifiable trait! – z0mbieKale Sep 03 '18 at 06:15