2010-10-19 81 views
1

今天我剛剛開始使用Node.js,並認爲我會從我認爲的簡單腳本開始:通過套接字連接到服務器,以及發送一些數據,並接收回來。我正在創建一個命令行實用程序。瀏覽器中什麼都沒有。Node.js:使用套接字連接到服務器

一個服務器的例子可能是memcached,beanstalkd等等。看起來net模塊是這個工作的正確工具,但是我仍然對Node.js的處理方式有些模糊。一些幫助將不勝感激。

更新#1

讓我看看,如果我能打破這在爲一對夫婦的小問題。我甚至不喜歡問這樣的問題,但Node.js文檔非常稀少,6個月前編寫的大多數文檔已經過時。 1)所以我可以使用net.stream.write()發送數據到遠程服務器,但我不知道如何得到迴應。我什至不知道如何測試write()完成時的時間,因爲它不需要回調。

2)關於整個event.emit事情如何工作的一些線索會很棒。我認爲這是我在這些事情中失蹤的關鍵石頭。

更新#2

這裏就是我仍在努力實現一個客戶端程序混亂。讓我示意一個典型的發送請求=>獲取響應系統:

1)我將回調函數綁定到net模塊以獲取響應和其他事件,其中包括必要的綁定以從服務器獲取響應。

2)我使用stream.write()向服務器發送請求。

3)我什麼都不做,因爲我綁定的「數據」事件會從服務器得到響應。

這裏的事情變得棘手。假設我在調用綁定的「data」事件之前調用stream.write()兩次。現在我有一個問題。當「數據」事件確實發生時,我如何知道這是2個請求中的哪一個?我保證答覆會按照請求的順序發生?如果回覆的順序不同,會怎麼樣?

+0

沒有多少時間ATM,但淨。 http://nodejs.org/api.html時鐘在側欄的'net.Server'上。你有它。一切都基於事件,你必須監聽流的'data'事件。這個例子實際上更像是一個基本的回顯服務器。如果你願意,我可以在以後爲你做更多的例子。 – 2010-10-19 07:16:59

+0

如果您需要知道客戶端在哪個「寫入」響應中很重要,那麼您應該爲您發送/接收的數據添加一個id或類似內容。但這是網絡的一個普遍問題,與基於事件的方法無關。 – 2010-10-19 22:07:33

回答

8

首先,讓我們清楚EventEmitter是什麼。 JavaScript,因此Node.js是asynchronous。這意味着,不必等待服務器對象上的傳入連接,而是將listener添加到對象並將其傳遞給callback function,然後在事件發生時「儘快」執行。

在這裏和那裏仍然在等待着後臺,但這已經被抽離了你的背景。

讓我們來看看這個簡單的例子:

// #1) create a new server object, and pass it a function as the callback 
var server = net.createServer(function (stream) { 


    // #2) register a callback for the 'connect' event 
    stream.on('connect', function() { 
     stream.write('hello\r\n'); // as 
    }); 


    // #3) register a callback for the 'data' event 
    stream.on('data', function (data) { 
     stream.write(data); 
    }); 

    // #4) register a callback for the 'end' event 
    stream.on('end', function() { 
     stream.write('goodbye\r\n'); 
     stream.end(); 
    }); 
}); 

// #5) make the server listen on localhost:8124 
server.listen(8124, 'localhost'); 

所以我們創建服務器並通過它的callback function,尚未執行此功能。在這裏傳遞函數基本上是爲服務器對象的事件添加偵聽器的快捷方式。之後,我們啓動服務器#5

現在在傳入連接的情況下會發生什麼?

  1. 由於我們傳遞給createServer函數被綁定到connection事件,現在被執行。

  2. 它添加connectdataend事件偵聽器向stream object(其表示個別連接)通過鉤住回調的事件。

  3. 之後,stream打響connect事件,因此在#2傳遞的函數會被執行並且寫入hello\r\n流中。函數如何知道它應該寫入哪個流? Closures是答案,函數繼承它創建的範圍,因此在函數stream中仍然引用單個連接,這觸發了我們現在正在進行的這種回調。

  4. 現在客戶端通過連接,這使得stream對象調用其data事件,因爲我們在#3約束的功能,這種情況下,我們現在回顯傳入的數據返回給客戶端發送一些數據。

  5. 如果客戶端關閉連接,我們在#4上綁定的函數被調用,寫入goodbye\r\n,之後關閉我們這邊的連接。

這是否使事情更清楚一點?那麼它肯定會讓整個事情變得更容易。 Node和JavaScript一樣在瀏覽器中,single threaded。在給定的時間點只有一件事發生。

來形容它簡單,所有這些callbacks結束了在全局隊列中,然後叫了一個又一個,所以這個隊列可以(抽象)是這樣的:

| connection event for a new stream 
| data event for stream #12 
| callback set via setTimeout 
v close event of yet another stream 

現在,這些均得到執行頂部到底,在這些之間什麼都不會發生。沒有機會,當你在callback事件中綁定到data事件時,其他事情將會發生並奇蹟般地改變系統的狀態。即使服務器上存在新的傳入連接,它的事件也會排隊等待,直到它發生之前的所有事件(包括您當前所在的事件data)結束。

+0

感謝這個偉大的例子伊沃。任何向我展示客戶實施的機會?還是把我指向一個?我一直在尋找node-memcache模塊的幫助,但事件驅動模型讓事情變得有點瘋狂。例如,您不寫入服務器並等待響應。你寫信給服務器,什麼都不做。在某個時候,服務器會迴應,並且你的一個事件監聽器捕獲它。但似乎你必須想出一些創造性的解決方案來處理這種方法。 – mellowsoon 2010-10-19 15:51:13

+0

如果你想在節點內建立一個到服務器的連接,那麼請檢查'net.Stream'和'net.createConnection',讓你建立一個連接。這個連接然後有類似的事件,比如在我的例子中,當有人連接到服務器時,你會得到'stream object'。 – 2010-10-19 16:08:55

+0

我接受你的回答,因爲這是一個明確的答案,我不想再花時間幫助我。但我確實更新了我的問題,以反映我仍然困惑的幾個方面。再次感謝! – mellowsoon 2010-10-19 21:37:38

相關問題