2012-01-31 37 views
12

我做了基於網絡的簡單網絡遊戲。該遊戲使用Socket.io互相進行網絡互動。 但我遇到了這個問題。如何在Socket.io中處理Close事件?

想想下面的情況。 我運行了Socket.io服務器。一個玩家進入房間,另一個玩家加入房間。 他們玩遊戲一段時間.. 但一個球員如此憤怒和關閉遊戲選項卡。

在這種情況下

,我怎麼能得到其中的一個客戶端已關閉在服務器端瀏覽器中的事件?

根據谷歌搜索,人們這樣說:「使用瀏覽器的關閉事件像onBeforeUnload」

,但我知道,所有的瀏覽器不支持onbeforeunload事件。所以我想解決有關 檢查服務器端,客戶端斷開事件。

在Socket.io(的NodeJS)服務器端的控制檯,當客戶端連接關閉,控制檯說,像以下:

調試 - 丟棄運輸

我的版本的NodeJS是0.4.10和Socket.io版本是0.8.7。並且都在Linux上運行。

任何人都可以幫助嗎?

shortend碼在這裏:

var io = require ("socket.io").listen (3335); 
io.sockets.on ("connection" , function (socket) 
{ 
    socket.on ("req_create_room" , function (roomId) 
    { 
    var socketInstance = io 
    .of ("/" + roomId) 
    .on ("connection" , function (sock) 
    { 
     sock.on ("disconnect" , function() 
     { 
      // i want this socket data always displayed... 
      // but first-connected-client doesn't fire this event .. 
      console.log (sock); 
     } 
    }); 
    }); 
}); 
+0

我的回答對您有幫助嗎?它解決了你的問題嗎? – 2015-03-13 21:10:22

回答

7

有一個事件disconnect它將觸發每當socket.io連接死亡(請注意,你需要這個,因爲你仍然可以有一個WEP頁面打開,但如果你的互聯網連接死了?)。試試這個:

var io = require('socket.io').listen(80); 

io.sockets.on('connection', function (socket) { 
    socket.on('disconnect', function() { 
    io.sockets.emit('user disconnected'); 
    }); 
}); 

在你的服務器上。採取從Socket.IO website

//編輯

所以,我看着你的代碼,並在我家做了一些測試。我得到了和你一樣的結果,這裏是我的解釋。您試圖通過動態強制它偵聽不同的URL(它們在運行時添加)來使Socket.IO非常動態。但是,當第一次連接時,服務器不會聽其他網址。看起來恰好在那時(當連接被接受時)disconnect處理程序爲第一個連接設置,並且稍後不更新(請注意,當您在客戶端多次調用io.connect時,Socket.IO不會創建新連接) 。總而言之,這似乎是一個錯誤!或者也許有一些奇怪的解釋,爲什麼這種行爲應該是這樣,但我不知道。

讓我告訴你一些其他的事情。首先,這種傾聽者的動態創造似乎不是一個好方法。在我看來,你應該做以下事情:存儲現有的房間,併爲他們全部使用一個網址。保留一個房間的ID,當你發出一個房間的ID號,例如message事件添加到數據,並在服務器處理一個message處理程序。我想你應該已經明白了。將動態部分推入數據中,而不是網址。但我可能是錯的,至少這是我的看法。

另一件事是,你寫的代碼似乎是不好的。請注意,多次運行.on('connection', handler)會使其多次啓動。處理程序將堆疊到另一個上,它們不會互相替換。所以這是我將如何實現這一點:

var io = require("socket.io").listen(app); 
var roomIds = []; 

function update_listeners(id) { 
    io.of("/"+id).on("connection", function(socket) { 
     console.log("I'm in room " + id); 
     socket.on("disconnect", function(s) { 
      console.log("Disconnected from " + roomId); 
     });    
    }); 
} 

var test = io.sockets.on("connection", function(socket) { 
    console.log("I'm in global connection handler"); 
    socket.on("req_create_room", function(data) { 
     if (roomIds.indexOf(data.roomId) == -1) { 
      roomIds.push(data.roomId); 
      update_listeners(data.roomId);  
     } 
     test.emit("room_created", {ok:true}); 
    }); 
    socket.on("disconnect", function(s) { 
     console.log("Disconnected from global handler"); 
    }); 
}); 

請與創建偵聽器之前連接的問題被定義仍將occure頭腦。

+0

謝謝!有用。但我仍然在這裏有一些問題......關於「斷開」事件火災很好,但除了第一連接客戶端。我想知道爲什麼第一連接客戶端無法觸發「斷開連接」事件? – 2012-02-01 05:22:57

+0

不知道。發佈一些代碼,我們會看到。 – freakish 2012-02-01 07:34:35

+0

我發佈了代碼。這是ebridged版本..謝謝你的幫助 – 2012-02-01 09:06:37

17

更新:我爲此解決方案創建了a blog post。歡迎任何反饋!

我建議在Socket IO上使用'卸載同步斷開連接'選項。我有類似的問題,這真的幫助我。

在客戶端:

var socket = io.connect(<your_url>, { 
'sync disconnect on unload': true }); 

無需導線在任何卸載beforeunload事件。在幾個瀏覽器中嘗試了這一點,並且迄今爲止完美運行。

+1

你先生已經度過了我的一天。我浪費了7個小時試圖找到解決這個問題的辦法! – 2013-06-18 20:44:48

+0

鏈接發佈,而不是博客請 – laggingreflex 2014-07-06 21:42:11

+0

我更新了鏈接網址。 – 2015-03-13 21:09:44