Socket.io vydávat akce vícekrát

0

Otázka

například, když jsem se vstoupit do místnosti-1 pokoj-2 místnosti-3 a odesílat zprávy v místnosti-3, které zprávy budou emitovány 3 krát, když je třeba pošlou jen jednou. používám vanilkovou JavaScript na straně klienta

na straně serveru

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

  })
})

na straně klienta \
Tady je když jsem se připojit pokoje a posílat zprávy

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 = ''
}

1

Nejlepší odpověď

0

To se děje proto, removeEventListener potřebuje pracovat s přesně stejné funkce referenční, která byla zapsána, a (e) => submitMsg(e) vytvoří novou lambda celou dobu. Což znamená, že pokaždé, když vstoupíte do místnosti, nový event handler bude přidáno, bez odstranění staré.

Vytvořil jsem rychlý vzorek aplikace, zde s následující kód, který by se opravit váš problém. Pokud klepnete na tlačítko 'Připojit k některé místnosti tři krát a potom klepněte na tlačítko "Odeslat zprávu", pouze jednu konzoli.log se objeví (rozšíření konzole na pravé straně vidět výsledek).

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

2021-11-20 23:27:13

V jiných jazycích

Tato stránka je v jiných jazycích

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................