Node.js: подключение к серверу с помощью сокетов - PullRequest
1 голос
/ 19 октября 2010

Сегодня я только начинаю играть с Node.js и подумал, что начну с простого сценария: подключение к серверу через сокеты, отправка небольшого количества данных и получение их обратно.,Я создаю утилиту командной строки.Ничего в браузере.

Примером сервера мог бы быть memcached, beanstalkd и т. Д. Кажется, сетевой модуль является подходящим инструментом для работы, но я все еще немного неясен с Node.jsспособ делать вещи.Хотелось бы получить некоторую помощь.

Обновление # 1

Дайте мне посмотреть, смогу ли я разбить это на пару небольших вопросов.Я ненавижу даже задавать подобные вопросы, но документация по Node.js очень скудная, и большая часть документации, написанной 6 месяцев назад, уже устарела.

1) Поэтому я могу использовать net.stream.write () дляотправить данные на удаленный сервер, но я не знаю, как получить ответ.Я даже не уверен, как тестировать, когда write () закончен, потому что он не принимает обратный вызов.

2) Несколько подсказок о том, как работает весь event.emit, было бы здорово.Я думаю, что это действительно ключевой камень, который я упускаю во всех этих вещах.

Обновление # 2

Здесь я все еще запутался в реализации клиентской программы.Позвольте мне описать типичный запрос на отправку => получить ответную систему:

1) Я привязываю обратные вызовы к сетевому модулю для получения ответов и других событий, включая необходимые привязки для получения ответа от сервера.

2) Я использую stream.write () для отправки запроса на сервер.

3) Затем я ничего не делаю, потому что мое связанное событие «data» получит ответ от сервера.

Здесь все становится сложнее.Предположим, что я вызываю stream.write () дважды до того, как будет вызвано мое связанное событие "data".Теперь у меня проблема.Когда происходит событие «data», как мне узнать, на какой из 2 запросов он отвечает?Я гарантированно, что ответы будут проходить в том же порядке, что и запросы?Что делать, если ответы возвращаются в другом порядке?

1 Ответ

8 голосов
/ 19 октября 2010

Прежде всего, давайте проясним, что такое 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, эта функция еще не выполнена.Передача функции здесь - это, по сути, ярлык для добавления прослушивателя для события connection объекта сервера.После этого мы запускаем сервер с #5.

Что теперь происходит в случае входящего соединения?

  1. Поскольку функция, которую мы передали createServer, былапривязанный к событию connection, теперь он выполняется.

  2. Добавляет прослушиватели событий connect, data и end к stream object (который представляетотдельное соединение) путем подключения обратных вызовов для событий.

  3. После этого stream запускает событие connect, поэтому функция, переданная в #2, выполняется и записывает hello\r\n до потока.Как функция узнает, в какой поток она должна записать? Замыкания - это ответ, функция наследует область, в которой она была создана, поэтому внутри функции stream все еще ссылается на отдельное соединение, которое вызвало этот самый обратный вызов, в котором мы сейчас находимся.

  4. Теперь клиент отправляет некоторые данные по соединению, что делает объект stream вызывающим его событие data, так как мы привязали функцию к этому событию в #3, теперь мы отображаем входящиеданные обратно клиенту.

  5. В случае, если клиент закрывает соединение, вызывается функция, которую мы связали в #4, которая записывает goodbye\r\n и после этого закрывает соединениес нашей стороны.

Делает ли это что-то более ясным?Ну, это определенно делает все намного проще.Узел, как и JavaScript внутри браузеров, single threaded.В данный момент времени происходит только одна вещь.

Чтобы описать это просто, все эти callbacks попадают в глобальную очередь и затем вызываются одна за другой, поэтому эта очередь может (абстрагироваться) выглядетьthis:

 | 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, в котором вы сейчас находитесь, не завершится.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...