Node.js connect работает только на localhost

Я написал небольшое приложение Node.js, используя connect, которое обслуживает веб-страницу, а затем отправляет ей регулярные обновления. Он также принимает и записывает пользовательские наблюдения в файл на диске.

Он работает нормально, пока я нахожусь на локальном хосте, но я не могу заставить другие компьютеры в той же интрасети его увидеть. Я использую порт 3000, но переход на порт 8080 или 80 не помог.

Вот код, который я использую для установки соединения:

var io = require('socket.io'),
  connect = require('connect');

var app = connect().use(connect.static('public')).listen(3000);
var chat_room = io.listen(app);

Как указано выше, я попытался изменить номер порта на 8080 или на 80 и не заметил никакой разницы, поэтому я не думаю, что это проблема брандмауэра (но я могу ошибаться). Я также подумал, прочитав аналогичные вопросы, касающиеся HTTP, добавить 0.0.0.0 к методу listen(), но похоже, что listen() не принимает параметр маски IP.


person schaz    schedule 26.12.2012    source источник
comment
иногда ваш интернет-провайдер блокирует порты 80 и 8080. Я склонен сказать, что проблема в вашем маршрутизаторе, межсетевом экране или провайдере.   -  person mkoryak    schedule 26.12.2012
comment
listen() в Connect по существу обертывает _ 2_, который по умолчанию принимает соединения со всех IP-адресов (хост 0.0.0.0), так что это должно быть проблема.   -  person Miikka    schedule 26.12.2012
comment
mkoryk, я нахожусь в локальной сети, все мои попытки были в локальной сети. Это мой роутер, и, насколько я понимаю, порты не заблокированы.   -  person schaz    schedule 26.12.2012
comment
Миикка, я не уверен, но я думаю, что вы говорите мне, что то, что у меня есть, должно работать.   -  person schaz    schedule 26.12.2012
comment
Для тех, кто пришел сюда через Google: если вы разместили службу в облаке Google и столкнулись с этой проблемой, сначала убедитесь, что вы добавили порт в правила исключений облачный брандмауэр, а также в брандмауэре операционной системы   -  person Atul    schedule 10.08.2016


Ответы (11)


Скорее всего, сокет вашего сервера привязан к петлевому IP-адресу 127.0.0.1 вместо символического IP-адреса «все IP-адреса» 0.0.0.0 (обратите внимание, что это НЕ сетевая маска). Чтобы подтвердить это, запустите sudo netstat -ntlp (если вы работаете в Linux) или netstat -an -f inet -p tcp | grep LISTEN (OSX) и проверьте, к какому IP-адресу привязан ваш процесс (найдите строку с ": 3000"). Если вы видите "127.0.0.1", проблема в этом. Исправьте это, передав "0.0.0.0" в вызов listen:

var app = connect().use(connect.static('public')).listen(3000, "0.0.0.0");
person Peter Lyons    schedule 26.12.2012
comment
Спасибо, Питер. Я пробовал 0.0.0.0, но забыл о кавычках. Да, netstat показал, что сервер сокетов привязан к 127.0.0.1. Теперь я могу с той же машины связаться с сервером node.js либо с локального хоста, либо с IP-адреса, назначенного dhcp. Я все еще не попадаю на сервер с других машин в той же сети. Я вернусь к проверке всех брандмауэров и маршрутизаторов. Это не должно быть так сложно, как я, потому что все они под моим контролем. - person schaz; 27.12.2012
comment
Ок, отлично. Если машины действительно находятся в одной сети (той же локальной подсети), то трафик будет передаваться напрямую от узла к узлу, не проходя через маршрутизатор. Так что скорее всего это брандмауэр на одном из хостов. - person Peter Lyons; 27.12.2012
comment
Это тоже была моя проблема. Спасибо! - person Pipo; 25.02.2013
comment
Я вижу следующее. Означает ли это, что "весь" порт привязан? tcp6 0 0 :::5000 :::* LISTEN 11363/node - person dcsan; 10.07.2016
comment
Да, для tcpv6 - person Peter Lyons; 10.07.2016
comment
что значит tcp46 0 0 *.3000 *.* LISTEN? - person svassr; 30.08.2016
comment
ты спас мне день. - person Vlad; 02.03.2017

Чтобы получить доступ других пользователей к вашему локальному компьютеру, я обычно использую ngrok. Ngrok предоставляет ваш localhost в Интернете и имеет оболочку NPM, которую легко установить и запустить:

$ npm install ngrok -g
$ ngrok http 3000

См. Этот пример использования:

введите здесь описание изображения

В приведенном выше примере локально запущенный экземпляр парусов по адресу: localhost: 3000 теперь доступен в Интернете и обслуживается по адресу: http://69f8f0ee.ngrok.io или https://69f8f0ee.ngrok.io

person arcseldon    schedule 07.01.2016
comment
Это намного лучше, чем я изначально искал - person Viliami; 24.01.2017
comment
Обратите внимание, что это решение ненадежно, так как ссылка пересылки меняется каждый раз, когда вы останавливаете службу ngrok. - person Shaishav Jogani; 02.11.2017
comment
Это зависит от того, чего вы пытаетесь достичь. Комментировать, что это ненадежно, без указания контекста, бесполезно и вводит в заблуждение. Часто используйте ngrok в качестве разработчика для тестирования разрабатываемых мною служб, которые вызываются внешней системой как часть веб-потока. Он всегда был надежным и хорошо отвечал этим требованиям. - person arcseldon; 08.11.2017
comment
Вау, это так круто! Он предоставляет мое приложение узла в Интернете, а не только в локальной сети. - person Lance; 05.02.2018
comment
дуууууууууууууууде, это УДИВИТЕЛЬНО! Lifechanger! ржу не могу - person NieMaszNic; 13.11.2020
comment
@arcseldon, я получаю ошибку - SocketException: ошибка ОС: истекло время ожидания соединения, errno = 110, address = 10.xxx.xx.xxx, port = 41xxx. в моем приложении flutter с локального адреса api только на реальных устройствах, но на эмуляторе он отлично работает с любым решением. - person s.j; 08.04.2021
comment
Я хочу проголосовать за это несколько раз. - person CITIZENDOT; 27.04.2021

Привязка к 0.0.0.0 - это половина дела. Существует брандмауэр IP (отличный от того, который указан в системных настройках), который блокирует TCP-порты. Следовательно, порт должен быть разблокирован и там, выполнив:

sudo ipfw add <PORT NUMBER> allow tcp from any to any
person Ashish Kaila    schedule 04.06.2013
comment
sudo ipfw add разрешить tcp от любого до любого 3000 - person rob; 05.12.2013
comment
Ашиш, грабитель, я последовал твоим инструкциям, но безуспешно. Вот мой исходный вопрос stackoverflow.com/q/20772940. Не могли бы вы оставить комментарий? - person Sergey; 25.12.2013
comment
ipfw это особый бренд unix? не работает на Ubuntu 14 - person dcsan; 10.07.2016
comment
@dcsan попробуйте ufw для ubuntu - person fart-y-goer; 05.09.2016
comment
изменил localhost на 0.0.0.0, и это сработало! Благодарю. - person Piyush Patel; 07.02.2017

В вашем приложении делает его доступным с любого устройства в сети:

app.listen(3000, "0.0.0.0");

Для NodeJS в Azure, GCP и AWS

Для виртуальной машины Azure, развернутой в диспетчере ресурсов, проверьте группу безопасности виртуальной сети и откройте порты или диапазоны портов, чтобы сделать ее доступной, в противном случае - в конечных точках облака, если виртуальная машина развернута в старой версии Azure.

Просто поищите аналог для GCP и AWS.

person ClusterAtlas    schedule 07.07.2017

У меня есть очень простое решение этой проблемы: process.argv дает вам список аргументов, переданных в приложение узла. Итак, если вы запустите:

node server.js 0.0.0.0

Ты получишь:

process.argv[0] //=> "node"
process.argv[1] //=> "server.js"
process.argv[2] //=> "0.0.0.0"

Таким образом, вы можете использовать process.argv[2], чтобы указать это в качестве IP-адреса, который вы хотите слушать:

http.listen(3000, process.argv[2]);

