Socket.IO在刷新浏览器时添加连接

时间:2018-07-26 01:53:33

标签: node.js sockets socket.io

我在NodeJS应用程序上添加Socket.IO(我是新手),当我刷新网页并在Chrome上按F5时,会根据我的服务器日志创建一个新的套接字:

  

用户连接的SWpG6Fv9mjmMoLZRAAAA
  用户断开了SWpG6Fv9mjmMoLZRAAAA
  用户连接的gvtxcnJR6sC4DW7CAAAB
  用户连接的gvtxcnJR6sC4DW7CAAAB
  用户断开了gvtxcnJR6sC4DW7CAAAB
  用户断开了gvtxcnJR6sC4DW7CAAAB
  用户连接的pWPjZbVV_-lnVL4RAAAC
  用户连接的pWPjZbVV_-lnVL4RAAAC
  用户连接的pWPjZbVV_-lnVL4RAAAC
  用户断开连接pWPjZbVV_-lnVL4RAAAC
  用户断开连接pWPjZbVV_-lnVL4RAAAC
  用户断开连接pWPjZbVV_-lnVL4RAAAC
  用户连接的sP7lJaRrH6Hrevp7AAAD
  用户连接的sP7lJaRrH6Hrevp7AAAD
  用户连接的sP7lJaRrH6Hrevp7AAAD
  用户连接的sP7lJaRrH6Hrevp7AAAD
  用户断开了sP7lJaRrH6Hrevp7AAAD
  用户断开了sP7lJaRrH6Hrevp7AAAD
  用户断开了sP7lJaRrH6Hrevp7AAAD
  用户断开了sP7lJaRrH6Hrevp7AAAD
  用户连接的-86W-itTDwrsyeVGAAAE
  用户连接的-86W-itTDwrsyeVGAAAE
  用户连接的-86W-itTDwrsyeVGAAAE
  用户连接的-86W-itTDwrsyeVGAAAE
  用户连接-86W-itTDwrsyeVGAAAE

关于为什么会发生这种情况的任何想法?

这是我的代码:

index.js:

"use strict";

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

const opn = require('opn');

const login = require('./scripts/login.js');
const main = require('./scripts/main.js')(socket);
const init = require('./scripts/init.js');
const config = require('./scripts/config.js');

app.use(express.static('public'));
app.set('view engine', 'ejs');
http.listen(3000, function () {
    console.log('==> Servidor iniciado -- Puerto 3000');
});

opn('http://localhost:3000');

app.use('/', main);

main.js

"use strict";

const express = require('express');
const router = express.Router();
const main = function (socket) {

    // Home page route.
    router.get('/', function (req, res) {
        socket.on('connection', function (socket) {
            console.log('user connected ' + socket.id);
            socket.on('disconnect', function () {
                console.log('user disconnected ' + socket.id);
            });
        });

        res.render('main', {
            page_name: 'main'
        });
    });

    return router;
};

module.exports = main;

index.html

<script src="/socket.io/socket.io.js" charset="utf-8"></script>
<script>
    var socket = io();

    socket.on('connect', function (data) {
        console.log('connected');
    });
</script>

1 个答案:

答案 0 :(得分:2)

您实际上并没有获得多个连接,而是为connection事件添加了越来越多的侦听器,因此最终多次处理同一事件(导致出现多个连接)。 / p>

在将socket.io connect事件侦听器放置在这样的路由处理程序中时:

// Home page route.
router.get('/', function (req, res) {
    socket.on('connection', function (socket) {
        console.log('user connected ' + socket.id);
        socket.on('disconnect', function () {
            console.log('user disconnected ' + socket.id);
        });
    });

    res.render('main', {
        page_name: 'main'
    });
});

然后,每次点击/路由时,您都会为connection事件添加另一个重复的侦听器。因此,当一个新的socket.io连接发生时,您将拥有多个侦听器,因此您将多次处理同一连接(创建令人困惑的日志记录)。

解决方案通常是将socket.io侦听器移到任何路由处理程序之外,因此只能安装一次。但是,如果由于其他原因将它们放在路由处理程序中,那么您还必须解决其他问题。无论如何,socket.io侦听器必须位于任何路由处理程序之外,因此仅在服务器启动时安装一次。

也许是这样的:

"use strict";
const router = require('express').Router();

module.exports = function(io) {

    io.on('connection', function (socket) {
        console.log('user connected ' + socket.id);
        socket.on('disconnect', function () {
            console.log('user disconnected ' + socket.id);
        });
    });

    // Home page route.
    router.get('/', function (req, res) {
        res.render('main', {
            page_name: 'main'
        });
    });

    return router;
};

请注意,您在同一个作用域中还有两个变量,分别名为socket。这是一个不好的做法,因为它会阻止访问范围较大的代码,并且通常会在处理代码时造成错误或混乱的机会。

您的较高级别的名称可能应该命名为io,以免与socket事件的connection参数混淆,并且io是引用时的常规约定主socket.io服务器实例。