Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Node.js:使用套接字连接到服务器_Javascript_Sockets_Node.js - Fatal编程技术网

Javascript Node.js:使用套接字连接到服务器

Javascript Node.js:使用套接字连接到服务器,javascript,sockets,node.js,Javascript,Sockets,Node.js,今天我刚开始玩Node.js,我想我应该从一个简单的脚本开始:通过套接字连接到服务器,发送一点数据,然后再接收回来。我正在创建一个命令行实用程序。浏览器中没有任何内容 服务器的一个例子是memcached、beanstalkd等。看起来net模块是完成这项工作的合适工具,但我对Node.js的工作方式仍然有点模糊。我们将非常感谢您的帮助 更新1 让我看看是否可以把这个问题分解成几个小问题。我甚至不喜欢问这样的问题,但是Node.js文档非常稀少,而且6个月前编写的大多数文档已经过时了 1所以我可

今天我刚开始玩Node.js,我想我应该从一个简单的脚本开始:通过套接字连接到服务器,发送一点数据,然后再接收回来。我正在创建一个命令行实用程序。浏览器中没有任何内容

服务器的一个例子是memcached、beanstalkd等。看起来net模块是完成这项工作的合适工具,但我对Node.js的工作方式仍然有点模糊。我们将非常感谢您的帮助

更新1

让我看看是否可以把这个问题分解成几个小问题。我甚至不喜欢问这样的问题,但是Node.js文档非常稀少,而且6个月前编写的大多数文档已经过时了

1所以我可以使用net.stream.write将数据发送到远程服务器,但我不知道如何获得响应。我甚至不知道如何在写入完成时进行测试,因为它不需要回调

2关于整个事件的一些线索。emit thing工作原理将非常有用。我想这才是我在整件事中遗漏的关键

更新2

在这里,我仍然对实现客户端程序感到困惑。让我来举例说明一个典型的发送请求=>get响应系统:

1我将回调绑定到net模块以获取响应和其他事件,包括从服务器获取响应所需的绑定

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

3然后我什么也不做,因为绑定数据事件将从服务器获得响应


这就是事情变得棘手的地方。假设在调用绑定数据事件之前调用stream.write两次。现在我有一个问题。当数据事件确实发生时,我如何知道这两个请求中的哪一个是响应?我是否保证响应的顺序与请求的顺序相同?如果响应以不同的顺序返回呢?

首先,让我们弄清楚什么是EventEmitter。JavaScript和Node.js都是异步的。这意味着,您不必等待服务器对象上的传入连接,而是向该对象添加一个侦听器并向其传递一个回调函数,然后在事件发生时立即执行该函数

在后台仍有很多人在等待,但这已经从你那里被抽象出来了

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

// #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');
因此,我们创建服务器并向其传递回调函数,该函数尚未执行。在这里传递函数基本上是为服务器对象的连接事件添加侦听器的快捷方式。之后,我们在5点启动服务器

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

由于传递给createServer的函数已绑定到连接事件,因此现在将执行该函数

它将连接、数据和结束事件侦听器添加到流对象中,流对象通过连接事件的回调来表示单个连接

之后,流触发connect事件,因此在2传递的函数将被执行并将hello\r\n写入流。函数如何知道应该写入哪个流?答案是,函数继承了它在其中创建的作用域,因此在函数流中仍然引用触发我们现在所处回调的单个连接

现在,客户机通过连接发送一些数据,这使得流对象调用其数据事件,因为我们在3处将一个函数绑定到此事件,所以现在将传入的数据回显到客户机

如果客户端关闭连接,将调用我们在4绑定的函数,该函数将写入“再见”\r\n然后从我们这边关闭连接

这能让事情变得更清楚一点吗?这确实让整个事情变得容易多了。节点是单线程的,就像浏览器中的JavaScript一样。在给定的时间点上只有一件事发生

简单地说,所有这些回调都以一个全局队列结束,然后一个接一个地被调用,因此这个队列可能抽象如下:

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

这些都是自上而下执行的,它们之间不会发生任何事情。当您在绑定到数据事件的回调中执行某些操作时,不可能发生其他操作并神奇地改变系统的状态。即使服务器上有一个新的传入连接,它的事件也会排队,并且它必须等到它之前的所有事情(包括您当前所在的数据事件)都完成。

