probil / vue-socket.io-extended

:v::zap: Socket.io bindings for Vue.js and Vuex (inspired by Vue-Socket.io)
MIT License
629 stars 38 forks source link

Socket Emits Multiple Times when Each Time page re renders #518

Open eyesmarty opened 3 years ago

eyesmarty commented 3 years ago

When I leave component in which i have implemented socket.client.emit and visit that component again the emit event triggers twice if i do the same the emit event triggers three times and so on.

I am using it to implement webrtc and each time user visits that page emit event triggers that many times

Kindly Let me know how to solve this issue

i have tried this.$socket.client.off("created") but it doesn't seem to be working

Sample Code

methods: {
  onOffer(offer) {
      if (!this.creator) {
        this.rtcPeerConnection = new RTCPeerConnection(this.iceServers);
        this.rtcPeerConnection.onicecandidate = this.onIceCandidateFunction;
        // this.rtcPeerConnection.ontrack = onTrackFunction;
        this.rtcPeerConnection.addStream(this.userStream);
        this.rtcPeerConnection.setRemoteDescription(offer);
        this.rtcPeerConnection.createAnswer(
          (answer) => {
            this.rtcPeerConnection.setLocalDescription(answer);
            this.$socket.client.emit("answer", answer, this.roomName);
            console.log("answer")
          },
          (error) => {
            console.log(error);
          }
        );
      }
    },
 }

created(){
  this.$socket.$subscribe("offer", (offer) => {
    console.log("offer");
    this.onOffer(offer);
  });
}

the answer event is triggered as many times as many times the component is re-rendered I have been stuck in this issue since long time kindle provide some guidence

Thanks in Advance

Kamran95 commented 3 years ago

I have been facing same issue But Haven't found any solution yet

UsmanGul commented 3 years ago

I have been facing same issue.....

probil commented 3 years ago

Hey @eyesmarty It's been a while since you've created the issue. Unfortunately I didn't have time to respond earlier.

Speaking about the issue, you might need to change the configuration a bit. created hooks is a bit tricky to understand. It's not called just once but every time the component is supposed to render on the page. Thus you create a new subscription every time. That's why socket emits multiple times for you - you never unsubscribe but subscribe more and more.

There multiple ways to avoid this: 1) Provide proper unsubscribe strategy when component is being destroyed

created(){
  // in addition to this line
  this.$socket.$subscribe("offer", (offer) => {
    console.log("offer");
    this.onOffer(offer);
  });
},

beforeDestroy() {
  // you always need this one
  this.$socket.$unsubscribe("offer");
}

2) The aforementioned syntax is tough, right? That's not vary much different from raw socket.io-client usage. That wasn't the intention of this library. The point was to make life simpler. That's why sockets key was introduced. When you define methods there it takes care of unsubscription automatically - so no need to worry about it. Therefore, the same code can be rewritten into a neater one:

sockets: {
  offer(offer) { // `offer()` is the name of the even you'd want to subscribe to
      console.log("offer");
      this.onOffer(offer);
  }
}

You can even inline all your code here (no need for onOffer, unless you don't need to call it from other functions):

sockets: {
  offer(offer) {
    if (this.creator) return;

    this.rtcPeerConnection = new RTCPeerConnection(this.iceServers);
    this.rtcPeerConnection.onicecandidate = this.onIceCandidateFunction;
    // this.rtcPeerConnection.ontrack = onTrackFunction;
    this.rtcPeerConnection.addStream(this.userStream);
    this.rtcPeerConnection.setRemoteDescription(offer);
    this.rtcPeerConnection.createAnswer(
      (answer) => {
        this.rtcPeerConnection.setLocalDescription(answer);
        this.$socket.client.emit("answer", answer, this.roomName);
        console.log("answer")
      },
      (error) => {
        console.log(error);
      }
    );
  }
},

Let me know if it helped to resolve your issue. Anyway, I'll add this point to the docs in order to help others.