2012-02-14 37 views
4

我一直有一些問題與我拼湊在一起的下面的代碼。所有的事件都像廣告一樣工作,但是,如果客戶沒有首先斷開關閉事件而脫機,就不會馬上接通電話。如果你給它一分鐘左右它最終會被調用。另外,我發現如果我繼續向客戶端發送數據,它會更快地收到關閉事件,但永遠不會馬上。最後,如果客戶端正常斷開連接,那麼結束事件就會被調用。Nodejs Websocket被稱爲...最終的事件

我知道這與升級和ondata等其他聽事件有關。

我還應該說客戶端是嵌入式設備。

client http request: 
GET /demo HTTP/1.1\r\n 
Host: example.com\r\n 
Upgrade: Websocket\r\n 
Connection: Upgrade\r\n\r\n 


//nodejs server (I'm using version 6.6) 
var http = require('http'); 
var net = require('net'); 
var sys = require("util"); 

var srv = http.createServer(function (req, res){ 
}); 

srv.on('upgrade', function(req, socket, upgradeHead) { 

    socket.write('HTTP/1.1 101 Web Socket Protocol Handshake\r\n' + 
       'Upgrade: WebSocket\r\n' + 
       'Connection: Upgrade\r\n' + 
       '\r\n\r\n'); 

    sys.puts('upgraded'); 

    socket.ondata = function(data, start, end) { 
    socket.write(data.toString('utf8', start, end), 'utf8'); // echo back 
    }; 

    socket.addListener('end', function() {  
    sys.puts('end'); //works fine 
    }); 

    socket.addListener('close', function() { 
    sys.puts('close'); //eventually gets here 
    }); 

}); 
srv.listen(3400); 

任何人都可以提出一個解決方案,以獲取即時關閉事件嗎?我試圖保持這個簡單而不使用模塊。提前致謝。

+3

爲什麼人們爲這些事情編寫模塊是有原因的。如果您希望在不使用任何事先編寫的代碼的情況下制定符合交叉草案的websocket實現,那麼您將進行相當多的工作。 – einaros 2012-02-14 10:28:06

+0

@einaros +1。 http://socket.io/已經處理這些問題,以及其他許多問題:http://stackoverflow.com/questions/7192747/socket-io-delay-in-firing-the-disconnect-event – 2012-02-14 11:28:28

+0

@RohanSingh,I應該知道 - 我爲socket.io寫了websocket代碼。 – einaros 2012-02-14 15:04:12

回答

0

close事件將被調用一旦TCP套接字連接被一個或另一個端點關閉,並且在系統「未意識到」該套接字已被關閉的情況下極少出現罕見情況併發症,但這種情況很少見。由於WebSockets從HTTP請求服務器啓動,可能會保持活動狀態,直到它超時爲止。這涉及到延遲。

在你的情況下,你試圖執行握手,然後來回發送數據,但WebSockets比這個更復雜的過程。
握手過程需要一些安全過程來驗證兩端(服務器和客戶端),它是HTTP兼容頭。但是不同平臺和瀏覽器支持的不同草稿版本確實以不同的方式實現它,所以您的實現也應該考慮到這一點,並根據您需要支持的版本遵循WebSockets規範的官方文檔。

然後通過WebSockets發送和接收數據不是純字符串。通過WebSockets協議發送的實際數據具有數據成幀層,其中包括向發送的每條消息添加標頭。這個頭文件包含了你發送的消息,屏蔽(從客戶端到服務器),長度和許多其他事情的細節。數據組幀依賴於WebSocket的版本,因此實現會稍有不同。

我會鼓勵使用現有的圖書館,因爲他們已經實現了您所需要的一切,以優美和乾淨的方式,並廣泛用於商業項目。
由於您的客戶端是嵌入式平臺,並且我認爲服務器也是node.js,所以在兩端使用相同的庫很容易。

這裏最好的套裝是ws - 實際的純WebSockets
Socket.IO不適合你的情況,因爲它更復雜,更重的庫有多個協議列表支持回退,並有一些抽象可能不是你正在尋找的。