2016-11-28 9 views
5

Tytuł pytania może być trochę zagmatwany, starałem się jak najlepiej to wyjaśnić.Echo powtarzające echo Laravel Echo dla n razy nadawano

Mam laravel-echo-server, redis (do kolejkowania) i Laravel echo skonfigurowałem. Chcę tylko wysłać wiadomość przez wejście i zaktualizować kanał wiadomości dla wszystkich na stronie; w zasadzie czat.

Wszystko działa, z wyjątkiem tego, że jest powolny jak diabli, ale jestem nowy w Laravel Echo i Vue.

jeśli wysłałem jedną wiadomość, jest w porządku, ale kiedy wysyłam kolejną wiadomość, otrzymuję dwie odpowiedzi. Wyślij trzecią wiadomość trzy odpowiedzi i tak dalej ...

Co dokładnie robię źle? Sprawdziłem, czy socket.io/// tylko łączy się z kanałem raz, a mój broadcast jest wysyłany tylko raz (sprawdzanie kolejki pracownik przetwarza tylko żądanie), więc w jaki sposób jest powtarzany wykładniczo?

To jest moje 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'] 
}); 

To mój czat widok:

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

Tylko w przypadku są one istotne tutaj jest mój trasa:

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

i mój wydarzenie:

<?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'); 
    } 
} 

Odpowiedz

2

Używam Redis PubSub we wniosku Jestem obecnie buduje i musieli walczyć ten sam problem. Chociaż nie znam wystarczająco dużego serwera laravel-echo, który mógłby doradzić ci konkretnie, jak to naprawić, mogę opisać prawdopodobną przyczynę tego objawu.

Twoja konfiguracja subskrybuje kanał Redis w każdym cyklu, a subskrypcja nie jest przejściowa. Za każdym razem, gdy subskrybujesz, tworzysz nowego słuchacza. Za każdym razem, gdy publikujesz, Redis wysyła wiadomość do wszystkich słuchaczy/subskrybentów. Jeśli jeden klient subskrybował trzy razy, otrzyma tę wiadomość trzy razy. Musisz rozpoznać, że jesteś subskrybentem, a nie duplikować go, lub musisz zrezygnować z subskrypcji po każdym cyklu.

Należy zwrócić uwagę na to, że instancja Redis powinna albo publikować, albo subskrybować, ale nie obie. laravel-echo-server prawdopodobnie sobie z tym poradzi.

Redis normalnie zwraca liczbę subskrybentów otrzymujących wiadomość w każdym wydaniu. Pomogło mi to zdiagnozować problem, zwłaszcza że używam prywatnych kanałów i powinienem mieć 1, i tylko 1, słuchacza dla każdej wiadomości. Redis ma również polecenie "numsub", które zwraca liczbę słuchaczy na kanale.

Zauważyłem, że twoja funkcja sendMessage używa metody nasłuchiwania. To strzał w ciemno, ale czy w którym masz wiele subskrypcji?

W każdym razie, chętnie pomogę, jeśli masz konkretne pytanie, na które mogę odpowiedzieć.

+0

Myślę, że możesz być na coś tutaj. Myślę, że powinienem oddzielić metodę nasłuchiwania i nie mieć jej w oddzwanianiu zwrotnym dla pomyślnego żądania ... To prawdopodobnie jest przyczyną problemu - nie potrzebuję oddzwaniania zwrotnego, tylko wywołania błędu i aby słuchać zdarzenia poza żądaniem, aby uniknąć nadmiernej subskrypcji. Dzięki za to, dam ci szansę i dam ci znać! –

+0

@ A.Appleby To również wygląda na mnie. –

+0

@ A.Appleby Jak leci? Czy rozwiązałeś to? Czy mogę pomóc? –