Nodejs創建TCP服務器


Nodejs創建TCP服務器

1.Nodejs提供了net模塊給我們,所以我們創建TCP服務器很簡單:

 1 require('net').createServer(function(socket) {
 2     // new connection
 3     socket.on('data', function(data) {
 4         // got data
 5     });
 6     socket.on('end', function(data) {
 7         // connection closed
 8     });
 9     socket.write('Some string');
10 }).listen(4001);

通過var server = require('net').createServer();這行代碼我們可以得到tcp服務器對象的引用。
server對象具注冊了以下幾個監聽事件:
listening,connection,close,error
下面一個例子是在TCP服務器的聲明周期中監聽了如上幾個事件:

 1 var server = require('net').createServer();
 2 var port = 4001;
 3 server.on('listening', function() {
 4     console.log('Server is listening on port', port);
 5 });
 6 server.on('connection', function(socket) {
 7     console.log('Server has a new connection');
 8     socket.end();
 9     server.close();
10 });
11 server.on('close', function() {
12     console.log('Server is now closed');
13 });
14 server.on('error', function(err) {
15     console.log('Error occurred:', err.message);
16 });
17 server.listen(port);

一旦建立連接成功后,會得到一個socket對象作為回調中的參數,我們可以操作這個socket對象,前面提到過tcp連接的對象是可讀可寫的流。作為一個流對象,因此能夠監聽data,end等事件;作為一個可寫流,具有write()方法。
下面是一個能夠監聽用戶輸入的例子:

 1 var server = require('net').createServer(function(socket) {
 2     console.log('new connection');
 3     socket.setEncoding('utf8');
 4     socket.write("Hello! You can start typing. Type 'quit' to exit.\n");
 5     socket.on('data', function(data) {
 6         console.log('got:', data.toString())
 7         if (data.trim().toLowerCase() === 'quit') {
 8             socket.write('Bye bye!');
 9             return socket.end();
10         }
11         //反饋回客戶端
12         socket.write(data);
13     });
14     socket.on('end', function() {
15         console.log('Client connection ended');
16     });
17 }).listen(4001);

因為socket對象又是一個可讀的流,因此你能夠空氣他的pause()和resume(),或者你可以直接使用pipe()方法輸出一個可寫流:

1 var ws = require('fs').createWriteStream('helloworld.txt');
2 require('net').createServer(function(socket) {
3     socket.pipe(ws);
4 }).listen(4001);

上面的代碼創建了一個可寫流對象,然后將這個可寫流對象輸出到客戶端。在客戶端可以得到一個名為helloworld.txt的文件,
可以用“telnet localhost 4001”來測試該例子。
因為socket對象同時具有可讀流的性質和可寫流的性質,因此上面的例子你可以反過來形成下面這樣的代碼:

1 require('net').createServer(function(socket) {
2     var rs = require('fs').createReadStream('hello.txt');
3     rs.pipe(socket);
4 }).listen(4001);

上面的代碼將hello.text文件內容輸出到socket對象中返回給客戶端,當內容輸出完成后,tcp連接就會退出,在前面的文章中有說過Pipe的用法,默認情況下在數據讀取完成后就會執行end方法,因此如果不想要這樣的效果並保持連接的話可以在pipe中添加第二個參數:{ end : false },並重寫end監聽。

 

2.閑置socket
當有閑置的socket出現的時候我們需要進行相應的清除的工作,由setTimeout方法可以幫我們把閑置的socket對象關閉。

1 var timeout = 60000; // 1 minute
2 socket.setTimeout(timeout);
3 socket.on('timeout', function() {
4     socket.write('idle timeout, disconnecting, bye!');
5     socket.end();
6 });

下面是一個更簡潔的使用方式:

1 socket.setTimeout(60000, function() {
2     socket.end('idle timeout, disconnecting, bye!');
3 });

 

3.保持連接
socket.setKeepAlive(true);
你也可以添加第二個參數在設置可延時時長:
socket.setKeepAlive(true, 10000); // 10 seconds


4.是否使用延時
kernel會在發送tcp數據包之前緩存數據,因此會占據一定的延時,這對於某些小數據包場景來說是有用的,但如果你不希望有這樣的延時的話,那么你可以這樣設置:
socket.setNoDelay(true);


5.監聽關閉連接

1 var port = 4001;
2 var host = '0.0.0.0';
3 server.listen(port, host);

listen方法的第二個參數是監聽客戶端的ip地址,如果填寫則只監聽所填寫的ip,否則則監聽所有ip地址,默認情況下不填寫。
關閉服務器連接,我們可以使用close方法,同時也可以對該事件進行監聽。

1 server.close();
2 server.on('close', function() {
3     console.log('server closed!');
4 });

 

6.創建一個簡單的TCP聊天室服務器

 1 var net = require('net');
 2 var server = net.createServer();
 3 var sockets = [];
 4 server.on('connection', function(socket) {
 5     console.log('got a new connection');
 6     sockets.push(socket);
 7     console.log('sockets length:', sockets.length);
 8     socket.on('data', function(data) {
 9         console.log('got data:', data.toString());
10         sockets.forEach(function(otherSocket) {
11             if (otherSocket !== socket) {
12                 otherSocket.write(data);
13             }
14         });
15     });
16     socket.on('close', function() {
17         console.log('connection closed');
18         var index = sockets.indexOf(socket);
19         sockets.splice(index, 1);
20         console.log('sockets length:', sockets.length);
21     });
22 });
23 server.on('error', function(err) {
24     console.log('Server error:', err.message);
25 });
26 server.on('close', function() {
27     console.log('Server closed');
28 });
29 server.listen(4001);

 7.常用插件

7.1開發中可以安裝supervisor來提高調試效率,這個插件可以保證我們每次修改完代碼后都無需重新手動啟動nodejs服務器,由supervisor幫我們自動搞定。

npm install -g supervisor

安裝完成后可以: supervisor bin/www

7.2在服務器環境中部署nodejs,我們不希望程序會斷掉,因此,就需要一個能自動重啟的服務來幫我們實現這一功能。

$ sudo npm install forever -g #安裝 $ forever start app.js #啟動 $ forever stop app.js #關閉 $ forever start -l forever.log -o out.log -e err.log app.js #輸出日志和錯誤


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM