Nodejs net.createServer() 使用方法
Nodejs net.createServer() 使用方法
代码:
var events = require('events');
var net = require('net');
var channel = new events.EventEmitter();
channel.clients = {};
channel.subscriptions = {};
channel.on('join', function(id, client){
this.clients[id] = client;
this.subscriptions[id] = function(senderId, message){
if(id != senderId){
this.clients[id].write(message);
}
};
this.on('broadcast', this.subscriptions[id]);
});
var server = net.createServer(function(client){ //here
var id = client.remoteAddress + ":" + client.remotePort;
client.on('connect', function(){ //事件1 <<问题行
channel.emit('join', id, client);
});
client.on('data', function(data){ //事件2
data = data.toString();
channel.emit('broadcast', id, data);
});
});
server.listen(8888);
最近在看Node.js in action一书,里面有个例子是建一个简单的聊天服务器
但是我运行代码后发现有问题,不知道怎么解决,看文档也找不到详细解释,所以到这里请教。 createServer的回调函数里面给新建的链接添加了个connect事件(见上面的问题行),但是我尝试用telnet连接的时候发现connect事件无法被触发,而data事件却可以触发,表明已经连接成功了,这让我很郁闷,所以想请教下这个connect事件的一些细节。
万分感谢。
当然,我可以帮助你解答关于 net.createServer()
的使用方法以及如何处理你提到的问题。
首先,我们来理解一下 net.createServer()
的基本用法。net.createServer()
是 Node.js 中用于创建 TCP 服务器的一个核心 API。它接受一个可选的回调函数,该回调函数会在每个新客户端连接时被调用。
示例代码
让我们先来看一个简化版本的示例代码:
var net = require('net');
var server = net.createServer(function(client) {
console.log('Client connected:', client.remoteAddress, client.remotePort);
client.on('end', function() {
console.log('Client disconnected');
});
client.on('data', function(data) {
console.log('Received data:', data.toString());
client.write('Echo: ' + data);
});
});
server.listen(8888, function() {
console.log('Server is listening on port 8888');
});
在这个示例中,我们创建了一个简单的 TCP 服务器,每当有新的客户端连接时,会打印一条消息,并且在接收到数据时会回显数据。
解决你的问题
关于你提到的 connect
事件不能触发的问题,实际上 net.Socket
对象没有 connect
事件。connect
事件通常用于 net.connect()
创建的客户端对象。对于服务器端来说,客户端连接的建立是自动完成的,因此不需要监听 connect
事件。
如果你想要在客户端连接时执行某些操作,可以在 net.createServer()
的回调函数中进行处理,如上所示的 console.log('Client connected:', client.remoteAddress, client.remotePort);
。
你的原始代码中的问题
在你的原始代码中,client.on('connect', ...)
这一行实际上是不必要的。因为每当一个新的客户端连接到服务器时,net.createServer()
的回调函数会被立即调用。你应该在回调函数内部处理客户端连接后的逻辑,而不是试图监听 connect
事件。
你可以将你的代码修改为如下所示:
var events = require('events');
var net = require('net');
var channel = new events.EventEmitter();
channel.clients = {};
channel.subscriptions = {};
channel.on('join', function(id, client){
this.clients[id] = client;
this.subscriptions[id] = function(senderId, message){
if(id != senderId){
this.clients[id].write(message);
}
};
this.on('broadcast', this.subscriptions[id]);
});
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);
});
});
server.listen(8888);
这样,每次有新的客户端连接时,channel.emit('join', id, client);
会被调用,从而注册相应的事件处理器。
服务器只会触发 connection 事件,亦即是调用 createServer 中的回调函数。 connect 是客户端调用 connect() 函数成功连接后才会触发的 你再看看文档中的上述两个事件和两个函数
据我所知 你说的这个net.Socket对象的connect事件应该是你开发tcp的客户端时,连接到服务器时(通过socket.connect()方法),才会触发你说的connect事件。 你是在开发服务器,不是客户端。
在Node.js中使用net.createServer()
来创建一个TCP服务器时,内置了一些常见的事件,如'connection'
、'close'
、'error'
等。对于客户端连接的处理,应该关注的是'connection'
事件,而不是'connect'
事件。'connect'
事件实际上是客户端用来监听服务器响应的事件,并不会在服务器端触发。
以下是修正后的代码示例:
var events = require('events');
var net = require('net');
var channel = new events.EventEmitter();
channel.clients = {};
channel.subscriptions = {};
channel.on('join', function (id, client) {
this.clients[id] = client;
this.subscriptions[id] = function (senderId, message) {
if (id != senderId) {
this.clients[id].write(message);
}
};
this.on('broadcast', this.subscriptions[id]);
});
var server = net.createServer(function (client) { // 这里
var id = client.remoteAddress + ":" + client.remotePort;
client.on('connect', function () { // 这里不需要
console.log("Client connected");
});
client.on('data', function (data) { // 事件2
data = data.toString();
channel.emit('broadcast', id, data);
});
client.on('end', function () {
delete channel.clients[id];
delete channel.subscriptions[id];
});
});
server.listen(8888, function () {
console.log('Server listening on port 8888');
});
解释:
-
事件:服务器端关注的事件是
'connection'
,但在这个例子中,我们直接在net.createServer
的回调函数中处理客户端连接,因此不需要显式地处理'connect'
事件。 -
连接处理:在
net.createServer
的回调函数中,我们通过监听'data'
事件来接收来自客户端的数据,并通过'broadcast'
事件广播给所有连接的客户端。 -
断开连接:我们还添加了一个
'end'
事件处理程序,当客户端断开连接时,从订阅列表中移除该客户端。 -
错误处理:建议添加对
'error'
事件的处理,以确保服务器能够优雅地处理异常情况。
通过这种方式,你可以创建一个简单的聊天服务器,其中每个连接的客户端都能接收到其他客户端发送的消息。