5

I'm developing real-time app with Laravel. Since I don't want to use Pusher, I'm trying to make websockets work using Laravel Echo Server, Redis, and Socket.IO. However, I'm having a problem with this stack. The client (browser) can't seem to receive data from events. I also use Intertia and Vue for the frontend. It's also worth noting that I use Laragon as my local dev environment.

My .env, some are omitted:

APP_URL=http://malbe.test

BROADCAST_DRIVER=redis
CACHE_DRIVER=file
QUEUE_CONNECTION=redis
SESSION_DRIVER=file
SESSION_LIFETIME=120

MIX_APP_URL="${APP_URL}"

My laravel-echo-server.json:

{
    "authHost": "http://malbe.test",
    "authEndpoint": "/broadcasting/auth",
    "clients": [
        {
            "appId": "omitted",
            "key": "omitted"
        }
    ],
    "database": "redis",
    "databaseConfig": {
        "redis": {},
        "sqlite": {
            "databasePath": "/database/laravel-echo-server.sqlite"
        }
    },
    "devMode": true,
    "host": null,
    "port": "6001",
    "protocol": "http",
    "socketio": {},
    "secureOptions": 67108864,
    "sslCertPath": "",
    "sslKeyPath": "",
    "sslCertChainPath": "",
    "sslPassphrase": "",
    "subscribers": {
        "http": true,
        "redis": true
    },
    "apiOriginAllow": {
        "allowCors": true,
        "allowOrigin": "http://malbe.test:80",
        "allowMethods": "GET, POST",
        "allowHeaders": "Origin, Content-Type, X-Auth-Token, X-Requested-With, Accept, Authorization, X-CSRF-TOKEN, X-Socket-Id"
    }
}

My redis config on database.php: Note: I use predis because I can't seem to make phpredis work even if I installed the dll on PHP extensions.

'redis' => [

        // 'client' => env('REDIS_CLIENT', 'phpredis'),
        'client' => env('REDIS_CLIENT', 'predis'),

        'options' => [
            'cluster' => env('REDIS_CLUSTER', 'redis'),
            // 'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'),
            'prefix' => "",
        ],

        'default' => [
            'url' => env('REDIS_URL'),
            'host' => env('REDIS_HOST', '127.0.0.1'),
            'password' => env('REDIS_PASSWORD', null),
            'port' => env('REDIS_PORT', '6379'),
            'database' => env('REDIS_DB', '0'),
        ],

        'cache' => [
            'url' => env('REDIS_URL'),
            'host' => env('REDIS_HOST', '127.0.0.1'),
            'password' => env('REDIS_PASSWORD', null),
            'port' => env('REDIS_PORT', '6379'),
            'database' => env('REDIS_CACHE_DB', '1'),
        ],

    ],

My Laravel event:

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

   public function __construct()
   {
       //
   }

   public function broadcastOn() {
      return new Channel("my-channel");
   }

   public function broadcastWith() {
      return ["data"=>"Hello"];
   }
}

My Echo initialization at bootstrap.js:

import Echo from "laravel-echo";
window.io = require("socket.io-client");

if (typeof window.io !== "undefined") {
    window.Echo = new Echo({
        broadcaster: "socket.io",
        host: process.env.MIX_APP_URL + ":6001"
    });
}

On the Vue page that subscribes to the Echo server

export default {
    props: ["foo"],
    mounted: function () {
        window.Echo.channel("my-channel").listen("SampleEvent", (d) => console.log(d));
    }
};

With these 3 commands running:

  1. laravel-echo-server start
  2. npm run watch
  3. php artisan queue:work

I tried broadcasting an event using Tinker and GET request.

Route::get("/broadcast", function () {
    event(new \App\Events\SampleEvent);
    // also tried
    // broadcast(new \App\Events\SampleEvent);
});

Queue worker processes the events;

[2020-12-24 11:07:35][n9FKq0n6C6QOKa2f1JBzWcCqgYqLiDvU] Processing: App\Events\SampleEvent
[2020-12-24 11:07:35][n9FKq0n6C6QOKa2f1JBzWcCqgYqLiDvU] Processed:  App\Events\SampleEvent

And laravel-echo-server outputs this whenever an event was broadcast;

L A R A V E L  E C H O  S E R V E R  
                                     
version 1.6.2                        
                                     
⚠ Starting server in DEV mode...     
                                     
✔  Running at localhost on port 6001 
✔  Channels are ready.               
✔  Listening for http events...      
✔  Listening for redis events...     
                                     
Server ready!                        
                                 
Channel: my-channel                  
Event: App\Events\SampleEvent        

Client does not show any error. Here is a look to its Network Tab on Developer Console:

Browser Network Tab

And when I closed the laravel-echo-server while the client is still open this error occurs every other second:

ERR_CONNECTION_REFUSED

Sorry for the lengthy question, I just had to show all my configuration so that I can help you help me with this issue. Can anyone point me to the right solution? Thanks!

Kolokoy
  • 118
  • 1
  • 5

2 Answers2

14

I think your config code is right. You could see your configuration of package.json in vue:

"socket.io-client": "^2.4.0",

If your "socket.io-client" is >=3, you'd better change it into 2.4.0. and run:

sudo cnpm i socket.io@2.4.0
linuxartisan
  • 2,396
  • 3
  • 21
  • 40
Token Yan
  • 156
  • 1
  • 3
  • I've wasted two weeks on this issue... thank you very much! is it due to the required secure connection? – Darkshifty Feb 08 '21 at 17:07
  • In my case the latest engine.io version didn't work at all witih Laravel. You can tell by the `EIO` parameter in the URL. Once I downgraded to client version 2.4 the `EIO` parameter changed from 4 to 3 and everything worked as expected. – hammurabi Feb 13 '21 at 22:10
  • THANK YOU! I spent far too many hours trying to sort this out. – Martin Sheeks Aug 28 '21 at 19:50
  • `npm install socket.io-client@2.4.0` or use `npm i socket.io-client@2.4.0` for install – Harsh Patel Jan 18 '22 at 11:28
  • @Token-Yan I have doubt why its not works with latest socket.io-client v4.4.1. first I was installed latest version but its not works then I see your answer & tried with socket.io-client v2.4.0 then its works perfectly. what's exact reason can you explain me? – Harsh Patel Jan 18 '22 at 11:36
  • I am having the same issue in React Native but you saved me from the frustration I have been battling for over a week now – Paulos Ab Jan 11 '23 at 21:54
  • I had the same issue. when i use newer version of socket.io-cliet echo object shows "connected:false". after downgrade the version to 2.4.0 its "connected:true" and echo server show the events but not trigger in client react app. and not showing any error. please give me a help. i wasted so many days for this. – Tharuka Dananjaya Jun 22 '23 at 13:33
0

Echo does not support and does not plan to support Socket IO >= v3 more info here: https://github.com/laravel/echo/issues/290