【问题标题】:Socket.io: io.on('connection) repeats three timessocket.io: io.on('connection) 重复3次
【发布时间】:2020-04-23 03:00:26
【问题描述】:

以下是位于应用程序入口点的一些服务器端代码的摘录:

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)
  })
});

在运行我的开发服务器时,我希望看到“ABC”打印到控制台一次。但是,它打印了 3 次(ABC、ABC、ABC)。为什么会这样? io 变量不在应用程序的其他任何地方使用。我很确定它与客户端逻辑无关(因为此时客户端没有发出任何请求)为了完整参考,下面显示了整个 app.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)
}

【问题讨论】:

    标签: node.js express socket.io


    【解决方案1】:

    当然,每次与客户端建立连接时都会呈现消息“ABC”。

    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

    【讨论】:

    • 你的结论不正确。 ABC 消息仅与正在启动的 socket.io 连接有关,与send-chat-message 无关。此问题可能是由与连接相关的问题引起的。
    • 你说的很对,我会修改我的答案,谢谢
    • 那么,问题出在哪里?解决方法是什么?
    • 我认为问题出在客户端。不知何故,三个客户端同时连接到服务器。检查您的代码,它可以正常工作,您可以在链接中看到它。
    猜你喜欢
    • 2020-07-16
    • 2021-07-28
    • 2014-08-07
    • 1970-01-01
    • 2021-12-21
    • 2016-01-23
    • 2023-01-01
    • 2021-09-26
    相关资源
    最近更新 更多