2

I've researched this for almost 2 days now and can't seem to find an answer. I am trying to build an app where I use sockets to notify my front end that something has changed on the server. Note - I am not using any action on the front end (so this makes this question different from the one such as what's found on this thread for example: socket.io emits multiple times)

Unfortunately the socket.io on the server side fires the same event multiple times. From everything I have read I understand this is because the connection stays open and every-time the server restarts it fires a connection. There should be a way for me to prevent it from emiting a duplicate event, but I can't seem to figure it out.

Here is my server side code:

// main file
const express = require('express');
const app = express();
const routes = require('./routes/index');

const server = app.listen(process.env.PORT || 3001, () => {
  console.log('listening on port 3001');
});

const io = require('socket.io')(server);
app.use('/sockets', socketFile(io))

module.exports = app;

// socketFile (same directory)

module.exports = function(io){

    var express = require('express');
    var router = express.Router();
    var request_m = require('request')

    router.post('/', function(req,res, next){

        const custom_message = req.body.custom_message

        io.sockets.emit('newMessage', {call: custom_message})

        next();  

    })
    return router
}

Her is the front end:

import React, {Component} from 'react';
import io from 'socket.io-client'
const socket = io('/');

class App extends Component  {
 constructor(){
   super()
 this.state={

 }
}

componentDidMount(){
  socket.on('newMessage', function (data) {
    this.setState({newMessage: data.call})
  }
}


render(){
  return (

    <div>        </div>

);
}

}

export default App;

thank you All!

an additional note: in the socketFile I did also originally have

io.on('connection', function(socket){
   ...
})

but that seemed unnecessary since I don't need to listen for anything, and only emit when that router is hit by an external api. in any case the result was the same. To be clear, what happens is that when the route in socketFile is accessed and it now has a custom_message (let's call it 'hello world')...the server emits 'hello world' twice.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
user3621334
  • 143
  • 3
  • 6
  • Do you call `componentDidMount()` more than once? If so, you are creating more than once listener for the same message. So, you aren't actually receiving multiple messages, but instead have multiple listeners for that message. When the single message arrives, you process it more than once. You can put a `console.log("calling componentDidMount()")` inside `componentDidMount()` to see for sure if this is happening. – jfriend00 Jul 04 '17 at 15:27
  • Also, this line of code `app.use('/sockets', socketFile(io))` looks questionable. Does `socketFile(io)` return a function that works as middleware? – jfriend00 Jul 04 '17 at 17:06
  • @jfriend00 thank you for helping to problem solve. I tried it without anything in componentdidmount (essentially removing the listener all-together) and the behavior is the same. it's the server that's firing multiple times, whether or not a listener is present. with regard to your question on socketFile --> you can see the file in the original post above, it returns router which should work fine I believe. – user3621334 Jul 04 '17 at 20:35
  • Well, the server code you show does not fire the event twice so there must be more to it than you have disclosed. Also, you have a `router.post()` that does not send a response and calls `next()`. That would imply that you're using it as middleware and the actual `.post()` response is sent elsewhere in your code. – jfriend00 Jul 04 '17 at 21:32
  • ugh, you're right. I condensed that router code to show the essence of the function. I was not including a response or a status message which was leaving the server hanging. If you hadn't pointed this out I would have kept staring at my screen blindly. Thank you! – user3621334 Jul 05 '17 at 19:37
  • How does failing to send a response cause multiple `.emit()` to happen? I agree it was a problem not to send a response, but that doesn't seem like the cause of multiple `.emit()` unless you had some other error to that interacted with that. If you intend to handle the response, you should both send a response `res.send(...)` and you should not call `next()` - that will end the response chain. – jfriend00 Jul 05 '17 at 22:07
  • Did you ever get this resolved? Posting an answer can be helpful to others. – Ben in CA Apr 28 '22 at 17:33

0 Answers0