Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/390.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使节点阵列在视图中可访问_Javascript_Node.js_Session_Express - Fatal编程技术网

Javascript 使节点阵列在视图中可访问

Javascript 使节点阵列在视图中可访问,javascript,node.js,session,express,Javascript,Node.js,Session,Express,我正在尝试使用express/nodejs创建一个基本的消息传递系统。虽然我能够成功地向所有用户发送消息。我需要用户能够以一对一的私人方式相互发送消息 下面我想做的很简单。当用户登录时,一旦会话被验证,将用户对象存储在客户机数组中,并使该数组在视图中可访问——就是这样 其目的是,随着用户登录,该阵列将在服务器上增长,我需要使其在视图中易于访问,以便生成可用于聊天的在线用户列表 我尝试了几种不同的方法,下面的方法会导致视图中出现一个空数组 我的目标是在在线用户登录时将其存储在服务器上的一个数组中,

我正在尝试使用express/nodejs创建一个基本的消息传递系统。虽然我能够成功地向所有用户发送消息。我需要用户能够以一对一的私人方式相互发送消息

下面我想做的很简单。当用户登录时,一旦会话被验证,将用户对象存储在
客户机
数组中,并使该数组在视图中可访问——就是这样

其目的是,随着用户登录,该阵列将在服务器上增长,我需要使其在视图中易于访问,以便生成可用于聊天的在线用户列表

我尝试了几种不同的方法,下面的方法会导致视图中出现一个空数组

我的目标是在在线用户登录时将其存储在服务器上的一个数组中,并在视图中访问该数组

我感谢你的建议

index.js

var express     = require('express');
var app = express();
var bodyParser = require('body-parser');
var mysql       = require('mysql');
var session     = require('client-sessions');
var server      = require('http').createServer( app );
var io          = require('socket.io').listen( server );
var clients = [];

app.locals.delimiters = '<% %>';


app.get('/', function(req, res){
    if(req.session && req.session.user.username){
        mysql.query("SELECT * FROM users WHERE username = ? AND pass = ? LIMIT 1", [req.session.user.username, req.session.user.pass], function(error, results, fields){
            if(results.length === 0){
                req.session.reset();
                res.redirect('/login');
            }else{
                res.locals.user = results[0];

                io.sockets.on('connection', function(socket){
                    clients.push({user : res.locals.user, socket : socket});
                });

                res.render('index');
            }
        });
    }else{
        res.redirect('/login');
    }
});

server.listen( 3331 ); //chat port

io.sockets.on('connection', function(socket){  

    //load all users
    socket.on('load users', function(){
       io.emit('load users', {clients : clients});      
    });

    socket.on('error', function(err){
        console.error(err.stack);
    });
});

module.exports = app;

这很有道理。它发送一个空数组,因为您在填充它之前发送了它

目前: 1) 启动MySQL查询以检索和填充用户数组

2) 同时,会触发“连接”上的套接字
事件(第24行),该事件会发出当前为空的用户数组

3) MySQL查询结束(第3行)并返回所需的数据

4) 在回调函数中,为('connection')上的io.sockets.on设置另一个侦听器。。太晚了,因为您已经设置了一个,并且连接事件已经发生。因此,同一事件有两个侦听器,而第二个侦听器从不触发

您应该做的是等待SQL查询结束,然后填充数组并将其发送到客户端

编辑2:不要同时使用HTTP连接和套接字进行身份验证。您试图存储HTTP请求中的用户对象,以及与HTTP请求无关的套接字。对插座执行所有操作:

var clients = [];

io.sockets.on('connection', function(socket){

    socket.on('credentials', function(data){ // data == { "username":"John" , "password":"123456" }
        login(data, socket); // sending credentials and socket to the login function, so both are defined there.
    })
    socket.on('error', function(err){
        console.error(err.stack);
    });
});

function login(data, socket){
    mysql.query("SELECT * FROM users WHERE username='"+data.username+"' AND pass='"+data.password+"' LIMIT 1", [req.session.user.username, req.session.user.pass], function(error, results, fields){
        if(!results.length){
            req.session.reset();
            res.redirect('/login');
        }else{
            clients.push({user : results[0], socket : socket}); // Both defined!
            io.emit('load users', {clients : clients});
            res.render('index');
        }
    });
}

server.listen( 3331 ); //chat port

谢谢你的回复。当SQL查询成功执行时,我当前正在填充数组。有没有办法通过一个
连接
事件来实现这一点?无论如何,您必须只有一个“连接”侦听器。填充阵列后,通过套接字发送它。如果它是空的,“连接时”发送它是无用的。为什么你绝对想通过连接发送?让客户端连接并等待,并在阵列准备好发送时发出阵列。这正是我一直试图实现的,但没有成功。我们如何知道“它准备好发送”的时间。我觉得这比它需要的要复杂得多:(我只是尝试为每个登录的用户填充一个数组,并将其发送到视图中……填充后就可以发送了:)这意味着在您的回调函数中填充它。我已经更新了我的andswer并添加了一些代码。感谢您的回复:)我尝试了类似的方法,问题是,
res.locals.user
在您的示例中未定义。这就是我最初将连接事件放在
get()
函数中的原因,因此
socket
res
都是定义的。
socket.emit('load users', function(clients){
    $scope.clients = clients;
    $scope.$apply();
});
var clients = [];

io.sockets.on('connection', function(socket){

    socket.on('credentials', function(data){ // data == { "username":"John" , "password":"123456" }
        login(data, socket); // sending credentials and socket to the login function, so both are defined there.
    })
    socket.on('error', function(err){
        console.error(err.stack);
    });
});

function login(data, socket){
    mysql.query("SELECT * FROM users WHERE username='"+data.username+"' AND pass='"+data.password+"' LIMIT 1", [req.session.user.username, req.session.user.pass], function(error, results, fields){
        if(!results.length){
            req.session.reset();
            res.redirect('/login');
        }else{
            clients.push({user : results[0], socket : socket}); // Both defined!
            io.emit('load users', {clients : clients});
            res.render('index');
        }
    });
}

server.listen( 3331 ); //chat port