Laravel Echo presence channel not working well wit

2019-08-23 11:32发布

问题:

The app is a chat app, using laravel and Vue, once a user logs in he sees the list of all online users, I called the Echo wrapper in the mounted component of the home page to show all online users, it works and shows them, the issue now is if I go to another page (via Vue Router) and then comeback to the home page it doesn't show the list of online users... Except manually i refresh the page again. Below is a snippet of my code:

mounted () {
// alert('Shoud work')
// console.log(Echo)
Echo.join('online')
.here((users) => {
  alert(JSON.stringify(users))
    this.users = users
})
.joining((user) => {
    this.users.push(user)
})
 .leaving((user) => {
    this.users = this.users.filter(u => (u.id !== user.id));
    })
  }
}

回答1:

Try leaving the channel using the component destroyed method. Since you never leaved the channel, once you come back, the issue could be that Echo.join won't load again, since the user is already on the channel, therefore, not triggering the .here which is the one responsible for loading your components users property with the chat users array.

mounted () {
    Echo.join('online')
    .here(users => {
        this.users = users
    })
    .joining(user => {
        this.users.push(user)
    })
    .leaving(user => {
        this.users = this.users.filter(u => (u.id !== user.id));
    })
},
destroyed() {
    Echo.leave(user => {
        this.users = this.users.filter(u => (u.id !== user.id));
    });
}

Or

mounted () {
    Echo.join('online')
    .here(users => {
        this.users = users
    })
    .joining(user => {
        this.users.push(user)
    })
    .leaving(user => {
        this.removeUser()
    })
},
destroyed() {
    Echo.leave(user => {
        this.removeUser()
    });
},
methods: {
    removeUser(user) {
        this.users = this.users.filter(u => (u.id !== user.id))
        // Any other reusable code...
    }
}

UPDATE:

If you intend to keep the user "logged in" through out your application, one way to do this is to create a "session" component. This component can or cannot have a template, however, it needs to stay loaded on every page. To access the the users list outside this session component, you could either store the users data into the browser's local store, use a global variable (ex. window.session.users), or, if available, use Vuex. Either way, as long as the users array is available for other components to use, the session component will keep that information up to date when users leave or join the application (or chat... or whatever join/leave rule you implement there).

For example, let's say you create a component named session. You could easily just place it inside your top navigation component template using <session></session>. Since the session component own template is empty, it won't affect the top navigation. However, it will be rendered, allowing you to manage the user's online state.