【问题标题】:Socket.io emit event multiple timesSocket.io 多次发出事件
【发布时间】:2021-12-31 02:43:22
【问题描述】:

例如,当我加入 room-1 然后 room-2 然后 room-3 并在 room-3 中发送消息时,该消息将被发送 3 次,而它应该只发送一次。我在客户端使用 vanilla JavaScript

服务器端

namespaces.forEach(namespace => {
  // join namespace
  io.of(namespace.endpoint).on('connection', socket => {

    console.log(`${socket.id} has joined the ${namespace.endpoint}`)
    socket.emit('nsRooms', {data: namespace.rooms})
    // Join room
    socket.on('joinRoom', async (payload, cb) => {
      const room = Array.from(socket.rooms)[1]
      room && socket.leave(room)
      socket.join(payload.data.roomName)
      const numOfMem = await io.of(payload.data.nsp).in(payload.data.roomName).allSockets()
      cb(Array.from(numOfMem).length)
    })

    socket.on('sendMessage', payload => {
      const room = Array.from(socket.rooms)[1]
      const nsp =  socket.nsp.name
      io.of(nsp).to(room).emit('updateMessage', payload)
    })

  })
})

客户端\
这是我加入房间并发送消息的时候

function joinRoom(roomName) {
  form.removeEventListener('submit', e => submitMsg(e))
  nsSocket.emit('joinRoom', {data: {nsp: nsSocket.nsp, roomName}}, numberOfMember => {
    document.getElementById('current-room').innerHTML = `<span class="curr-room-text">${roomName}</span> <span class="curr-room-num-users">Users: ${numberOfMember}<span class="glyphicon glyphicon-user"></span></span>`
  })

  messages.innerHTML = ''
  nsSocket.on('updateMessage', payload => {
    messages.innerHTML += 
    `
        <li>
          <div class="user-image">
              <img src="https://via.placeholder.com/30" />
          </div>
          <div class="user-message">
              <div class="user-name-time">rbunch <span>${new Date(Date.now()).toDateString()}</span></div>
              <div class="message-text">${payload.data}</div>
          </div>
        </li>
    `
  })
}

form.addEventListener('submit', e => submitMsg(e))

function submitMsg(e) {
  e.preventDefault()
  const msg = userMessage.value
  msg.length > 0 && nsSocket.emit('sendMessage', {data: msg})
  userMessage.value = ''
}

【问题讨论】:

    标签: javascript node.js websocket socket.io eventemitter


    【解决方案1】:

    发生这种情况是因为removeEventListener 需要使用已注册的完全相同的函数引用,并且(e) =&gt; submitMsg(e) 始终创建一个新的 lambda。这意味着每次加入房间时,都会添加一个新的事件处理程序,而不会删除旧的。

    我使用以下代码创建了一个快速示例应用程序here,可以解决您的问题。如果你点击 'Join some room' 3 次,然后点击 'Send message',只会出现一个 console.log(展开右侧的控制台查看结果)。

    const testBtn = document.getElementById('joinRoom');
    const form = document.getElementById('chatForm');
    
    testBtn.addEventListener('click', () => {
      form.removeEventListener('submit', submitMsg);
    
      // ... some other code
    
      form.addEventListener('submit', submitMsg);
    });
    
    submitMsg = (e) => {
      e.preventDefault();
    
      console.log('submitMsg() called!');
    
      return false;
    }
    
    

    【讨论】:

      猜你喜欢
      • 2019-10-30
      • 1970-01-01
      • 1970-01-01
      • 2013-10-10
      • 1970-01-01
      • 2015-11-22
      • 2021-06-27
      • 1970-01-01
      • 2023-03-26
      相关资源
      最近更新 更多