2017-09-22 2 views
3

J'essaie de créer un système de notification en temps réel en utilisant Laravel comme client API backend et un SPA pour mon frontend, j'utilise React comme frontend, mais pour le bas Par exemple, je vais utiliser un simple Vue.Js et une lame que j'ai créés pour obtenir un exemple de travail.Laravel Diffusion vers un canal privé en utilisant Socket.io

Ainsi, dans l'ensemble, j'ai une route qui déclenche un événement, cela est montré comme l'exemple ci-dessous:

Route::get('fire', function() { 
    // this fires the event 
    $user = App\Models\User::find(1); 
    event(new App\Events\CampaignUploadedWithSuccess($user, 'testing a notification')); 
    return "event fired"; 
}); 

L'événement qu'il se déclenche ressemblera à ceci

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

class CampaignUploadedWithSuccess implements ShouldBroadcast 
{ 
    protected $user; 

    public $notification; 

    use Dispatchable, InteractsWithSockets, SerializesModels; 

    /** 
    * Create a new event instance. 
    * 
    * @param $user 
    * @param $notification 
    */ 
    public function __construct($user, $notification) 
    { 
     $this->user = $user; 
     $this->notification = $notification; 
    } 

    /** 
    * Get the channels the event should broadcast on. 
    * 
    * @return Channel|array 
    */ 
    public function broadcastOn() 
    { 
     return ['notifications-channel.' . $this->user->id]; 
    } 
} 

Je suis donc en train de diffuser sur un canal appelé notification-channel.{userId}

J'ai alors un fichier socket.js que je cours en utilisant node.

qui ressemble à ceci

var app = require('express')(); 
var http = require('http').Server(app); 
var io = require('socket.io')(http); 
var Redis = require('ioredis'); 

var redis = new Redis(); 
redis.subscribe('notifications-channel.1', function(err, count) { 
}); 
redis.on('message', function(channel, message) { 
    console.log('Notification Recieved: ' + message); 
    message = JSON.parse(message); 
    io.emit(channel + ':' + message.event, message.data); 
}); 
http.listen(3000, function(){ 
    console.log('Listening on Port 3000'); 
}); 

utilisant node socket.js exécute le serveur et le tir de l'événement fait ce que je veux comme ci-dessous:

Notification Recieved on localhost:3000

Happy Days! Je diffusion à un canal ..

Cependant, j'ai maintenant un fichier appelé lame test.blade qui va tirer dans Vue et Socket.io

qui ressemble à ceci

<!DOCTYPE html> 
<html> 
<head> 
    <title>Laravel</title> 
</head> 
<body> 
<h1>Notifications</h1> 

<ul> 
    <li v-repeat="notification: notifications">@{{ notifications }}</li> 
</ul> 

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/0.12.16/vue.min.js"></script> 
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.7/socket.io.min.js"></script> 

<script> 
    var socket = io('http://localhost:3000'); 
    new Vue({ 
     el: 'body', 
     data: { 
      notifications: [] 
     }, 
     ready: function() { 
      socket.on('notifications-channel.1', function(data) { 
       alert(data.notification); 
      }); 
     } 
    }); 
</script> 
</body> 
</html> 

Et la L'objectif ici est d'avoir le message d'alerte lorsque le canal de notification.1 a des données diffusées. Pourtant, cela ne fonctionne pas. Donc, ma question est de savoir comment on peut diffuser sur une chaîne et consommer cette émission à partir du canal en utilisant socket.io, Laravel et Redis.

Je suis également un peu dans le noir sur les canaux privés et comment je peux créer un canal pour un seul utilisateur. La documentation est bonne, mais elle ne fournit pas d'exemples concrets sur la façon d'y parvenir et d'avoir des notifications consommées par plusieurs plates-formes.

Répondre

2

J'ai également fait face à la même question après la recherche que j'ai trouvé le problème était dû à la version socket. S'il vous plaît Assurez-vous que la vous avez utilisé la même version socket.io à la fois la fin du serveur et côté client, vous pouvez vérifier en d'abord vérifier la version socket dans le fichier package.json comme dans mon cas, vous pouvez voir ci-dessous

"devDependencies": { 
    "socket.io": "^2.0.3", 
    "socket.io-client": "^2.0.3", 
} 

, puis vérifiez la version du socket dans votre test.fichiers lame comme ci-dessous

<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.3/socket.io.js"></script> 

Vous pouvez voir ces deux sont la même version. Et il y a un problème dans vos fichiers de lames vous émettez un événement de socket par canal de clé: event.name mais sur vos fichiers de lame, vous pouvez écouter uniquement le nom de canal sans concaténer le nom de l'événement. s'il vous plaît le remplacer par le code ci-dessous

<script> 
    var socket = io('http://localhost:3000'); 
    new Vue({ 
     el: 'body', 
     data: { 
      notifications: [] 
     }, 
     ready: function() { 
      socket.on('notifications-channel.1:App\\Events\\CampaignUploadedWithSuccess', function(data) { 
       alert(data.notification); 
      }); 
     } 
    }); 
</script> 
+0

Cela fait beaucoup de sens, donc j'ai modifié le fichier de la lame, et quand je le lance dans le navigateur, je vois mon balise H1, en disant notifications, la console affiche la connexion d'erreur refusé, donc je cours le noeud socket.js et cette erreur disparaît, dans mon esprit cela signifie qu'il se connecte à localhost: 3000, je déclenche l'événement et il apparaît dans la console du serveur, mais la console ne se connectera pas sur le client ... J'ai fait correspondre les versions :) –

+0

Je pense que je peux manquer une connexion à la socket dans mon fichier socket.js –

+0

Le canal que vous diffusez votre événement a des notifications de nom-canal puis dynamiquement vous passez l'ID de l'utilisateur et sur le côté client vous dur codé avec 1. est-ce que l'utilisateur que vous êtes en train de vous connecter a l'ID 1 pouvez-vous s'il vous plaît confirmer. –

1

Je pense que vous manquez la configuration du look io à

https://socket.io/docs/server-api/

Quelque chose comme cela serait nécessaire sur votre serveur nodejs et/ou client.

io.on('connect', onConnect); 

function onConnect(socket){ 
    socket.emit(channel + ':' + message.event, message.data); 
} 

Hope this helps