2014-11-04 83 views
2

首先抱歉,我不是母語英語,並感謝您的興趣!我不知道爲什麼當我對數組執行一些半重操作時,我的瀏覽器斷開與Socket.io的連接。瀏覽器收到斷開連接事件,然後重新連接,但不應該首先斷開連接。爲什麼我的代碼在Node中斷開Socket.io連接?

該代碼包含一對嵌套循環,我知道這不是最好的做法,但我沒有找到任何其他方式來完成任務。我開始測試大型用戶陣列(大約10k)並且問題開始發生,所以我想這是一個性能問題。

我試圖找到內存韭菜,但沒有成功,它幾乎像執行操作應用程序凍結和打破Socket.io時。

謝謝你試圖幫助。

var pushUsersToCorrectLeagues = function(appConfig, callback, usersArray, newSeason, db) { 
    //determinate which league is the last one 
    var leaguesOrderArray = []; 
    _.each(newSeason.leagues, function(league) { 
     leaguesOrderArray.push(league.key); 
     return false; 
    }); 

    var lastLeagueKey = _.last(leaguesOrderArray.sort(function(a, b) { 
     return a - b; 
    })); 

    _.each(usersArray, function(user) { 
     var keyUserData = {}; 
     keyUserData.userLogin = user.userLogin; 
     keyUserData._id = user._id; 
     keyUserData.avatarUrl = user.avatarUrl; 
     keyUserData.isActive = true; 
     keyUserData.scores = {}; 

     //now put users in correct leagues 
     var userPushed = false; 
     var endedInLeague = null; 


     //if found a user in league 
     _.each(newSeason.leagues, function(league) { 
      _.find(league.users, function(alredyInLeagueUser, i) { 
       if (alredyInLeagueUser.userLogin == user.userLogin) { 
        newSeason.leagues[league.key].users[i] = keyUserData; 
        userPushed = true; 
        endedInLeague = league.key; 
        return true; 
       } 
      }); 

      return false; 
     }); 

     //user wasnt found in any league, has to be pushed to the last one then 
     if (!userPushed) { 
      newSeason.leagues[lastLeagueKey].users.push(keyUserData); 
      endedInLeague = lastLeagueKey; 
     } 

     if (endedInLeague) { 
      process.nextTick(function() { 
       var callback = function(updatedUser) { 
        //console.log('updatedUser', updatedUser); 
        return false; 
       }; 
       updateUserCurrentLeague(callback, user._id, endedInLeague, db); 
      }); 
     } 

     return false; 
    }); 

    callback(usersArray, newSeason); 
    return false; 
}; 
+1

你的時間密集型操作持續多久?客戶端和服務器交換心跳包,並且如果一端很長時間沒有響應,那麼可能一端因爲心跳尚未處理而認爲它已斷開連接? – jfriend00 2014-11-04 23:55:28

+0

約10k用戶在當前設置上花了6秒鐘。我將心跳超時設置降低到5秒我想這是問題所在。我該如何解決它? – youbetternot 2014-11-05 00:13:04

+0

和6秒似乎是很多的方式,我想我需要找到一個更好的方式來完成這項任務,你有什麼建議嗎? – youbetternot 2014-11-05 00:22:56

回答

1

這聽起來像你的操作比插座心跳間隔要長,因此連接的一端認爲連接已斷開。

您有以下選擇:

  1. 可以拉長(其實只是一個創可貼,而不是最好的解決)插槽上的心跳間隔。
  2. 您可以將耗時的節點操作卸載到子進程並讓它運行,收集結果並將結果以JSON形式發回。這使您的主節點進程始終保持響應。
  3. 您可以將耗時的操作分成塊,其中每個塊的運行時間不超過500毫秒,然後服務器可以在耗時的操作進行時處理其他事件。這需要重新處理處理事物的方式,因爲您無法使用.each()循環。相反,您必須在某處存儲某個狀態,使用計數器,執行一定量的工作,更新狀態,設置計時器在其他事件處理完成後執行其他工作,完成另一部分工作,重複執行,直到完成所有工作。

僅供參考,下面是如何處理一個非常大的陣列的示例:Best way to iterate over an array without blocking the UI。這是針對瀏覽器編碼的,但節點中的概念是相同的。

+0

謝謝,這看起來很棒!這個問題就像你說的由心跳超時引起的。我會在明天嘗試選項二和三。十分感謝! – youbetternot 2014-11-05 00:37:01

相關問題