2013-10-03 97 views
6

我試圖學習節點並開始創建與socket.io混搭 消息傳輸已經開始,但我遇到了一些麻煩。Socket.io消息事件觸發多次

消息事件觸發多次,導致單個消息在接收者的方框上多次出現。我已經將套接字路由到exports.chat,並想知道是否會導致問題?

爲了縮小問題的範圍:消息正在觸發次數=客戶端的連接順序。也就是說,如果客戶端連接第二個,他的消息將會觸發兩次。連接第三個客戶三次。

這裏是代碼片段:

exports.chat = function(io, pseudoArray, req, res){ 
    res.render('chat', {title: 'ChatPanel.'}); 

     var users = 0; 

     io.sockets.on('connection', function (socket) { // First connection 
      users += 1; 
     // reloadUsers(io, users); 

      socket.on('message', function (data) { // Broadcast the message to all 
       if(pseudoSet(socket)) { 
        var transmit = {date : new Date().toISOString(), pseudo : returnPseudo(socket), message : data}; 
        socket.broadcast.emit('message', transmit); 
        console.log("user "+ transmit['pseudo'] +" said \""+data+"\""); 
       } 
      }); 

      socket.set('pseudo', req.session.user, function(){ 
       pseudoArray.push(req.session.user); 
       socket.emit('pseudoStatus', 'ok'); 
       console.log("user " + req.session.user + " connected"); 
      }); 

      socket.on('disconnect', function() { // Disconnection of the client 
       users -= 1; 
      // reloadUsers(); 
       if (pseudoSet(socket)) { 
        var pseudo; 
        socket.get('pseudo', function(err, name) { 
         pseudo = name; 
        }); 
        var index = pseudoArray.indexOf(pseudo); 
        pseudo.slice(index - 1, 1); 
       } 
      }); 
     }); 
}; 
+0

在您的斷開連接處理程序中:帶pseudo.slice的部分應位於getter處理程序中。 –

回答

5

socket.io代碼的整個部分都必須在external.chat函數外面。套接字IO必須與http/app服務器綁定,你不應該在每個請求中處理它。

消息被射擊的次數=客戶端的連接順序

什麼本質上發生的事情是,每一個新的請求到達您註冊的消息的事件處理程序的時間,因此它被激發的次數與您訪問聊天網址的次數相同。

io.socket.on('message', function (data) {...}) 
+11

這個問題如何解決? – sniper

+0

我也面臨同樣的問題有人可以幫助我解決這個問題,當我將我的代碼更改爲'io.sockets.on('message''它不起作用 –

1

我覺得這個行爲不端是因爲你試圖使用內置/保留的事件名稱「消息」的少數之一爲應用專用消息。要確認,請將您的活動名稱更改爲「message2」或其他內容,並查看問題是否消失。我相信至少「連接」,「斷開」和「消息」保留。 https://github.com/LearnBoost/socket.io/wiki/Exposed-events

1

所以我有同樣的問題。該解決方案是關閉的socket.on所有聽衆(「斷開」)事件,這是我的代碼看起來像 -

socket.on('disconnect', function() { 
       socket.removeAllListeners('send message'); 
       socket.removeAllListeners('disconnect'); 
       io.removeAllListeners('connection'); 
      }); 

可能不需要調用它斷開,不知道,但我這樣做無論如何。

+0

這實際上並沒有解決問題什麼時候第二個客戶端登錄..只是當一個客戶端斷開連接。仍然沒有解決我的問題:/ – joe