【问题标题】:Socket.io sends two messagesSocket.io 发送两条消息
【发布时间】:2020-08-03 04:39:29
【问题描述】:

我正在尝试设置 socket.io,这是我的 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');
});

还有我的简单客户:

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);
    })
}

如果我第三次点击,我会收到 3 条消息,依此类推。我做错了什么?我希望向服务器发送消息并接收修改后的消息。 我是网络套接字的新手。

任何帮助表示赞赏。

附: socket.io v2.0.1

【问题讨论】:

    标签: websocket socket.io


    【解决方案1】:

    每次单击按钮时,您都会添加一个socket.on() 事件处理程序。因此,在单击按钮两次后,您将拥有重复的 socket.on() 事件处理程序。当事件返回时,您的两个事件处理程序将分别被调用,您会认为您收到了重复的消息。实际上,它只是一条消息,但具有重复的事件处理程序。

    您几乎不想在另一个事件处理程序中添加一个事件处理程序,因为这会导致这种重复事件处理程序的堆积。你没有(用语言)准确地描述你的代码试图做什么,所以我不知道确切的建议是什么。通常,您首先设置事件处理程序,只设置一次,当套接字连接时,您将永远不会得到重复的处理程序。

    所以,也许就像改变这个一样简单:

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

    到这里:

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

    【讨论】:

    • 谢谢!你拯救了我的一天。
    • @jfriend00 太棒了......你拯救了我们的一天。
    【解决方案2】:

    如果您使用 Angular 并且(可能)将 Socket 嵌入到服务中(简单实例),那么您每次加载页面时都会在 ngOnInit 中创建一个持久监听器。

    您需要创建某种标志来了解侦听器是否已在服务中从您页面的另一个实例中创建。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-08-17
      • 1970-01-01
      • 2018-12-24
      • 2014-01-05
      • 1970-01-01
      • 2018-01-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多