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);
});
});
这是不正确的?这个听众不需要/永远不会被击中。发射应该在听众之外。
答案 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() { });
模块,net
和createConnection
。
为了更好地理解它是如何工作的,您可以将此图用作示例:
当您需要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时,该事件将发送到服务器。您放入此回调的任何函数都将立即执行。在我们的例子中,我们做了三件事:
不需要connection
,因为服务器连接事件的回调是我们刚才提到的。那么client.on('connect', function() { // do something })
的目的是什么?
通过使用此功能,您可以创建“与服务器的连接”,而不是创建服务器本身。换句话说,就像你打开一个终端并使用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;事件。