gpt4 book ai didi

javascript - Socket.io 为所有客户端分配相同的 ID

转载 作者:行者123 更新时间:2023-11-30 08:05:10 24 4
gpt4 key购买 nike

我正在尝试将所有已连接的客户端保存在一个对象中。但正如我所想,连接的客户端都具有相同的 ID。因此,如果对象 connections 具有所有已连接的套接字,当我尝试向 connections['mac'] 发送消息时,它只会出现在我的屏幕上,就像我发送给我。这是授权码:

app.post('/auth', function(req, res){   // routes.auth(hash, db, io, pseudoArray, connections)
var username = req.body.username,
password = req.body.password;
if (username != "" && password != ""){
authenticate(username, password, db, hash, function(err, user){
if (user) {
// Regenerate session when signing in
// to prevent fixation
console.log('user authenticated');
req.session.regenerate(function(){
req.session.user = user.name;
req.session.success = 'Authenticated as ' + user.name
+ ' click to <a href="/logout">logout</a>. '
+ ' You may now access <a href="/restricted">/restricted</a>.';

io.sockets.on('connection', function (socket) {
socket.set('pseudo', req.session.user, function(){
pseudoArray.push(req.session.user);
var sessionuser = req.session.user;
socket.emit('pseudoStatus', 'ok');
connections[req.session.user] = socket;
console.log("user " + req.session.user + " connected");
});
});
res.cookie('rememberme', '1', { maxAge: 900000, httpOnly: true });
res.redirect('home');
});
} else {
console.log('auth failed');
req.session.error = 'Authentication failed, please check your '
+ ' username and password.'
+ ' (use "tj" and "foobar")';
res.redirect('login');
}
});
} else {
res.redirect('connect');
}
});

我向其他客户端发送消息的代码:

exports.addfriend = function(connections, io){
return function(req, res){
// var collection = db.get('go1');
var username = req.session.user;
var friend = req.body.name;
console.log(connections[''+friend+'']);
connections[''+friend+''].emit('addRequest', username);
return;
}
}

我之前在路由文件中有这个授权码,我想我应该在 app.js 上运行它。我这样做了,但它仍然无法正常工作。有人能告诉我我错过了什么吗?

最佳答案

您的代码的问题在于您的一个 HTTP 路由中有一个 Socket.IO 传入连接处理程序。这意味着处理程序仅在访问路由后应用,除此之外您应该只有一个 Socket.IO 连接处理程序。

您需要做的是将 HTTP 和 Socket.IO 处理程序分开,并且由于您使用的是 session ,因此允许 Socket.IO 处理授权。

首先,将套接字处理程序移到 HTTP 处理程序之外:

app.post('/', handler);
io.sockets.on('connection', handler);

然后,定义 Socket.IO 授权设置以从 Express 获取 session 对象。假设您使用 express.cookieParser() 因为您有 session 和 session 存储,我们需要从外部引用它们:

var MemoryStore = express.session.MemoryStore;

var session_key = 'express.sid';
var session_secret = 'for signed cookies';
var session_store = new MemoryStore();

var cookieParser = express.cookieParser(session_secret);

app.use(cookieParser);
app.use(express.session({
secret: session_secret,
store: session_store,
key: session_key
});

既然可以访问 session 对象和 cookie 解析器,我们就可以定义授权设置了:

io.set('authorization', function(handshake, callback) {
if (handshake.headers.cookie) {
cookieParser(handshake, null, function(err) {
// Use depends on whether you have signed cookies
// handshake.sessionID = handshake.cookies[session_key];
handshake.sessionID = handshake.signedCookies[session_key];

session_store.get(handshake.sessionID, function(err, session) {
if (err || !session) {
callback('Error or no session.', false);
} else {
handshake.session = session;
callback(null, true);
}
});
});
} else {
callback('No session cookie found.', false);
}
});

这段代码的作用是检查客户端是否有 session cookie。如果不是,它不会授权 Socket.IO 连接。如果是,它会解析 cookie,找到关联的 session ,并将 session 与套接字一起存储。现在您可以通过套接字访问 session 属性:

app.post('/', function(req, res) {
req.session.user = 'genericusername';
res.send(200);
});

io.sockets.on('connection', function(socket) {
var session = socket.handshake.session;
session.user // genericusername
});

至于您的代码,它将如下所示:

var http = require('http');
var express = require('express');
var app = express();

var server = http.createServer(app);
var io = require('socket.io').listen(server);

var MemoryStore = express.session.MemoryStore;

var session_key = 'express.sid';
var session_secret = 'for signed cookies';
var session_store = new MemoryStore();

var cookieParser = express.cookieParser(session_secret);

app.use(cookieParser);
app.use(express.session({
secret: session_secret,
store: session_store,
key: session_key
});

路由处理器:

app.post('/auth', function(req, res) {
var username = req.body.username,
var password = req.body.password;

if (username != '' && password != '') {
authenticate(username, password, db, hash, function(err, user) {
if (user) {
req.session.regenerate(function() {
req.session.user = user.name;
req.session.success = 'Authenticated as ' + user.name + ' click to <a href="/logout">logout</a>. You may now access <a href="/restricted">/restricted</a>.';
res.cookie('rememberme', '1', {
maxAge: 900000,
httpOnly: true
});
res.redirect('/home');
});
} else {
req.session.error = 'Authentication failed, please check your username and password. (use "tj" and "foobar")';
res.redirect('/login');
}
});
} else {
res.redirect('/connect');
}
});

然后是 Socket.IO 配置:

io.set('authorization', function(handshake, callback) {
if (handshake.headers.cookie) {
cookieParser(handshake, null, function(err) {
// Use depends on whether you have signed cookies
// handshake.sessionID = handshake.cookies[session_key];
handshake.sessionID = handshake.signedCookies[session_key];

session_store.get(handshake.sessionID, function(err, session) {
if (err || !session) {
callback('Error or no session.', false);
} else {
handshake.session = session;
callback(null, true);
}
});
});
} else {
callback('No session cookie found.', false);
}
});

io.sockets.on('connection', function(socket) {
var session = socket.handshake.sessionl
socket.set('pseudo', session.user, function() {
socket.emit('pseudoStatus', 'ok');
connections[session.user] = socket;
});
});

关于javascript - Socket.io 为所有客户端分配相同的 ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19273235/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com