Socket.io sends two messages

一笑奈何 提交于 2020-08-08 06:29:07

问题


I'm trying to setup socket.io and here is part of my server.js

const app = require('express')();
const http = require('http').Server(app);
const io = require('socket.io')(http, { path: '/websocket', origins:'*:*' });

io.on('connection', (socket) => {
socket.send('Hi');
socket.on('message', (message) => {
    console.log(message);
    socket.emit('hello', `New: ${message}`);
});
    console.log('a user connected');
});

http.listen(3030, function(){
   console.log('listening on *:3030');
});

and my simple client:

var socket = io('https://*******.com', {
  secure: true,
  path: '/websocket'
});

const input = document.getElementById('text');
const button = document.getElementById('button');
const msg = document.getElementById('msg');

button.onclick = () => {
    socket.emit('message', input.value);
    socket.on('hello', (text) => {
        const el = document.createElement('p');
        el.innerHTML = text;
        msg.appendChild(el);
    })
}

And if I'll click for third time I receive a 3 messages back and so on. What I'm doing wrong? I wish to send message to the server and receive modified message back. I'm new in web sockets.

Any help appreciated.

P.S. socket.io v2.0.1


回答1:


You are adding a socket.on() event handler each time the button is clicked. So, after the button has been clicked twice, you have duplicate socket.on() event handlers. When the event comes back, your two event handlers will each get called and you will think you are getting duplicate messages. Actually, it's just one message, but with duplicate event handlers.

You pretty much never want to add an event handler inside another event handler because that leads to this sort of build-up of duplicate event handlers. You don't describe (in words) exactly what you're code is trying to do so I don't know exactly what alternative to suggest. Usually, you set up the event handlers first, just once, when the socket is connected and then you will never get duplicate handlers.

So, perhaps it's as simple as changing this:

button.onclick = () => {
    socket.emit('message', input.value);
    socket.on('hello', (text) => {
        const el = document.createElement('p');
        el.innerHTML = text;
        msg.appendChild(el);
    })
}

to this:

button.onclick = () => {
    socket.emit('message', input.value);
}

socket.on('hello', (text) => {
    const el = document.createElement('p');
    el.innerHTML = text;
    msg.appendChild(el);
});



回答2:


If you are using Angular and (probably) embedding the Socket in a Service (simpleton) you are creating a persistent listener in ngOnInit every time you load a page.

You need to create some kind of flag to know if the listener was already created in the Service from another instance of your page.



来源:https://stackoverflow.com/questions/44166273/socket-io-sends-two-messages

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!