Как изменить номер порта, если он уже занят?

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

Я работаю с Vite, express и ws. Это один из кодов моего сервера.

const { WebSocketServer } = require('ws')

const sockserver1 = new WebSocketServer({ port: 311 })
sockserver1.on('connection', ws => {
    sockserver1.clients.forEach(client => {
        client.send(`A new player connection has been established`);
    })

    ws.on('message', data => {
        sockserver1.clients.forEach(client => {
            client.send(`${data}`)
        })
    })

    ws.on('close', () => {
        sockserver1.clients.forEach(client => {
            client.send(`A player has disconnected`)
        })
    })

    ws.onerror = function () {
        console.info('websocket error')
    }
});

Когда я запускаю это во второй раз, он терпит неудачу и сообщает, что порт :: 311 занят. Как я могу добавить 1 к номеру порта, пока не найду тот, который не занят? Я заметил, что Vite делает это.

Что делает установка порта на 0?

Anston Sorensen 17.08.2024 22:53

Это... не выдает мне ошибку для этого сервера! Следующий сервер выдает мне ошибку, поскольку для него установлено значение, отличное от 0.

Alex 17.08.2024 22:57

Однако localhost:0 ограничен.

Alex 17.08.2024 22:57

Этот вопрос похож на: Случайные свободные TCP-порты Nodejs. Если вы считаете, что это другое, отредактируйте вопрос, поясните, чем он отличается и/или как ответы на этот вопрос не помогают решить вашу проблему.

jabaa 17.08.2024 23:16

@jabaa Ой, да, это может быть дубликат. Я пытался узнать, был ли уже подобный вопрос

Anston Sorensen 17.08.2024 23:19

«Как я могу добавить 1 к номеру порта, пока не найду тот, который не занят? Я заметил, что Vite делает это». Vite имеет открытый исходный код. Вы можете проверить это в исходном коде. github.com/vitejs/vite

jabaa 17.08.2024 23:26

Не думаю, что мне рекомендовали этот вопрос. Как закрыть вопрос?

Alex 17.08.2024 23:48

Я не уверен, сможете ли вы закрыть свои вопросы своей репутацией. Вы можете либо удалить его, либо подождать, пока другие его закроют.

jabaa 17.08.2024 23:49

Что ж, я удовлетворен ответом Энстона, так что я согласен, что мой вопрос будет закрыт. Спасибо всем!

Alex 17.08.2024 23:53

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

jabaa 17.08.2024 23:53

Да. Я буду иметь это в виду. Спасибо, Джабаа!

Alex 17.08.2024 23:55

@Алекс, посмотри на мой исправленный ответ

Anston Sorensen 18.08.2024 07:38
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
12
88
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

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

Вот как это будет выглядеть:

const { WebSocketServer } = require('ws');
const net = require('net');

function findAvailablePort(startPort, callback) {
    const server = net.createServer();
    server.listen(startPort, () => {
        server.once('close', () => {
            callback(startPort);
        });
        server.close();
    });
    server.on('error', () => {
        findAvailablePort(startPort + 1, callback);
    });
}

findAvailablePort(311, (availablePort) => {
    const sockserver1 = new WebSocketServer({ port: availablePort });
    console.info(`WebSocket server started on port ${availablePort}`);

    sockserver1.on('connection', ws => {
        sockserver1.clients.forEach(client => {
            client.send(`A new player connection has been established`);
        });

        ws.on('message', data => {
            sockserver1.clients.forEach(client => {
                client.send(`${data}`);
            });
        });

        ws.on('close', () => {
            sockserver1.clients.forEach(client => {
                client.send(`A player has disconnected`);
            });
        });

        ws.onerror = function () {
            console.info('websocket error');
        }
    });
});

Это может вызвать состояние гонки. Порт может быть свободным при создании сервера в тестовой функции и использоваться другой программой при создании реального сервера. Вам следует либо использовать реальный сервер для теста, либо запросить порт у операционной системы. Ваш подход может время от времени давать сбой. В зависимости от количества параллельных серверов вам придется протестировать множество портов, прежде чем вы найдете свободный.

jabaa 17.08.2024 23:22

Вы пробовали это с портом 0? В ОП написано, они попробовали, но это не работает так, как вы описали.

jabaa 18.08.2024 13:21

Я попробовал, и это работает. Я не понимаю. Где Алекс говорит, что это не работает?

Anston Sorensen 18.08.2024 16:55

Я имею в виду, нужно ли мне присылать скриншоты работы? Что я сделал? Это были мои ненужные комментарии ранее?

