簡體   English   中英

Socket.io 多次發出事件

[英]Socket.io emit event multiple times

例如,當我加入 room-1 然后 room-2 然后 room-3 並在 room-3 中發送消息時,該消息將被發送 3 次,而它應該只發送一次。 我在客戶端使用香草 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 = ''
}

發生這種情況是因為removeEventListener需要使用已注冊的完全相同的 function 引用,並且(e) => submitMsg(e)創建一個新的 lambda。 這意味着每次加入房間時,都會添加一個新的事件處理程序,而不會刪除舊的事件處理程序。

我在這里使用以下代碼創建了一個快速示例應用程序,可以解決您的問題。 如果你點擊 '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;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM