如何防止与页面重定向 socket.io 多个连接

How to prevent multiple connections with socket.io on page redirect?

本文关键字:io 连接 socket 重定向 何防止      更新时间:2023-09-26

我正在使用Express和 Socket.IO 构建一个NodeJS应用程序,该应用程序指示客户端脚本根据某些条件将用户重定向到不同的页面。 我遇到的问题是,当它重定向时,我得到了另一个套接字连接。 在我的代码中,我根据套接字 ID 跟踪套接字会话,以便将消息发送到特定套接字以对其执行操作。由于重定向创建了一个具有新ID的新套接字,因此我无法再实现此功能。

我尝试在重定向之前断开套接字

,在连接后发送消息以断开以前的套接字等。 似乎没有什么可以让我轻松管理带有重定向的单个套接字连接。

免责声明:我对 Node、Socket.io 等完全陌生。

这是我的服务器代码:

var http    = require('http'),
    express = require('express');
var app     = express();
var server  = http.createServer(app);
var io      = require('socket.io')(server);
var port = 8000;
app.use(express.static(__dirname + '/public'));
var activeClientId;
var clientQ = [];
var clients = {};
var numUsers = 0;
function updateActive() {
    console.log("Updating active client...");
    activeClientId = clientQ.shift();
    var active = clients[activeClientId];
    while (!checkActive() && clientQ.length > 0) {
        if (typeof active !== 'undefined' && active !== null) {
            delete clients[activeClientId];
            active.disconnect();
            console.log("Force Disconnect Client: " + activeClientId);
            numUsers = Object.keys(clients).length;
        }
        activeClientId = clientQ.shift();
        active = clients[activeClientId];
    }
    if (checkActive()) {
        console.log("New Active Client: " + activeClientId);
    } else {
        console.log("Active Client Not Updated");
    }
};
function checkActive() {
    var active = clients[activeClientId];
    return typeof active !== 'undefined' && active !== null && active.connected;
};
io.on('connection', function (socket) {
    clients[socket.id] = socket;
    clientQ.push(socket.id);
    numUsers = Object.keys(clients).length;
    console.log("Client " + "#" + numUsers + " connected: " + socket.id);
    if (numUsers === 1) {
        activeClientId = socket.id;
    } else {
        updateActive();
    }
    if (socket.id === activeClientId) {
        socket.emit('game');
    } else {
        socket.emit('wait');
    }
    socket.on('play', function () {
        console.log("users: " + numUsers);
        console.log("curId: " + socket.id);
        console.log("actId: " + activeClientId);
        if (socket.id !== activeClientId && numUsers > 1) {
            socket.emit('kick');
        } else {
            console.log("Game started on client: " + socket.id);
        }
    });
    socket.on('disconnect', function () {
        console.log("Client " + "#" + numUsers + " disconnected: " + socket.id);
        delete clients[socket.id];
        numUsers = Object.keys(clients).length;
        updateActive();
        socket.broadcast.emit('disconnected', {
            numUsers: numUsers
        });
    });
});
server.listen(port, function () {
    console.log('Listening on port: %d', port);
});

而我的客户:

$(function () {
    var socket = io();
    socket.on('game', function (data) {
        socket.disconnect();
        window.location.replace("/game");
    });
    socket.on('wait', function (data) {
        socket.disconnect();
        window.location.replace("/wait");
    });
});

/game页面的代码:

$(function () {
    var socket = io();
    socket.on('connect', function (data) {
        socket.emit('play');
    });
    socket.on('kick', function(data) {
        socket.disconnect();
        alert("KICK!");
        window.location.replace("/wait");
    });
});

'wait页面的代码:

$(function () {
    var socket = io();
    socket.on('connect', function (data) {
        socket.emit('wait');
    });
    socket.on('game', function (data) {
        socket.disconnect();
        window.location.replace("/game");
    });
});

在客户端添加一些 IO() 中的选项

{transports: ['websocket'], upgrade: false}

var socket = io('http://localhost:8000',{transports: ['websocket'], upgrade: false});