Anston Sorensen 18.08.2024 17:10

Я проголосовал против, потому что ОП прямо написал в комментарии, что port: 0 у них не работает. Если это сработает, вопрос требует дополнительных разъяснений. Ответ, который не работает для ОП, бесполезен.

jabaa 18.08.2024 19:13

Это когда он сказал, что localhost:0 ограничен? Я даже не уверен, что это значит

Anston Sorensen 18.08.2024 20:56

Ладноааа тогда. Ответ отменен

Anston Sorensen 18.08.2024 20:58

Да, это то, что я имел в виду. Вы попросили ОП использовать порт 0, и ответ заключался в том, что первый сервер был запущен на порту 0, а второй сервер вышел из строя. Это не имеет особого смысла, но я не пробовал и доверял ОП. Я отменил свой отрицательный голос.

jabaa 18.08.2024 21:02

Это просто странно, потому что это сработало, когда я его запустил. Каждый раз он использует другой порт. Обычно порт стоит 30 тысяч на винде

Anston Sorensen 18.08.2024 21:53

Возможно, проблема в том, что я доверял заявлению ОП. Возможно, ОП сделал что-то не так.

jabaa 18.08.2024 21:54

Вот сообщение, которое я получаю, когда пытаюсь его открыть (вероятно, мне следовало отправить его раньше): «Этот адрес использует сетевой порт, который обычно используется для целей, отличных от просмотра веб-страниц. Firefox отменил запрос в целях вашей защиты». Chrome не может получить доступ к серверу. Я тоже не уверен, почему порт 0 работает. Это происходит от порта 0 до порта 9. Порт 10 работает нормально. Это еще один вопрос, который мне следует задать? Посмотрите, знает ли кто-нибудь еще, в чем может быть проблема?

Alex 18.08.2024 22:16

@Alex Не пытайтесь открыть адрес с портом 0. Порт 0 не существует. Это особое значение, которое сигнализирует операционной системе о том, что вам нужен случайный свободный порт. Операционная система выбирает порт для сервера. Вам нужно узнать этот порт и использовать его в своем клиенте. Пожалуйста, предоставьте более подробную информацию и информацию об отладке в будущем. «Это... не выдает мне ошибку для этого сервера! Следующий сервер выдает мне ошибку, поскольку для него установлено значение, отличное от 0. Однако Localhost:0 ограничен». это бесполезно.

jabaa 18.08.2024 22:19

Я думаю, что теперь, когда у него есть ответ, этот вопрос его больше не волнует. Я имею в виду, я был таким раньше

Anston Sorensen 18.08.2024 22:28

Нет, я знаю. Я пытаюсь помочь вам понять, что я делаю, чтобы мы все знали, что происходит.

Alex 18.08.2024 22:35

@jabaa Полезно знать на будущее. Что касается комментария, который вам не помог, я имел в виду, что когда я запускаю сценарий дважды, я не получаю сообщение об ошибке о том, что порт 0 уже занят, но я получаю сообщение об ошибке, что другие порты для другого сервера заняты. Я не рассказал вам о других серверах, поэтому моя ошибка.

Alex 18.08.2024 22:35

Я новичок в подобных веб-сайтах, поэтому пытаюсь выработать хорошие привычки общения (особенно для Stack Overflow).

Alex 18.08.2024 22:37

@Alex Так мой новый ответ подойдет тебе или нет? Вот что мне действительно хотелось бы знать

Anston Sorensen 18.08.2024 22:47

Да, это работает. Я проверил ваше последнее редактирование, и оно работает, так что спасибо Анстону Соренсену и Джабаа за уделенное время. Я все еще буду помнить о состоянии гонки. И, к счастью, мой проект предназначен только для моих друзей, поэтому я могу их предупредить.

Alex 18.08.2024 23:09

@Alex Вопрос в том, работает ли port: 0. Это был бы правильный ответ. Он не тестирует порты и не имеет состояния гонки. Если я правильно понимаю, комментарии под вашим вопросом неверны. Серверы запустились правильно, но вы не знали правильный URL-адрес клиента.

jabaa 18.08.2024 23:14

Этот пакет поможет вам с такими потребностями: https://github.com/sindresorhus/get-port

Это также имеет проблему состояния гонки. get-port может вернуть свободный порт, который используется другой программой, прежде чем сервер сможет к нему привязаться. Я бы не рекомендовал этот пакет.

jabaa 19.08.2024 12:29

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