0

I am building a little topic/chat for our application with socket.io in an ionic app. My problem is that each time I create a new topic, I end up with one more first message in the topic, a screenshot will explain it better : My list of topics

First time I create a topic after launching my app

Second time

I don't need to submit the new topic actually, just pushing to the add-topic page (or leaving it?) is triggering the "new event?" resulting in adding a new message.

Here is my add-topic page (the concerned part) :

  constructor(public navCtrl: NavController,
          public navParams: NavParams,
          public chatService: ChatService,
          private socket: Socket,
          public events: Events) {

            this.socket.on('add-message', (data) => {
              console.log("recu la reponse = " + JSON.stringify(data));
              this.chatService.sendMsg(data);
            });

            this.chatService.getUserInfo()
            .then((res) => {
                this.user = res
            });
}

this.chatService.sendSalon(newSalon, newMsg)
.then(() => {
  console.log("Message envoyé et contenu : " + newSalon);
  this.navCtrl.setRoot(ChatListPage);
})

Here is the server code :

io.on('connection', (socket) => {

console.log("socket-chat-connection");

//Receive a salon
socket.on('add-salon', (envoi) => {
salon = envoi.salon;
message = envoi.message;
salon._id = new ObjectID();

db.collection("chatSalons", function(err, collection) {
  collection.save(salon, function(err, result) {
    if(err) {
      console.log('parse : err2 ' + err);
    }
    message.chatId = new ObjectID(salon._id);
    console.log("message.chatId = " + JSON.stringify(message));
    socket.emit('add-message', message);
  });
});
io.emit('salon-received', {text: salon.title, from: salon.userId, created: new Date()});
});
//Receive a message
socket.on('add-message', (message) => {
  message._id = new ObjectID();

  console.log("debut message = " + JSON.stringify(message));

  db.collection("chatMsgs", function(err, collection) {
      collection.save(message,  function(err, result) {
          if (err) {console.log('parse :err1'+err);}
      });
  });
  io.emit('message-received', {text: message.message, from: message.userId, created: new Date()});

});


});

And here are the Chat Service lines handling sending to the server :

mockNewSalon(salon, message) {
  setTimeout(() => {
      console.log(salon);
      console.log("contenu message avant envoi vers le serveur = " + JSON.stringify(message));
      this.socket.emit('add-salon', {salon, message});
  }, Math.random() * 50);
}

mockNewMsg(msg) {

  setTimeout(() => {
      console.log(msg)
      this.socket.emit('add-message', msg);
      //this.events.publish('chat:received', mockMsg, Date.now())
  }, Math.random() * 50)
}

  sendSalon(salon: ChatSalon, message: ChatMessage) {
  console.log("chat service sendSalon = " + salon);
  return new Promise(resolve => setTimeout(() => resolve(salon), Math.random() * 1000))
  .then(() => this.mockNewSalon(salon, message));
}

sendMsg(msg: ChatMessage) {
  return new Promise(resolve => setTimeout(() => resolve(msg), Math.random() * 1000))
  .then(() => this.mockNewMsg(msg));
}

Sorry for the weird code presentation. So, first I send the topic (salon), when the server is done saving it to the database, it emits back the message with the id of this new topic and then the client send the message as it would if he was actually in the topic which is the normal way of using it. Also, before I had the trouble with two users (one in my browser, one on my iPhone) : if I created a topic in my browser and then on my iPhone, the iPhone would send two first messages. I fixed this by changing

io.emit('add-message', message);

by

socket.emit('add-message', message);
  • I'm having trouble following what's going on with the code, particularly the distinction between Topics and Messages. However, this [Stack Overflow summary](https://stackoverflow.com/a/10099325/7316502) of the different types of Socket.io transmissions might be useful. `io.emit` sends to all clients, including the sender. If you have client code that updates its own view when a client sends a message *and* responds to that message from the server, this will result in duplication. – thmsdnnr Jan 08 '18 at 15:48
  • I haven't copy/paste everything, only the part where I send a topic to the server, the server saves it in the database and emits back the add-message event to the client, then the client send back the first message of this topic. –  Jan 08 '18 at 16:12
  • I did change io.emit to socket.emit so that only the client sending the topic will receive the response back and it did fixed on of my problems. But I don't understand why I am getting more and more first messages when I enter my add-topic page. If I just go in add-topic page and return back to the topic list 5 times right at the launch of my app, then I will send 5 first messages the first time I send a topic. I thought I created a new socket each time I entered the add-topic page but watching over the server with nodemon and a console.log("socket-chat-connec") told me it isn't the case. –  Jan 08 '18 at 16:19

1 Answers1

0

I think I found the problem and fixed it, I am just not sure it is the proper way but that will do. It was indeed the fact that I entered the add-topic page each time that started a whole new page and so a new socket.on listener. I thought I could "delete" the page just by going back with the ionic function this.navCtrl.pop(); but the problem remained.

So I removed the listener with socket.removeListener('add-message'); I am not sure how bad it can be to leave a new page with a socket in it each time I push to this page but optimisation will come later.