断开连接时销毁socket.io连接

Posted

技术标签:

【中文标题】断开连接时销毁socket.io连接【英文标题】:Destroy socket.io connection when disconnect 【发布时间】:2016-07-08 02:36:30 【问题描述】:

我遇到了一个问题,即用户从 socket.io 断开连接并且实例仍然处于活动状态,包括所有事件侦听器。

下面的两个示例都是我的部分代码,因为有数百行。但问题仍然存在于这段代码中。

app.js 示例:

var express = require('express'),
    app = express(),
    routes = require('./routes/index'),
    server = require('http').createServer(app);

io = require('socket.io').listen(server);

app.engine('handlebars', exphbs( defaultLayout: 'main' ));
app.set('view engine', 'handlebars');

app.use('/', routes);

server.listen(3000, function() 
    console.log('listening on *:3000');
);

module.exports = app;

index.js 路由示例:

var express = require('express'),
    router = express.Router();

router.get('/', function(req, res) 
    res.render('home', 
        title: 'Home'
    );

    setupSocket(req);
);

function setupSocket(req) 
    io.on('connection', function(socket) 
        console.log('connected')
    );


module.exports = router;

这将导致:

第一次连接:

connected

第二次连接:

connected
connected

第三次连接:

connected
connected
connected

等等。这将在重新加载页面、新选项卡、新浏览器或其他任何内容时继续,直到我重新启动节点服务器。

在我的代码中,我将数据从客户端发布到 mongo 数据库,由于上述问题,请求将发布相同数据的多个副本。

所以问题是,如何防止实例在用户离开页面后保持活动状态?

【问题讨论】:

可能重复:***.com/questions/5048231/… 谢谢,不幸的是,这并不能解决问题,我运行socket.on('disconnect', function() socket.disconnect(); ); 但是当我重新加载页面时,它仍然在控制台中保持“已连接”状态 【参考方案1】:

正如您在每次连接或刷新时所说,您将获得多个connected 字符串输出,这是因为您在每个请求上都附加了 socket.io 侦听器。这就是你应该如何在你的 socket.io 上附加 connected 监听器:

var express = require('express'),
    app = express(),
    routes = require('./routes/index'),
    server = require('http').createServer(app);

io = require('socket.io').listen(server);

app.engine('handlebars', exphbs( defaultLayout: 'main' ));
app.set('view engine', 'handlebars');

app.use('/', routes);

// Your listener should be outside your routes
io.on('connection', function(socket) 
    console.log('connected')
);

server.listen(3000, function() 
    console.log('listening on *:3000');
);

module.exports = app;

然后在你的 index.js 上删除 setUp 函数:

var express = require('express'),
    router = express.Router();

router.get('/', function(req, res) 
    res.render('home', 
        title: 'Home'
    );
);

module.exports = router;

【讨论】:

那么你将如何只在某个 URL 上打开一个套接字? 你为什么想要那个?您希望您的套接字服务器每次都运行 我的套接字启动了另一个函数,所以我只希望它在某个 URL 上注册一个套接字连接。我将它放在 URL 请求块下,但遇到与 OP 相同的问题。 但这是特定于前端的。在您的网站上,只要您在某个 URL 上,您就会创建到套接字服务器的连接。您的套接字服务器与 URL 无关,套接字是事件流。 啊,好吧,我想我是误会了。所以在前端我只会发出一条消息,说用户访问了我的套接字可以处理的那个页面,对吗?

以上是关于断开连接时销毁socket.io连接的主要内容,如果未能解决你的问题,请参考以下文章

socket.io 服务器在注册客户端断开连接时非常延迟

socket.io 在空闲时断开客户端的连接

Socket.io 不会在断开连接时向房间发送消息

刷新时Socket.io断开连接?

更改请求标头 SOCKET.IO(无需断开连接和重新连接)

如何在 android 上检查 socket.io 连接或断开连接?