首先,让我们弄清楚什么是EventEmitter。JavaScript和Node.js都是异步的。这意味着,您不必等待服务器对象上的传入连接,而是向该对象添加一个侦听器并向其传递一个回调函数,然后在事件发生时立即执行该函数

还有人等着呢 背景中到处都在发生,但那已经从你那里抽象出来了

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

// #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');
因此,我们创建服务器并向其传递回调函数,该函数尚未执行。在这里传递函数基本上是为服务器对象的连接事件添加侦听器的快捷方式。之后,我们在5点启动服务器

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

由于传递给createServer的函数已绑定到连接事件,因此现在将执行该函数

它将连接、数据和结束事件侦听器添加到流对象中,流对象通过连接事件的回调来表示单个连接

之后,流触发connect事件,因此在2传递的函数将被执行并将hello\r\n写入流。函数如何知道应该写入哪个流?答案是,函数继承了它在其中创建的作用域,因此在函数流中仍然引用触发我们现在所处回调的单个连接

现在,客户机通过连接发送一些数据,这使得流对象调用其数据事件,因为我们在3处将一个函数绑定到此事件,所以现在将传入的数据回显到客户机

如果客户端关闭连接,将调用我们在4绑定的函数,该函数将写入“再见”\r\n然后从我们这边关闭连接

这能让事情变得更清楚一点吗?这确实让整个事情变得容易多了。节点是单线程的,就像浏览器中的JavaScript一样。在给定的时间点上只有一件事发生

简单地说,所有这些回调都以一个全局队列结束,然后一个接一个地被调用,因此这个队列可能抽象如下:

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

这些都是自上而下执行的,它们之间不会发生任何事情。当您在绑定到数据事件的回调中执行某些操作时,不可能发生其他操作并神奇地改变系统的状态。即使服务器上有一个新的传入连接,它的事件也会排队,并且它必须等待所有事情完成,包括您当前所处的数据事件。

除了网络之外,ATM没有太多时间。侧栏中的net.Server上的时钟。给你。一切都是基于事件的,您必须侦听流的数据事件。这个例子实际上是一个基本的echo服务器。如果您愿意,我可以稍后为您提供更多的示例。如果您需要知道客户机响应了哪一个写入,那么您可能应该在发送/接收的数据中添加一个id或类似的内容。但这是网络的一个普遍问题,与基于事件的方法无关。除了网络,ATM没有太多时间。侧栏中的net.Server上的时钟。给你。一切都是基于事件的,您必须侦听流的数据事件。这个例子实际上是一个基本的echo服务器。如果您愿意,我可以稍后为您提供更多的示例。如果您需要知道客户机响应了哪一个写入,那么您可能应该在发送/接收的数据中添加一个id或类似的内容。但这是网络的一个普遍问题,与基于事件的方法无关。感谢Ivo这个伟大的例子。有没有可能向我展示一个客户端实现?还是指给我看?我一直在寻找node memcache模块的帮助,但是事件驱动模型让事情变得有点疯狂。例如,您不向服务器写入数据,而是等待响应。您向服务器写入数据,但不执行任何操作。在某个时刻,服务器将做出响应,并且您的一个事件侦听器将捕获它。但似乎您必须想出一些创造性的解决方案来处理这种方法。如果您想从节点内建立到服务器的连接,请签出net.Stream和net.createConnection,让您建立一个连接。在我的例子中,一旦有人连接到服务器,这个连接就会发生类似的事件,比如流对象。我接受你的答案,因为这是一个明确的答案,我不想再占用你的时间来帮助我了。但我确实更新了我的问题,以反映我仍然困惑的几个方面。再次感谢!谢谢你给我举了一个很好的例子。有没有可能向我展示一个客户端实现?还是指给我看?我一直在寻找node memcache模块的帮助,但是事件驱动模型让事情变得有点疯狂。例如,您不向服务器写入数据,而是等待响应。您向服务器写入数据,但不执行任何操作。在某个时刻,服务器将做出响应,并且您的一个事件侦听器将捕获它。但似乎你必须为交易想出一些创造性的解决方案
如果您想从节点内建立到服务器的连接,请签出net.Stream和net.createConnection,这样您就可以建立单个连接。在我的例子中,一旦有人连接到服务器,这个连接就会发生类似的事件,比如流对象。我接受你的答案,因为这是一个明确的答案,我不想再占用你的时间来帮助我了。但我确实更新了我的问题,以反映我仍然困惑的几个方面。再次感谢!