2016-11-28 3 views
5

Frage Titel kann etwas verwirrend sein, versuchte ich mein Bestes, es zu erklären.Laravel Echo wiederholen hören Ereignis für n-mal Sendung wurde gemacht

Ich habe laravel-echo-server, redis (für Warteschlangen) und Laravel echo eingerichtet. Ich möchte nur eine Nachricht über eine Eingabe senden und den Nachrichten-Feed für alle auf der Seite aktualisieren. im Wesentlichen ein Chatraum.

Alles funktioniert, abgesehen von der Tatsache, dass es langsam wie die Hölle ist, aber ich bin neu in Laravel Echo und Vue.

Wenn ich eine Nachricht gesendet habe, ist es in Ordnung, aber wenn ich eine weitere Nachricht sende, erhalte ich zwei Antworten. Senden Sie eine dritte Nachricht drei Antworten und so weiter ...

Was genau mache ich falsch? Ich habe überprüft socket.io/laravel-echo-server ist nur Verbindung mit dem Kanal einmal, und meine broadcast wird nur einmal gesendet (Überprüfung der Warteschlange Worker es verarbeitet nur die Anfrage), also wie wird es wiederholt exponentiell?

Das ist mein app.js:

const chatWindow = new Vue({ 
    el: '#chatWindow', 
    data: { 
     messages: [] 
    }, 
    methods: { 
     sendMessage: function() { 
      this.$http.post('/chat', {message: this.message}).then((response) => { 
       window.Echo.channel('test-chat-channel') 
        .listen('MessageSent', (event) => { 
         console.log(event.message); 
         // this.messages.push(event.message); 
        }); 
      }, (response) => { 
       // error callback 
      }); 

      this.message = ''; 
     } 
    }, 
    props: ['message'] 
}); 

Dies ist mein Chat Ansicht:

<div id="chatWindow" class="col-sm-7"> 
    <h1 class="text-center no-top">Chat</h1> 
    <div class="chat-window"> 
     <ul> 
      <li v-for="message in messages">@{{ message }}</li> 
     </ul> 

     <div class="form-group"> 
      <input title="Send Message" v-model="message" @keyup.enter="sendMessage" class="form-control" placeholder="Send message..."> 
     </div> 
    </div> 
</div> 

Gerade falls sie hier relevant sind, ist meine Route:

Route::post('/chat', function (Request $request) { 
    event(new MessageSent($request->message)); 
}); 

und mein Ereignis:

<?php 

namespace App\Events; 

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

class MessageSent implements ShouldBroadcast 
{ 
    use InteractsWithSockets, SerializesModels; 

    public $message; 

    public function __construct($message) 
    { 
     $this->message = $message; 
    } 

    public function broadcastOn() 
    { 
     return new Channel('test-chat-channel'); 
    } 
} 

Antwort

2

Ich verwende Redis PubSub in der Anwendung, die ich zur Zeit bin Gebäude und haben zu kämpfen hatte das gleiche Problem. Obwohl ich Laravel-Echo-Server nicht genug kenne, um Sie speziell zu beraten, wie man es beheben kann, kann ich den wahrscheinlichen Grund für dieses Symptom beschreiben.

Ihre Konfiguration abonniert den Redis-Kanal in jedem Zyklus, und dieses Abonnement ist nicht vorübergehend. Bei jedem Abonnement erstellen Sie einen neuen Listener. Bei jeder Veröffentlichung sendet Redis die Nachricht an alle Listener/Abonnenten. Wenn ein einzelner Client dreimal abonniert wurde, erhält er diese Nachricht dreimal. Sie müssen entweder erkennen, dass Sie abonniert sind und es nicht duplizieren, oder Sie müssen sich nach jedem Zyklus abmelden.

Eine Sache zu beachten ist, dass die Redis-Instanz entweder veröffentlichen oder abonnieren sollte, aber nicht beides. Laravel-Echo-Server verarbeitet das wahrscheinlich für Sie.

Redis gibt normalerweise die Anzahl der Abonnenten zurück, die bei jeder Veröffentlichung eine Nachricht erhalten. Dies half mir, das Problem zu diagnostizieren, zumal ich private Kanäle betreibe und für jede Nachricht 1 und nur 1 Listener haben sollte. Redis hat auch einen "numsub" -Befehl, der die Anzahl der Listener auf einem Kanal zurückgibt.

Ich habe festgestellt, dass Ihre sendMessage-Funktion die listen-Methode verwendet. Es ist ein Schuss in die Dunkelheit, aber wo bekommt man mehrere Abonnements?

Wie auch immer, ich würde gerne weiter helfen, wenn Sie eine bestimmte Frage haben, die ich beantworten kann.

+0

Ich denke, dass Sie hier auf etwas sein können. Was ich denke, ich sollte trennen die Listen-Methode, und nicht im Antwort-Callback für erfolgreiche Anfrage haben ... Dies ist wahrscheinlich, was das Problem verursacht - ich brauche eigentlich keine Antwort Rückruf, nur ein Fehler Rückruf und auf das Ereignis außerhalb der Anfrage zu hören, um ein Überabonnement zu vermeiden. Danke dafür, ich werde es versuchen und Sie wissen lassen! –

+0

@ A.Appleby Das sieht mir auch wahrscheinlich. –

+0

@ A.Appleby Wie geht es? Hast du es gelöst? Kann ich helfen? –

Verwandte Themen