vue-socket.io-extended icon indicating copy to clipboard operation
vue-socket.io-extended copied to clipboard

Socket Emits Multiple Times when Each Time page re renders

Open eyesmarty opened this issue 5 years ago • 3 comments

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

eyesmarty avatar Feb 19 '21 06:02 eyesmarty

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

Kamran95 avatar Feb 19 '21 06:02 Kamran95

I have been facing same issue.....

UsmanGul avatar Feb 19 '21 06:02 UsmanGul

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");
}
  1. 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.

probil avatar Apr 25 '21 07:04 probil