2010-10-19 130 views
1

今天我刚刚开始使用Node.js,并认为我会从我认为的简单脚本开始:通过套接字连接到服务器,以及发送一些数据,并接收回来。我正在创建一个命令行实用程序。浏览器中什么都没有。Node.js:使用套接字连接到服务器

一个服务器的例子可能是memcached,beanstalkd等等。看起来net模块是这个工作的正确工具,但是我仍然对Node.js的处理方式有些模糊。一些帮助将不胜感激。

更新#1

让我看看,如果我能打破这在为一对夫妇的小问题。我甚至不喜欢问这样的问题,但Node.js文档非常稀少,6个月前编写的大多数文档已经过时。 1)所以我可以使用net.stream.write()发送数据到远程服务器,但我不知道如何得到回应。我什至不知道如何测试write()完成时的时间,因为它不需要回调。

2)关于整个event.emit事情如何工作的一些线索会很棒。我认为这是我在这些事情中失踪的关键石头。

更新#2

这里就是我仍在努力实现一个客户端程序混乱。让我示意一个典型的发送请求=>获取响应系统:

1)我将回调函数绑定到net模块以获取响应和其他事件,其中包括必要的绑定以从服务器获取响应。

2)我使用stream.write()向服务器发送请求。

3)我什么都不做,因为我绑定的“数据”事件会从服务器得到响应。

这里的事情变得棘手。假设我在调用绑定的“data”事件之前调用stream.write()两次。现在我有一个问题。当“数据”事件确实发生时,我如何知道这是2个请求中的哪一个?我保证答复会按照请求的顺序发生?如果回复的顺序不同,会怎么样?

+0

没有多少时间ATM,但净。 http://nodejs.org/api.html时钟在侧栏的'net.Server'上。你有它。一切都基于事件,你必须监听流的'data'事件。这个例子实际上更像是一个基本的回显服务器。如果你愿意,我可以在以后为你做更多的例子。 – 2010-10-19 07:16:59

+0

如果您需要知道客户端在哪个“写入”响应中很重要,那么您应该为您发送/接收的数据添加一个id或类似内容。但这是网络的一个普遍问题,与基于事件的方法无关。 – 2010-10-19 22:07:33

回答

8

首先,让我们清楚EventEmitter是什么。 JavaScript,因此Node.js是asynchronous。这意味着,不必等待服务器对象上的传入连接,而是将listener添加到对象并将其传递给callback function,然后在事件发生时“尽快”执行。

在这里和那里仍然在等待着后台,但这已经被抽离了你的背景。

让我们来看看这个简单的例子:

// #1) create a new server object, and pass it a function as the callback 
var server = net.createServer(function (stream) { 


    // #2) register a callback for the 'connect' event 
    stream.on('connect', function() { 
     stream.write('hello\r\n'); // as 
    }); 


    // #3) register a callback for the 'data' event 
    stream.on('data', function (data) { 
     stream.write(data); 
    }); 

    // #4) register a callback for the 'end' event 
    stream.on('end', function() { 
     stream.write('goodbye\r\n'); 
     stream.end(); 
    }); 
}); 

// #5) make the server listen on localhost:8124 
server.listen(8124, 'localhost'); 

所以我们创建服务器并通过它的callback function,尚未执行此功能。在这里传递函数基本上是为服务器对象的事件添加侦听器的快捷方式。之后,我们启动服务器#5

现在在传入连接的情况下会发生什么?

  1. 由于我们传递给createServer函数被绑定到connection事件,现在被执行。

  2. 它添加connectdataend事件侦听器向stream object(其表示个别连接)通过钩住回调的事件。

  3. 之后,stream打响connect事件,因此在#2传递的函数会被执行并且写入hello\r\n流中。函数如何知道它应该写入哪个流? Closures是答案,函数继承它创建的范围,因此在函数stream中仍然引用单个连接,这触发了我们现在正在进行的这种回调。

  4. 现在客户端通过连接,这使得stream对象调用其data事件,因为我们在#3约束的功能,这种情况下,我们现在回显传入的数据返回给客户端发送一些数据。

  5. 如果客户端关闭连接,我们在#4上绑定的函数被调用,写入goodbye\r\n,之后关闭我们这边的连接。

这是否使事情更清楚一点?那么它肯定会让整个事情变得更容易。 Node和JavaScript一样在浏览器中,single threaded。在给定的时间点只有一件事发生。

来形容它简单,所有这些callbacks结束了在全局队列中,然后叫了一个又一个,所以这个队列可以(抽象)是这样的:

| connection event for a new stream 
| data event for stream #12 
| callback set via setTimeout 
v close event of yet another stream 

现在,这些均得到执行顶部到底,在这些之间什么都不会发生。没有机会,当你在callback事件中绑定到data事件时,其他事情将会发生并奇迹般地改变系统的状态。即使服务器上存在新的传入连接,它的事件也会排队等待,直到它发生之前的所有事件(包括您当前所在的事件data)结束。

+0

感谢这个伟大的例子伊沃。任何向我展示客户实施的机会?还是把我指向一个?我一直在寻找node-memcache模块的帮助,但事件驱动模型让事情变得有点疯狂。例如,您不写入服务器并等待响应。你写信给服务器,什么都不做。在某个时候,服务器会回应,并且你的一个事件监听器捕获它。但似乎你必须想出一些创造性的解决方案来处理这种方法。 – mellowsoon 2010-10-19 15:51:13

+0

如果你想在节点内建立一个到服务器的连接,那么请检查'net.Stream'和'net.createConnection',让你建立一个连接。这个连接然后有类似的事件,比如在我的例子中,当有人连接到服务器时,你会得到'stream object'。 – 2010-10-19 16:08:55

+0

我接受你的回答,因为这是一个明确的答案,我不想再花时间帮助我。但我确实更新了我的问题,以反映我仍然困惑的几个方面。再次感谢! – mellowsoon 2010-10-19 21:37:38

相关问题