2017-08-08 4 views
1

J'utilise Redis avec Socket.io pour configurer les mises à jour en temps réel mais Laravel Echo n'attrape pas les événements.Laravel Echo n'attrape pas les événements avec socket.io

Si j'utilise une instance de io() cela fonctionne très bien. Voici mon code dans mon application vue pour écouter les événements:

ne sera pas attraper les événements

window.Echo.channel('users') 
    .listen('UserCreated', event => { 
      console.log(event); 
      this.all_users.push(event.user); 
      this.filter_data(); 
    }); 

attraperez événements

window.socket = io(window.location.origin+':3000'); 
window.socket.on('users:App\\Events\\UserCreated', function(data){ 
    console.log(data); 
    console.log('from socket'); 
    this.all_users.push(data.user); 
    this.filter_data(); 
}.bind(this)); 

Code js Mon noeud pour pousser les événements.

var server = require('http').Server(); 

var io = require('socket.io')(server); 

var Redis = require('ioredis'); 

var redis = new Redis(); 

redis.subscribe('users', function(error, count){ 
    console.log(error); 
    console.log(count); 
}); 

redis.on('message', function(channel, message){ 
    console.log(channel); 
    message = JSON.parse(message); 
    console.log(message); 
    const emmitChannel = `${channel}:${message.event}`; 
    console.log(emmitChannel); 
    io.emit(emmitChannel, message.data); 
}); 

server.listen(3000); 

Mon Laravel Evénement de diffusion

<?php 

namespace App\Events; 

use Illuminate\Broadcasting\Channel; 
use Illuminate\Queue\SerializesModels; 
use Illuminate\Broadcasting\PrivateChannel; 
use Illuminate\Broadcasting\PresenceChannel; 
use Illuminate\Foundation\Events\Dispatchable; 
use Illuminate\Broadcasting\InteractsWithSockets; 
use Illuminate\Contracts\Broadcasting\ShouldBroadcast; 


//Models 
use App\User; 

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

    public $user; 

    /** 
    * Create a new event instance. 
    * 
    * @return void 
    */ 
    public function __construct(User $user) 
    { 
     $this->user = $user; 

     $this->dontBroadcastToCurrentUser(); 
    } 

    /** 
    * Get the channels the event should broadcast on. 
    * 
    * @return Channel|array 
    */ 
    public function broadcastOn() 
    { 
     return ['users']; 
    } 
} 

J'ai essayé de changer les événements de manière sont passés à Laravel Echo puisque par défaut, il les reçoit comme users:App\Events\UserCreated mais je ne l'ai pas eu la chance.

Répondre

0

J'ai finalement réussi à comprendre cela. J'ai regardé à travers les fichiers JS et réussi à l'épingler au fait que the code in this line a la section try catch pas réellement jeter des erreurs si le Laravel channels.php vérifier à qui peut écouter un canal ne retourne pas une instance de modèle d'utilisateur comme il se doit .

Quelque chose comme ça dans Channels.php rejettera cette erreur:

Broadcast::channel('users', function ($user) { 
    if($user->type == 'admin'){ 
     return $user; 
    }else{ 
     return false; 
    } 
}); 

Si le $user ne passe pas le chèque if Laravel retournera false. Comme il ne retourne pas JSON et qu'il est simplement faux, je pense qu'il devrait se connecter que le corps de la réponse n'a pas passé la fonction JSON.parse() afin que vous puissiez voir cela dans le terminal. Quelque chose comme ceci:

try { 
    body = JSON.parse(response.body); 
} catch (e) { 
    Log.warning('Response body provided is not expected JSON. Response body provided ${response.body}'); 
    body = response.body; 
} 

De cette façon, nous pouvons voir si Laravel ne renvoie pas une instance de modèle utilisateur. Par conséquent, lorsque vous n'obtenez pas une instance de modèle utilisateur comme prévu, il n'y a pas d'objet utilisateur auquel le code doit attacher le paramètre sockedId car il n'est pas défini. Il n'y avait jamais de JSON avec lequel faire l'objet.

Je pense que le code devrait cesser d'essayer de se connecter à la présence ou au canal privé si vous n'obtenez pas une instance d'utilisateur non plus que d'essayer d'attacher un ID de socket.

De toute façon, pour retourner un utilisateur, assurez-vous d'être connecté using Laravel's Auth system. Si vous ne l'avez pas utilisé, vous devrez peut-être travailler pour le faire fonctionner. Si vous ne l'utilisez pas, alors this function in Laravel will throw a 403 error because it can't find you to be logged in.

J'ai dû écraser la fonction qui vérifie l'algorithme de hachage du mot de passe à un algorithme personnalisé avec un fournisseur afin que je ne plaisante pas avec le noyau Laravel et que le modèle utilisateur étende la classe recherchée par Laravel.

Ensuite, dans votre fichier channels.php, assurez-vous que la vérification que vous effectuez est en train de renvoyer l'utilisateur $ dans la fonction de rappel de la vérification d'authentification effectuée par le fichier Broadcaster.php.Quelque chose comme ceci:

Broadcast::channel('users', function ($user) { 
    return $user; 
}); 

C'est une chaîne privée de présence/super simple mais avec un utilisateur connecté et retourner à l'utilisateur $ ce ne sera pas jeter cette erreur.

Aussi, assurez-vous que vous appelez socket.io dans votre instance Echo comme ceci:

window.Echo = new Echo({ 
    broadcaster: 'socket.io', 
    host: window.location.origin + ':6001' 
});