节点js网络事件:连接与连接

时间:2014-05-02 21:10:55

标签: node.js

net.Server的连接事件何时触发net.Socket连接事件。他们是同一个活动吗?我看过一个代码示例,其中net.createServer函数的处理程序(处理连接事件)也包含以下代码

    var server = net.createServer(function (client) {
var id = client.remoteAddress + ':' + client.remotePort;
client.on('connect', function() {
channel.emit('join', id, client);
});
client.on('data', function(data) {
data = data.toString();
channel.emit('broadcast', id, data);
});
});

这是不正确的?这个听众不需要/永远不会被击中。发射应该在听众之外。

3 个答案:

答案 0 :(得分:5)

根据您在此处发布的代码,我假设您正在阅读Node.js in Action,这是导致问题的示例代码。如果是这种情况,您可以参考这个类似的问题:NodeJS events on('connect') error

摘要

简而言之,这2个事件由2个不同的对象接收。

connect事件由套接字对象接收,并在“成功建立套接字连接时”发出。另一方面,服务器对象接收connection事件,并在“建立新连接时”发出。

注意当客户端命中节点并创建套接字时,会自动调用net.createServer(callback)的回调,因此您不必在此客户端 - 服务器套接字上手动注册另一个事件处理程序,即{{1在你的代码中。

概念

提到@3y3,有两种方法可以在node.js中使用client.on('connect', function() { });模块,netcreateConnection

为了更好地理解它是如何工作的,您可以将此图用作示例:

enter image description here

net.createServer

当您需要createServer模块和net时,您基本上为客户端创建服务器(浏览器通过http,终端通过telnet等)进行连接。

请考虑以下代码:

createServer

在这种情况下,var net = require('net'); var events = require('events'); var channel = new events.EventEmitter(); var server = net.createServer(function (socket) { var id = socket.remoteAddress + ': ' + client.remotePort; console.log('Server connected', id); channel.emit('join', id, socket); socket.on('data', function(data) { data = data.toString(); channel.emit('broadcast', id, data); }); }).listen(8888); 回调中的参数是服务器和客户端之间的“套接字”。在示例代码中,Node.js in Action的作者将其称为createServer,这对您来说可能有点混乱,但这实际上是相同的概念:它是一个客户端相关对象,其中包含服务器执行的方法东西。

请注意,此回调已在服务器上注册,并在建立连接的同时被调用。这是client事件的结果,当客户端在此情况下命中服务器上的端口8888时,该事件将发送到服务器。您放入此回调的任何函数都将立即执行。在我们的例子中,我们做了三件事:

  • Console.log服务器上的客户端ID
  • 向频道对象发送'join'事件
  • 为'data'事件注册事件监听器(即从客户端发送数据时调用)

不需要connection ,因为服务器连接事件的回调是我们刚才提到的。那么client.on('connect', function() { // do something })的目的是什么?

net.createConnection

通过使用此功能,您可以创建“与服务器的连接”,而不是创建服务器本身。换句话说,就像你打开一个终端并使用telnet连接到服务器一样,只有这种情况发生在服务器代码库中(即在你的节点环境中,如图clinet.on('connect')所示)

考虑以下代码:(再次基于@3y3的例子):

Client x

在这里,我们在节点中构建一个客户端,并通过端口8888连接到服务器,这是我们之前定义的。 var Client = net.createConnection; var client = Client({port: 8888, localAddress: '127.0.0.1', localPort: 51000}); client.on('connect', function() { var id = this.localAddress + ': ' + this.localPort; console.log('Client connected', id); }); localPort是任意定义的,只是模仿本地环境中的终端连接。

然后我们在此客户端上注册一个事件处理程序,因此当此客户端连接到服务器时,它将收到localAddress事件并执行此事件处理程序。如果在带有节点的同一文件中运行两个片段,您将看到两个

connect

在控制台中。

结论

如果要在远程客户端连接到服务器时执行某些操作,只需将要执行的行放在Client connected 127.0.0.1: 51000 Server connected ::ffff:127.0.0.1: 51000 的回调函数中。

net.createServer(function(socket) { // your lines here })用于节点环境中的其他手动构建客户端。

有关套接字对象和服务器对象的更多信息,请参阅官方文档here

在您的情况下,您可以使用以下修订代码:

client.on('connect', function() {});

答案 1 :(得分:2)

如果您的代码与:

相同
var Client = require('net').createConnection,
    client = Client({port:4321});

client.on('connect', function(){
  //channel.emit('join', id, client);
  channel.emit('join', id, this); //avoid bad closure
});

这是有效的代码,当connect发出时,服务器部分会发出connection,创建套接字对象并将其传递给connection回调

更新: 您的代码不正确。您将createServer事件的回调传递给connection,其内容与:

相同
var server = net.createServer();
server.on('connection', callback);

在回调中,您还连接了套接字对象。这是正确的:

var server = net.createServer(function (client) {
  var id = client.remoteAddress + ':' + client.remotePort;
  channel.emit('join', id, client);
  client.on('data', function(data) {
    data = data.toString();
    channel.emit('broadcast', id, data);
  });
});

答案 2 :(得分:0)

请阅读模块' net'的官方Nodejs文档。

问题的关键在于,您有一个服务器套接字,您已将其命名为“客户端' (一个令人困惑的名称),它不是客户端套接字。对于客户端套接字,您可以订阅' connect'事件而不是服务器套接字。

net.createServer(callback)接受 回调 ,当来自客户端的新连接发生并且回调通过服务器套接字时,会回调该回调。您在function(client)中所指的内容本质上是一个服务器套接字,使用的术语是' client'是误导。请参阅Node.js' net' createServer的模块示例。对于服务器套接字,列出的所有事件(例如数据,超时,结束,关闭等)都是有效的,除了连接'事件。

与服务器套接字相反,如果要创建一个调用net.createConnection的客户端程序,它将返回一个客户端套接字。在那个插座中,您订阅了“连接”#39;事件。