2015-06-03 10 views
0

我想使用express/nodejs創建一個基本的消息傳遞系統。雖然我能夠向所有用戶成功發送消息。我需要用戶能夠以1對1的私人方式互相發送消息。使節點陣列在視圖中可訪問

我在下面想要做的事很簡單。當用戶登錄時,一旦會話已被驗證,將用戶對象存儲在clients數組中,並使該數組在視圖中可訪問 - 就是這樣!

的意圖是,這個數組將在服務器上成長爲用戶登錄和我需要使其通俗易懂的觀點,這樣我就可以生成可用於上網聊天的用戶列表。

我曾嘗試幾種不同的方法,在所述視圖中的空數組下面的結果的方法。

我的目標是簡單的在線用戶存儲在服務器上的一組,因爲他們登錄並必須在視圖訪問該數組。

我欣賞任何建議。

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; 

index.hjs

<div class="messenger-user" ng-repeat="n in clients"> 
    <div class="avatar-icon glyphicon glyphicon-user"> 
    </div> 
    <div class="user-meta"> 
     {{n.user.firstname}} {{n.user.lastname}} 
    </div> 
</div> 

index.hjs的JavaScript

socket.emit('load users', function(clients){ 
    $scope.clients = clients; 
    $scope.$apply(); 
}); 

回答

0

非常有意義。它發送一個空數組,因爲您在填充它之前發送它。

目前: 1)MySQL查詢啓動檢索和填充用戶陣列。

2)另一方面,將觸發插座on 'connection'事件(第24行),其發射的用戶陣列,這是當前爲空。

3)您的MySQL查詢結束(第3行)並返回您想要的數據。

4)在回調函數中,您設置另一個io.sockets.on('connection')的收聽者。這太遲了,因爲你已經設置了一個,並且連接事件已經發生。所以你有兩個監聽器用於同一事件,而第二個監聽器從不觸發。

您應該做的是等待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 
+0

感謝您的答覆。一旦SQL查詢成功執行,我正在填充數組。有一種方法可以通過一個'connection'事件來完成嗎? – AnchovyLegend

+0

無論如何,你必須只有一個「連接」監聽器。一旦數組被填充後,通過套接字發送它。如果它是空的,發送'連接'是無用的。爲什麼你絕對想要通過連接發送它?讓客戶端連接並等待,並在準備發送時發出數組。 –

+0

這正是我一直在努力完成的,沒有成功。我們怎麼知道'準備好發送'的時間。我覺得這比它需要更復雜:(我只是試圖爲每個登錄併發送到視圖的用戶填充數組... – AnchovyLegend