JKhan
JKhan

Reputation: 1297

socket io event fires multiple times

I have searched similar questions here but none of them work for me.

I know some people recommend not to use socket inside another event but I had no clue how to trigger socket whenever there is an event.

So I have initialized socket inside another event which is updated every time something happens. But socket connection repeats the previous result with every new update.

I tried initializing socket within componentDidMount lifecyle and it simply does not work.

class UploadComponent extends Component {
  constructor (props) {
    super(props);

    this.state = {
      endpoint: "http://localhost:3000",
    }

    this.uploadModal = this.uploadModal.bind(this);
  }

  uploadModal () {

     update.on('success', file => {
          let {endpoint} = this.state;
          let socket = socketIOClient(endpoint, {transports: ['websocket', 'polling', 'flashsocket']});

          socket.on('data', (mydata) => {
            console.log(mydata) // <-- This gets fired multiple times.
          })
      })

   }

// some more code //
}

I want to trigger socket whenever "update" event is fired without message duplication.

Upvotes: 1

Views: 2858

Answers (3)

Rohit
Rohit

Reputation: 11

As sockets are emitting multiple times on Angular with nodejs happened the same with me for sockets, i tried by removing the socket listeners by this.socket.removeListener( "Your On Event" );,

This helped me solved the issue of multiple socket calls, try it, it may help !

Upvotes: 1

JKhan
JKhan

Reputation: 1297

As James have suggested I have put my socket logic in the constructor. But it was only being fired after my component remounts.

After looking at my nodejs server code I tried to replace

// some code //
io.on('connection', (client) => {
  client.emit('data', { 
              image: true, 
              buffer: imageBuffer.toString('base64'),
              fileName: meta.name
  })
})

with this


// some code //
io.emit('data', { 
   image: true, 
   buffer: imageBuffer.toString('base64'),
   fileName: meta.name
})

and it works!

Also I had to close socket in componentWillUnmount to avoid multiple repeated data.

Upvotes: 0

James
James

Reputation: 82136

Unless you can guarantee success is called only once, then you'll need to initialize the socket connection / event handler outside this function

class UploadComponent extends Component {
  constructor (props) {
    super(props);

    const endpoint = "http://localhost:3000";
    this.state = { endpoint };

    this.uploadModal = this.uploadModal.bind(this);
    this.socket = socketIOClient(endpoint, {transports: ['websocket', 'polling', 'flashsocket']});
    this.socket.on('data', (mydata) => {
        console.log(mydata)
    })
  }

  uploadModal() {
    update.on('success', file => {
     // this.socket.emit perhaps?  
    })
  }
}

Upvotes: 0

Related Questions