簡體   English   中英

Socket.io句柄同步接收

[英]Socket.io handle receiving synchronously

由於某些原因,socket.io在這方面實在是太痛苦了。 我在這個問題上待了大約一個小時,而且他們在網上的任何地方都沒有太多信息,因為JavaScript是同步的,因此很難找到有關此事件的信息。

所以基本上,我像其他任何程序員一樣在socket.io中接收斷開連接,如下所示:

client.on('disconnect', function() {
    console.log("Client left");
    removeClient(client);
    console.log("Client completely removed");
  });

現在,這就是問題所在。 用戶斷開連接,並且可以正常工作,除非多個用戶彼此緊接斷開連接。 我使用了調試消息,這就是正在發生的事情。

場景:我們有兩個用戶同時離開。 用戶離開時,它將在服務器上運行5種不同的功能。

USER1離開:

功能1。
功能2。
功能3。
USER2離開:
功能1。
功能2。
功能3。
功能4。
功能5。
用戶2已成功完全離開
功能4。
功能5。
用戶1已成功完全離開

問題:由於某種原因,在刪除用戶1時,它將與用戶2斷開連接,然后開始刪除用戶2。我正在嘗試這樣做,以便在服務器刪除用戶1時如果用戶2斷開連接,它將等待直到為用戶2執行5個功能為止,然后再為用戶2執行它們。

編輯:標題說“正在接收”而不是斷開連接,因為它將對任何事件執行此操作。

當您不顯示相關代碼時,很難提出一個代碼修復建議,但是如果根據您的評論,問題是當您在迭代過程中時,陣列會從您的下方變出來,然后處理的典型方法是為迭代而制作數組的臨時副本 這樣,您的副本就不會更改。 如果您需要檢查套接字是否已從原始陣列中刪除,則也可以進行檢查。

這是想法:

// suppose your array of sockets is in socketList

// make a copy of the sockets array
var copyList = socketList.slice(0);
var socket;

for (var i = 0; i < copyList.length; i++) {
    socket = copyList[i];
    // make sure this socket is still in the original array
    if (socketList.indexOf(socket) !== -1) {
        // do your operation here on socket
    }
}

如果使用的是對象而不是數組來存儲套接字列表,則可以使用Object.keys()預取鍵並迭代這些鍵,以檢查在時間到時該鍵是否仍在對象中處理它。

僅供參考,我自己還沒有證明這一點,但是.forEach()的MDN文檔建議,使用它來迭代數組也.forEach()並發修改。 由於我們沒有確切的代碼,因此我不確切知道它的行為,因此我可能寧願使用上面的我自己的副本。

造成這種情況的可能原因還在於,您實際上擁有異步運行的異步代碼。 這意味着您必須在調用堆棧上上下移動,然后才能調用其他任何處理程序。 您可以強制堆棧松開,然后使用process.nextTick繼續執行,但應該注意性能后果,因為我認為在一個周期內可以發生多少次回調,而其余的會排隊則是有限的。

var callback = function (err, data) {
   // will now be next on the stack
   process.nextTick(function() {
        // will be on a clean(ish) stack
   });
}
a(callback); // should be async but is sync 

暫無
暫無

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

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