Синхронное чтение 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-соединение с сервером, поэтому мы просто используем его.
Вот решения, которые я попробовал:
Найдите блокирующую функцию чтения для сокета, скрытого где-то похожего на библиотеку сокетов python в сетевом модуле узла.
string_from_tcp = socket.recv(1024)
Проблема здесь в том, что он, кажется, не существует (неудивительно, потому что он идет вразрез с идеологией узла).
Этот модуль синхронизации добавляет то, что мне нужно, но не имеет поддержки Windows; поэтому я должен добавить это.
Найдите функцию, которая позволяет узлу разблокировать цикл обработки событий, а затем вернуться назад, чтобы это работало:
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!
Очевидная проблема здесь в том, что я не думаю, что такая вещь существует.
Используйте функции генератора ECMAScript 6:
var stringFromTcp = yield socketRead(1024);
Проблема в том, что мы заставляем студентов обновлять свои клиенты JavaScript до этого нового синтаксиса, и понимание ES6 выходит за рамки тех курсов, которые используют это.
Используйте 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, это, вероятно, ваша единственная ставка.