Javascript 路由终结点外部的访问请求属性
上述代码运行良好,但存在一个问题。如果用户刷新页面/或重新进入页面,则连接会成倍增加。我应该把Javascript 路由终结点外部的访问请求属性,javascript,node.js,express,Javascript,Node.js,Express,上述代码运行良好,但存在一个问题。如果用户刷新页面/或重新进入页面,则连接会成倍增加。我应该把路由器.get('/'..放在外面,但我必须使用req.user.id 知道如何获取user.id吗???正如我已经提到的,您不需要处理这个问题,因为在刷新时,客户端关闭旧连接,新页面加载应该再次连接,因此没有多个连接 我的样品 只需刷新几次选项卡,您将在服务器上获得以下输出: var app = require('express')(); var http = require('http').Serv
路由器.get('/'..
放在外面,但我必须使用req.user.id
知道如何获取user.id吗???正如我已经提到的,您不需要处理这个问题,因为在刷新时,客户端关闭旧连接,新页面加载应该再次连接,因此没有多个连接 我的样品 只需刷新几次选项卡,您将在服务器上获得以下输出:
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', function(req, res){
res.sendfile('index.html');
});
io.on('connection', function(socket){
console.log('CONNECTED!');
socket.on('disconnect', function () {
console.log('DISCONNECTED!');
});
});
http.listen(3000, function(){
console.log('listening on *:3000');
});
传递用户id
无论如何,这应该通过将用户id信息从客户端传递到服务器来完成,您可以通过为其定义新事件来完成,如authenticated
CONNECTED!
DISCONNECTED!
CONNECTED!
DISCONNECTED!
CONNECTED!
...
或者将它与每个事件一起作为附加数据传递
socket.on('authenticated', function(userId) {
socket.on('disconnect', function () {
console.log(userId + ' DISCONNECTED!');
});
});
另一种方法是使用模块,如
从路由发出事件
为了从路由发出事件,您需要在express
和socket.io
之间建立某种连接,这可以通过如下映射实现:
sessionSockets.on('connection', function (err, socket, session) {
//your regular socket.io code goes here
//and you can still use your io object
});
而内部路由只需使用sockets[userId].emit
来发出事件
参考文献
var sockets = {};
socket.on('authenticated', function(userId) {
sockets[userId] = socket;
...
});
现在让我们实现sockets\u controller.js
// file - app.js
// In your middleware authorization or another middleware
// you have to pass the user to the response.
app.use(function(req, res, next){ res.locals['user'] = req.user; });
...
var io = require('socket.io').listen(server);
require('./sockets_controller.js')(io);
现在,对于您的客户端(让我假设它是您的渲染引擎):
这样,您就可以从其他地方为特定用户获取套接字。
例如,在另一条路线上
script.
const id_user = '#{user.id}',
io = io.connect("...");
io.on('connect', function(socket){
if(id_user != 'undefined')
io.emit('get_id_user', {
id_user: id_user
});
});
我认为刷新时客户端会关闭旧的连接,因为客户端正在从服务器断开连接,而新的连接应该在页面加载时打开,所以没有多个连接。@gevorg客户端有这样的连接要断开吗?是的,您不能通过编程调用它,但在页面刷新时客户端正在从服务器断开连接。Lo好的,我的答案了解更多详细信息。我找到了问题所在。这是因为我在express的路由终结点内放置了。因此,如果我刷新页面,它将有许多套接字的init()。我尝试将其放置在外部,这使得init()无论用户刷新或重新进入页面多少次,总是一次。它起作用了,但我有一个问题,我需要为我的套接字发出
req.user.id
。@JamieJordan不管怎样,你应该在某一点上将userId从客户端传递到服务器,我建议通过定义单独的事件来完成,如authenticated
,看看更新的答案。+1很好回答。我认为这应该被标记为已接受。我已经实现了我的方法,使用socket.io事件将用户id传递到打开的套接字,以获得一个示例。因此,您可以从Jade获取user.id。如何在服务器端获取该id?而不使用route.use(“/”…
使用这种方法是不可能的,因为您需要在客户端获取用户的id。流程是:客户端接收用户的id,套接字io连接到服务器,并发送事件以识别用户打开的套接字,列表中填充了套接字。我成功了。我使用模块调用节点localstorage,我存储id,然后检索它。已工作:D
// file - app.js
// In your middleware authorization or another middleware
// you have to pass the user to the response.
app.use(function(req, res, next){ res.locals['user'] = req.user; });
...
var io = require('socket.io').listen(server);
require('./sockets_controller.js')(io);
global.clients = {}; // Make a global object - so you can use it everywhere
module.exports = function(io){
io.on('connection', function(socket){
socket.on('get_id_user', function(data){
if (data){
if (!data.id_user) return;
this.id_user = data.id_user;
// One client can have more than one socket opened!!
if (clients[this.id_user]){
clients[this.id_user][this.id] = this;
}
else {
clients[this.id_user] = {};
clients[this.id_user][this.id] = this;
}
}
});
socket.on('disconnect', function(){
if (clients[this.id_user]){
delete clients[this.id_user][this.id];
if(Object.keys(clients[this.id_user]).length == 0){
delete clients[this.id_user];
}
}
});
};
script.
const id_user = '#{user.id}',
io = io.connect("...");
io.on('connect', function(socket){
if(id_user != 'undefined')
io.emit('get_id_user', {
id_user: id_user
});
});
app.post('/whatever', function(req, res){
for(var socketID in clients[req.user.id_user]){
clients[req.user.id_user][socketID].emit(...);
}
});