Search code examples
laravelvue.jselectronpusherlaravel-echo

Laravel echo in electron-vue app - join() not working


I'm building a desktop app with electron-vue and a laravel backend. I setup Laravel Echo in the project and using Echo.channel() worked totally fine. Now I tried to use a presence channel with Echo.join() and it doesn't seem to do anything at all. I can see the connection in the pusher debug console but it never joins the channel. The strangest thing is that it never makes a request to my server to authorize either.

In my renderer/main.js file I create the Echo instance:

window.Pusher = require('pusher-js')
window.Echo = new Echo({
  broadcaster: 'pusher',
  key: Keys.PUSHER_KEY,
  cluster: Keys.PUSHER_CLUSTER,
  forceTLS: true,
  authEndpoint: `${apiUrl}/broadcasting/auth`
})

if(localStorage.getItem('api_key')) {
  let key = localStorage.getItem('api_key')
  axios.defaults.headers.common['Authorization'] = 'Bearer ' + key
  window.Echo.connector.pusher.config.auth.headers['Authorization'] = 'Bearer ' + key
}

Then in my component I have the following code to join the presence channel. The display comes from vuex, so that's why I trigger it from a watcher:

watch: {
  'display.id': {
    immediate: true,
    handler: function(newVal) {
      if(newVal) {
        this.joinPresenceChannel()
      }
    }
  }
},
methods: {
  joinPresenceChannel() {
    console.log(`joining presence channel: display.${this.display.id}`)
    Echo.join(`display.${this.display.id}`)
        .here((users) => {
          console.log('Users here: ')
          console.log(users)
        })
  }
}

The console.log() saying "joining presence channel" fires, but the console.log()s in the here() method never fire. And looking at the network tab in chrome I can see that it never makes a request to /broadcasting/auth.

I do have the backend all setup to authorize the channels as well. I actually have my inertiajs app in the laravel project using the same presence channel, with the same code, and it joins just find. I just can't seem to get the electron app to work.

Can anyone point me in the right direction?


Solution

  • Looks like I finally got to the bottom of this. After doing a little more investigating I found out that the electron devtools apparently just wasn't showing the request to the authorization route, as I did a tail on my access_log and saw it was in fact hitting that route. In the access log I could also see I was getting a 403 response.

    Since I need both my electron app and my inertia web app to be able to authenticate to these channels, I changed the BroadcastServiceProvider boot method to look like this:

    public function boot()
    {
        Broadcast::routes(['middleware' => 'web']);
        Broadcast::routes(['prefix' => 'api', 'middleware' => ['api', 'auth:sanctum']]);
    
        require base_path('routes/channels.php');
    }
    

    I also found out that it won't work unless you add the auth:sanctum middleware on the API route. You also have to make sure to update the client to use the /api/broadcasting/auth route instead of the default /broadcasting/auth.

    After making those changes it looks like I'm able to join presence channels just fine.