[英]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.