Socket.io: io.on ('connection) повторяется три раза - PullRequest
0 голосов
/ 22 апреля 2020

Ниже приведена выдержка из некоторого кода на стороне сервера, расположенного в точке входа приложения:

const app = express()
const chatServer = require('http').Server(app);
chatServer.listen(3000)
const io = require('socket.io')(chatServer);

io.on('connection', (socket) => {
  console.log('ABC')
  socket.on('send-chat-message', message => {
    socket.broadcast.emit('chat-message', message)
  })
});

После запуска моего сервера разработки я ожидал, что «AB C» будет напечатан один раз на приставка. Однако он печатает три раза (AB C, AB C, AB C). Почему это происходит? Переменная io НЕ используется где-либо еще в приложении. Я почти уверен, что это не имеет ничего общего с логикой на стороне клиента c (так как на данный момент клиент не делает никаких запросов). И для полной справки, весь код приложения. js показан ниже:

const express = require('express')
require('./db/mongoose')
const playerRouter = require('./routers/player')
const contractRouter = require('./routers/contract')
const bodyParser = require('body-parser');
const hbs = require('express-handlebars')
const path = require('path')
const passport = require('passport');
const flash = require('connect-flash');
const session = require('express-session');

// Define paths for Express config
const viewsPath = path.join(__dirname, '../templates/views')
const partialsPath = path.join(__dirname, '../templates/partials')
const layoutPath = path.join(__dirname, '../templates/layouts')

const app = express()
const chatServer = require('http').Server(app);
chatServer.listen(3000)
const io = require('socket.io')(chatServer);

// Passport Config
require('./middleware/passport')(passport);

//Setup handlebars engine and views location
app.engine('hbs', hbs({
  extname: 'hbs',
  defaultLayout: 'main',
  layoutsDir: layoutPath,
  partialsDir: partialsPath,
}));

app.set('view engine', 'hbs')
app.use(express.static('public'))
app.set('views', viewsPath)

io.on('connection', (socket) => {
  console.log('ABC')
  socket.on('send-chat-message', message => {
    socket.broadcast.emit('chat-message', message)
  })
});

app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.json())

// Express session
app.use(
  session({
    secret: 'secret',
    resave: true,
    saveUninitialized: true
  })
);

// Passport middleware
app.use(passport.initialize());
app.use(passport.session());

// Connect flash
app.use(flash());

// Global variables
app.use(function (req, res, next) {
  res.locals.success_msg = req.flash('success_msg');
  res.locals.error_msg = req.flash('error_msg');
  res.locals.error = req.flash('error');
  res.locals.currentUser = req.user
  next();
});

app.use(playerRouter)
app.use(contractRouter)

module.exports = app

Вот код на стороне клиента (для краткости я не включил весь файл HTML):

const socket = io('http://localhost:3000')
const messageContainer = document.getElementById('message-container')
const messageForm = document.getElementById('send-container')
const messageInput = document.getElementById('message-input')

socket.on('chat-message', message => {
  appendMessage(`Opponent: ${message}`)
})


messageForm.addEventListener('submit', e => {
  e.preventDefault()
  const message = messageInput.value
  appendMessage(`You: ${message}`)
  socket.emit('send-chat-message', message)
  messageInput.value = ''
})

const appendMessage = (message) => {
  const messageElement = document.createElement('div')
  messageElement.innerText = message
  messageContainer.append(messageElement)
}

1 Ответ

0 голосов
/ 22 апреля 2020

Конечно, сообщение 'AB C' отображается каждый раз, когда устанавливается соединение с клиентом.

const express = require("express");
const path = require("path");
const app = express();
const http = require("http").Server(app);
const io = require("socket.io")(http);

// Here declare fiel static, as index.html, css, javascript.
app.use(express.static(path.resolve(__dirname, "../public")));

io.on("connection", socket => {
  console.log("ABC");
  socket.on("send-chat-message", message => {
    socket.broadcast.emit("chat-message", message);
  });
});

http.listen(8080, () => {
  console.log("Starting...");
});

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
  </head>
  <body>
    <div id="message-container"></div>
    <form id="send-container">
      <input id="message-input" type="text" />
      <button type="submit">submit</button>
    </form>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.2.0/socket.io.js"></script>
    <script>
      const socket = io();
      const messageContainer = document.getElementById("message-container");
      const messageForm = document.getElementById("send-container");
      const messageInput = document.getElementById("message-input");

      socket.on("chat-message", message => {
        appendMessage(`Opponent: ${message}`);
      });

      messageForm.addEventListener("submit", e => {
        e.preventDefault();
        const message = messageInput.value;
        console.log(message);
        appendMessage(`You: ${message}`);
        socket.emit("send-chat-message", message);
        messageInput.value = "";
      });

      const appendMessage = message => {
        const messageElement = document.createElement("div");
        messageElement.innerText = message;
        messageContainer.append(messageElement);
      };
    </script>
  </body>
</html>

Здесь вы можете увидеть работающий код.

Надеюсь, это поможет. Любые вопросы комментируйте.

https://codesandbox.io/s/expressjs-chat-9v8lo

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...