Синхронное чтение TCP в Node.js

Есть ли способ сделать синхронное чтение TCP-сокета в node.js?

Я хорошо знаю, как сделать это асинхронно, добавив обратный вызов к событию "data" сокета:

socket.on('data', function(data) {
    // now we have the string data to do whatever with
});

Я также знаю, что попытка блокировки с помощью вызова функции вместо регистрации обратных вызовов противоречит дизайну узла, но мы пытаемся обновить старый модуль узла, который действует как клиент для моего университета, при этом сохраняя обратную совместимость. Итак, в настоящее время мы имеем:

var someData = ourModule.getData();

куда getData() Раньше за этим стояла куча логики, но теперь мы просто хотим отправить на сервер "run getData()" и дождаться результата. Таким образом, вся логика на стороне сервера, а не дублируется на стороне клиента и сервера. Этот модуль уже поддерживает TCP-соединение с сервером, поэтому мы просто используем его.

Вот решения, которые я попробовал:

  1. Найдите блокирующую функцию чтения для сокета, скрытого где-то похожего на библиотеку сокетов python в сетевом модуле узла.

    string_from_tcp = socket.recv(1024)
    

    Проблема здесь в том, что он, кажется, не существует (неудивительно, потому что он идет вразрез с идеологией узла).

  2. Этот модуль синхронизации добавляет то, что мне нужно, но не имеет поддержки Windows; поэтому я должен добавить это.

  3. Найдите функцию, которая позволяет узлу разблокировать цикл обработки событий, а затем вернуться назад, чтобы это работало:

    var theData = null;
    clientSocket.on('data', function(data) {
        theData = data;
    });
    
    clientSocket.write("we want some data");
    
    while(theData === null) {
        someNodeFunctionThatUnblocksEventLoopThenReturnsHere(); // in this function node can check the tcp socket and call the above 'data' callback, thus changing the value of theData
    }
    
    // now theData should be something!
    

    Очевидная проблема здесь в том, что я не думаю, что такая вещь существует.

  4. Используйте функции генератора ECMAScript 6:

    var stringFromTcp = yield socketRead(1024);
    

    Проблема в том, что мы заставляем студентов обновлять свои клиенты JavaScript до этого нового синтаксиса, и понимание ES6 выходит за рамки тех курсов, которые используют это.

  5. Используйте node-gyp и добавьте в наш модуль узлов интерфейс к библиотеке C++ TCP, который поддерживает синхронные чтения, такие как boost asio. Это, вероятно, сработало бы, но заставить модуль узла компилироваться с кросс-платформой Boost было огромной болью. Поэтому я пришел в Stack Overflow, чтобы убедиться, что я не слишком усложняю эту проблему.

Проще говоря, я просто пытаюсь создать программу JavaScript для командной строки, которая поддерживает синхронное чтение tcp.

Так есть еще идеи? И заранее извините, если это кажется кощунственным в контексте проекта узла, и спасибо за любой вклад.

1 ответ

Решение

В итоге я выбрал вариант 5. Я нашел небольшую, быструю и простую в создании библиотеку TCP на C++ ( netLink) и написал для нее обертку для модуля узла под метким названием netlinkwrapper.

Модуль построен на Windows и Linux, но так как это аддон C++, для его сборки вам потребуется сконфигурированный node-gyp.

Я надеюсь, что больше никому не придётся связываться с Node.js, как я использовал этот модуль, но если вам нужно заблокировать цикл обработки событий с помощью вызовов TCP, это, вероятно, ваша единственная ставка.

Другие вопросы по тегам