Сокет.клиент ввода-вывода отвечает только один раз

#node.js #express #socket.io

#node.js #экспресс #socket.io

Вопрос:

Я создаю экспресс-сервер, который вызовет index.html страница для перенаправления на новую страницу при получении запроса post. Все работает нормально, но только в первый раз. Я должен регулярно перезапускать сервер, чтобы он работал. Вот несколько фрагментов кода.

 //server.js

const app = express();
app.use(express.static(`${__dirname}/public`));

const server = http.createServer(app);
const io = socketIo(server, {'force new connection': true });

io.on('connection', (socket) => {
    console.log('New client connected');

    app.post('/redirect', (req,res) => {
        socket.emit('redirect');
        res.status(200).send('Redirected');
    });
});  
 <body>

   <!-- Jquery CDN -->
   <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
   <!-- Socket.IO -->
   <script src="/socket.io/socket.io.js"></script>

   <script>
   let socket = io.connect({'force new   connection': true });
   socket.on('connect', () => {
       console.log('Connected to Server');
   });

   socket.on('redirect', () => {
       window.location.replace("https://google.com");
   });
   </script>

</body>  

Ответ №1:

Основная проблема заключается в том, что у вас есть свой маршрут внутри прослушивателя подключения к сокету. Маршрут должен быть зарегистрирован только один раз. И connection срабатывает несколько раз.

 const app = express();
app.use(express.static(`${__dirname}/public`));

const server = http.createServer(app);
const io = socketIo(server, {'force new connection': true });

app.post('/redirect', (req,res) => {
    res.status(200).send('Redirected');
    io.emit('redirect');
    // io.to(someSocketOrRoom).emit('redirect');

});

io.on('connection', (socket) => {
    console.log('New client connected');     
});
  

Если вы хотите отправить сообщение в сокет при получении сообщения извне сокета, в данном случае HTTP Post. Вам нужно использовать io.emit для отправки во все сокеты или io.to().emit для отправки в определенный.

Теперь нет особого смысла перенаправлять с помощью socket.io , если вы отправляете сообщение на /redirect , почему бы вам просто не перенаправить пользователя с помощью res.redirect , ничего не передавая.

Комментарии:

1. Да, я знаю, что не имеет особого смысла перенаправлять с помощью socket.io . Однако я новичок в socket. ввод-вывод, и для меня это просто как практическая программа «Hello World». Я пытаюсь использовать ваше решение, но у меня есть запрос. Кто-то онлайн сказал мне, что вы должны использовать ввод-вывод только для установления соединения, и после этого вы должны использовать сокеты для двунаправленной связи один к одному. Так это правильная логика?

2. io.emit использует то же самое socket для передачи данных, он просто перебирает все сокеты. Таким образом, это двунаправленная связь. И вы можете получить доступ к определенному сокету, я прокомментирую эту часть в коде: io.to..

3. Я немного обновил свой ответ, чтобы объяснить о io.emit