Теперь ваше приложение прослушивает "все" IP-адреса, например http://192.168.1.4:3000/your_app.

Надеюсь, это кому-то поможет!

person akelec    schedule 29.04.2017

Дистрибутив Fedora или Centos проверяет ваши selinux и firewalld, в моем случае firewalld заблокировал соединение:

Selinux: $sestatus
SELinux status:                 enabled
SELinuxfs mount:                /sys/fs/selinux
SELinux root directory:         /etc/selinux
Loaded policy name:             targeted
Current mode:                   {{checkmode}}
Mode from config file:          {{checkconfig}}
Policy MLS status:              enabled
Policy deny_unknown status:     allowed
Max kernel policy version:      30

Firewalld status: $systemctl status firewalld
person soloproper    schedule 12.09.2016
comment
Отключение моей службы firewalld помогло. Теперь я могу получить доступ к своему приложению узла из локальной сети. Но я думаю, что это не выход. Как я могу указать своему брандмауэру просто разрешить подключение к порту моего приложения node.js? - person Lance; 05.02.2018

Работая для меня с этой строкой (просто добавьте --listen при запуске):

node server.js -p 3000 -a : --listen 192.168.1.100

Надеюсь, это поможет...

person Meloman    schedule 24.05.2017

После долгой борьбы с этой проблемой мне удалось решить ее, разрешив входящие соединения на порт 8080.

Поскольку вы написали, что решение .listen(8080, "0.0.0.0") не работает для вас, убедитесь, что подключения к порту 8080 разрешены через ваш брандмауэр.

Это сообщение помогло мне создать новое правило для входящих подключений в настройках брандмауэра Windows.

person Bar Horing Amir    schedule 26.10.2018

Такая же проблема здесь, для меня решение заключалось в редактировании строки файла server.js 161

 var server = app.listen(argv.port, '**<server.ip.adress.here>**', function() {
 console.log('Cesium development server running publicly.  Connect to localhost:%d/', server.address().port);
    });

заменить localhost> на <server.ip.adress.here>

person Ed.    schedule 14.07.2020

в моем случае мне пришлось использовать как символический IP-адрес 0.0.0.0, так и перезвонить при прослушивании сервера cors: ^ 2.8.5, express: ^ 4.17.1,

const cors = require("cors");
app.use(cors());

const port = process.env.PORT || 8000;
app.listen(port,"0.0.0.0" ,() => {
  console.log(`Server is running on port ${port}`);
});

вы также можете использовать свой локальный IP-адрес вместо 0.0.0.0. В ОС Ubuntu вы можете найти свой IP-адрес с помощью команды

ifconfig | grep "inet " | grep -v 127.0.0.1

введите описание изображения здесь Затем используйте IP-адрес:

app.listen(port,"192.168.0.131" ,() => {
  console.log(`Server is running on port ${port}`);
});

Если вы используете фиксированный IP-адрес, такой как 192.168.0.131, тогда вы должны использовать его при вызове сервера, например, Моя конфигурация вызова api для реагирующего клиента приведена ниже:

REACT_APP_API_URL = http://192.168.0.131:8001/api
person Lord    schedule 14.11.2020

ПРОВЕРЬТЕ НАСТРОЙКИ АНТИВИРУСА БРАНДВОЛЛА.

У меня есть сервер NodeJS, работающий на ПК с Windows 10, но когда я помещаю IP-адрес и порт (например, http://102.168.1.123:5000) в браузер другого компьютера в моей локальной сети ничего не произошло, хотя на главном компьютере все работало нормально.

(Чтобы узнать IP-адрес вашего Windows, запустите CMD, затем IPCONFIG)

Ответ Бар Хоринга Амира указывает на настройки брандмауэра Windows. На моем ПК брандмауэр Windows был отключен, поскольку антивирус McAfee добавил свой собственный брандмауэр.

Моя система начала работать на других компьютерах после того, как я добавил порт 5000 в «Порты и системные службы» в настройках брандмауэра McAfee на компьютере с NodeJS. Другие антивирусные программы будут иметь аналогичные настройки.

Я серьезно рекомендую сначала попробовать это решение с Windows.

person London_Phil    schedule 01.01.2021