2014-10-05 86 views
3

這是一本書在行動Node.js的,第3章,例如第11頁52一個簡單的發佈/訂閱使用事件系統發射

var events = require('events'); 
var net = require('net'); 


var channel = new events.EventEmitter(); 
channel.clients = {}; 
channel.subscriptions = {}; 

//Add a listener for the join event that stores a user’s client object, 
//allowing the application to send data back to the user. 

channel.on('join', function(id, client) { 
    console.log('join fired'); 
    channel.clients[id] = client; 
    this.subscriptions[id] = function(senderId, message) { 
     console.log('broadcast fired'); 
      //ignore data if it’s been directly broadcast by the user. 
      if (id != senderId) { 
       this.clients[id].write(message); 
      } 
     } 
     //Add a listener, specific to the current user, for the broadcast event. 
    this.on('broadcast', this.subscriptions[id]); 

}); 

var server = net.createServer(function(client) { 
    var id = client.remoteAddress + ':' + client.remotePort; 
    client.on('connect', function() { 
     console.log('connect fired'); 
     //Emit a join event when a user connects to the server, specifying the user ID and client object. 
     channel.emit('join', id, client); 
    }); 
    client.on('data', function(data) { 
     console.log('data fired'); 
     data = data.toString(); 
     //Emit a channel broadcast event, specifying the user ID and message, when any user sends data. 
     channel.emit('broadcast', id, data); 
    }); 
}); 
server.listen(8888); 

據統計,與此聊天應用:

「如果你開了一些命令行,你會看到,在任何一個 命令行輸入回顯到別人。」

我添加了console.log()事件來嘗試和調試發生了什麼。發送消息時唯一的日誌是get'data fired'。我能夠啓動服務器,並通過telnet連接到服務器,但輸入的任何消息都不會迴應給任何客戶端(包括髮送消息的客戶端)。

任何人都可以闡明一些輕:

  1. 爲什麼這不起作用
  2. 這是否是有效的或推薦的代碼結構
  3. 如何可以提煉/修正
+0

你能給我關於加入和廣播監聽器的文檔 – loveNoHate 2014-10-05 03:52:59

+0

這是整個描述的功能。連接事件在客戶端對象的連接上發出,當數據數據從客戶端傳遞時甚至會發出廣播。這兩個函數位於net.createServer()內部的底部。 – Aweary 2014-10-05 03:54:11

+0

這是最接近我得到http://nodejs.org/api/net.html#net_event_connect – loveNoHate 2014-10-05 03:59:04

回答

3

傳入套接字沒有connect事件(傳遞給createServer()回調)。當回調被調用時,套接字已經連接。所以這在這本書中是一個錯誤。

您還應該注意使用this。這裏

恕我直言,是一個更好的例子:

var events = require('events'); 
var net = require('net'); 

var channel = new events.EventEmitter(); 
channel.clients = {}; 
channel.subscriptions = {}; 

channel.on('join', function(id, client) { 
    channel.clients[id] = client; 
    channel.subscriptions[id] = function(senderId, message) { 
    if (id !== senderId) 
     channel.clients[id].write(message); 
    } 
    channel.on('broadcast', channel.subscriptions[id]); 
}).on('leave', function(id, client) { 
    // cleanup on client disconnect 
    console.log('user ' + id + ' has left'); 
    delete channel.clients[id]; 
    channel.removeListener('broadcast', channel.subscriptions[id]); 
    delete channel.subscriptions[id]; 
}); 

var server = net.createServer(function(client) { 
    var id = client.remoteAddress + ':' + client.remotePort; 

    console.log('user ' + id + ' has joined'); 

    channel.emit('join', id, client); 

    client.on('data', function(data) { 
    channel.emit('broadcast', id, data.toString()); 
    }).on('close', function() { 
    channel.emit('leave', id, client); 
    }); 
}); 
server.listen(8888); 

進一步改善將只有一個broadcast事件,其遍歷,而不是增加新的broadcast事件處理程序,每一個插座所有連接的插座。

+0

謝謝,這就是它。 – Aweary 2014-10-05 04:03:44

+0

「你也應該小心」這個「用法」。你能舉一個例子來說明這一點嗎?或者我可以找到解釋的鏈接。謝謝! – Gerd 2016-12-06 08:48:55