2012-09-12 3 views
0

J'ai un problème qui défie l'explication. Voici ce que je veux:étrange comportement node.js et redis

  • Le client se connecte au serveur de noeud par socket.io, envoie son SID
  • Redis vérifie si ledit SID est dans son magasin, sinon, ne dégage pas de « authentifié », si le sid est dans le magasin, puis émettre « authentifié »
  • Dès réception de l'authentification, les options supplémentaires sont données

Sons assez simple, et il devrait être. Cependant cela se produit:

  • Le client se connecte avec un thats SID dans le magasin de Redis
  • serveur Node.js vérifie que le SID est dans le magasin, mais ne parvient pas à émettre ledit « authentifié »

Cependant , quand je redémarre le serveur de noeud, tout semble fonctionner très bien: S. Mais quand je procède à enlever la clef du magasin, et l'ajoute encore (par? Auth et? Logout) le "authentifié" n'est pas encore émis.

Code client:

<?php 
session_start(); 
header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1 

require "./libraries/Predis.php"; 


if(isset($_GET['logout'])) { 
    session_regenerate_id(); 
} 

$sid = sha1(session_id()); 
$redis = new Predis\Client(); 

echo "<h1>SID: " . $sid . "</h1>"; 

if(isset($_GET['auth'])) { 
    $redis->set($sid, mt_rand(1,20000)); 
    $redis->expire($sid, 1800); 
    echo "auth set<br />"; 
} 

if ($redis->get($sid)) { 
    // he is authenticad, show something else 
    echo "auth found<br />"; 
} 

?> 
<html> 
<head> 
    <title>Node Test VTclient</title> 
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script> 
    <script src="http://the_server.dev:11337/socket.io/socket.io.js"></script> 
</head> 
<body> 
    <p id="text">access denied</p> 
    <script type="text/javascript"> 
     var connected = false; 
     var authenticated = false; 
     if(typeof io == 'undefined') { 
      trigger_error();   
     } else { 

      var socket = io.connect('http://vtvserver.dev:11337/', { 
       'reconnection delay' : 1, 
       'max reconnection attempts' : 1 
      }); 

      socket.on('connect', function (data) { 

       connected = true;    
       socket.emit('success_connect',{sid: '<?php echo $sid; ?>'}); 
       $('#text').html('connected'); 

       socket.on('get_bids', function (data) {    
        $('#bids').html(''); 
        if(typeof data === 'object') { 
         $.each(data.rows, function(key, value) { 
          add_bid(value.bid_id, value.bid_amount); 
         }); 
        }      
       }).on('reconnecting', function (reason) { 

        trigger_error(reason); 
        $('#text').html('disconnected'); 
        socket.disconnect(); 

       }).on('authenticated', function(data) { 
        $('#text').html('authorised!'); 
        // successful auth 
        $('#bidding').show(); 

       }).on('disconnect', function (data) { 

        connected = false; 

       }).on('bid_placed', function (data) { 

        add_bid(data.id, data.amount); 

       }).on('own_bid_placed', function(data){ 

        if(!data.error) { 
         alert('bieding geplaatst!'); 
        } else { 
         alert('Uw bieding is ongeldig.'); 
        } 
       }); 
     }); 


     } 

     function trigger_error(reason) { 
      $('#text').html('Server is down...'); 
     } 

     function add_bid(id, amount) { 
      $('#bids').append($('<option>', { value : id }).text(amount)); 
     } 

    $(function() { 
     $('#disconnect').click(function() { 
      if(connected === true) { 
       socket.disconnect(); 
       $('#text').html('Disconnected from server.'); 
      } 
     }); 

     $('#bid').click(function() { 
      var amount = $('#amount').val(); 

      // commit the bid to the server 
      socket.emit('add_bid', {amount: amount}); 
     }); 
    }) 
    </script> 
    <label for="bids">Biedingen:</label> 
    <select name="bids" id="bids" multiple='multiple' style='width:100px; height:150px'></select> 
    <fieldset style="display:none" id="bidding"> 
     <legend>Plaats bieding</legend> 
     <label for="amount"><Bedrag: </label><input type="text" id="amount" name="amount" value='0' /> 
     <button id="bid">Bied</button> 
    </fieldset> 

    <button id="disconnect">Disconnect</button> 
</body> 

Code Serveur:

var 
    cfg = require("./config").cfg(),    
    sys = require("sys"), 
    url = require("url"), 
    http = require("http"), 
    qs = require("querystring"), 
    redis = require("redis"), 
    redis_client = redis.createClient(cfg.redis.port, cfg.redis.host), 
    express = require("express"), 
    mysql = require("./node_modules/mysql"), 
    //ch = require("./node_modules/channel").channel(cfg.msg_backlog, cfg.msg_truncate), 
    sio = require('./node_modules/socket.io'); 


//require ('./node_modules/sherpa'); 
//require ('./node_modules/log'); 
require ('./node_modules/simplejsonp'); 

redis_client.on("error", function (err) { 
     console.log("REDIS error: " + err); 
}); 

var app = express(); 

app.configure(function(){ 

}); 

app.get('/', 
     function (req,res) { 
      if (req.headers['referer']) { 
       log(req.connection.remoteAddress + "/" + req.headers['referer']); 
      } 
      else { 
       log(req.connection.remoteAddress + " /"); 
      } 
      res.writeHead(307, {'Location':'http://' + cfg.domain}); 
      res.end(); 
}); 

app.listen(cfg.server_port, cfg.server_public_ip); 

/* Create the IO server */ 
var server = http.createServer(app); 
var io = sio.listen(server); 

// minify the browser socket io client 
io.enable('browser client minification'); 

server.listen(11337); 

io.set('log level', 2); 

io.sockets.on('disconnect', function(data) { 
    console.log('client disconnected'); 
}); 



/** 
* Enable authentication 
* @param {[type]} handshakeData [description] 
* @param {Function} callback  [description] 
* @return {[type]}     [description] 
*/ 

// Anonymous or authenticaed user? 
io.on('connection', function (socket) { 

    var sql_client = mysql.createClient({ 
     host  : cfg.database.server, 
     user  : cfg.database.user, 
     password : cfg.database.pass, 
     database : cfg.database.primary 
    }); 

    console.log('incoming connection');  
    socket.emit('access', 'granted'); 

    socket.on('success_connect', function(data) {   
     console.log('Client connected: ' + data.sid); 

     sql_client.query('SELECT * FROM `bids`',function(error, results) { 
       if(error) { 
        console.log('Error: ' + error); 
        return false; 
       } 
       console.log('emitting get_bids...'); 
       socket.emit('get_bids', {rows: results}); 
     }); 

     // if the user is authenticated, flag it as such 
     redis_client.get(data.sid, function(err, reply) { 

      var authenticated = false; 

      if(err) { 
      console.log("Fatal error: " + err); 
      } 

      console.log('Got response from redis...'); 
      if(reply !== null) { 
      console.log('auth succesful for '+data.sid); 
      socket.emit('authenticated', { sid : data.sid}); 
      authenticated = true; 
      } 

      // LEFT JOIN user_bids ON user_bids_bid_id = bid_id 

      if(authenticated === true) { 
      // safest way: only listen for certain commands when the user is autenticated 
      socket.on('add_bid', function(data) { 
       var amount = data.amount;   
       var values = [amount]; 
       var error = false; 

       // validate the amount 
       var regexp = new RegExp(/^\d{1,5}(\.\d{1,2})?$/); 

       if(typeof amount === 'undefined' || amount < 1.00 || !amount.match(regexp)) { 
       error = 'invalid_bid'; 
       } 

       socket.emit('own_bid_placed', {amount: amount, error : error}); 

       if(!error) { 

       sql_client.query('INSERT INTO `bids` SET bid_amount = ?',values,function(error, results) { 
        if(error) { 
         console.log('Error: ' + error); 
        } 
        console.log('Inserted: ' + results.affectedRows + ' row.'); 
        console.log('Id inserted: ' + results.insertId); 

        io.sockets.emit('bid_placed', {id: results.insertId, amount: amount}); 
        }); 
       } 
      }); 
      } 
     }); 
    }); 

    sql_client.end(); 

    socket.on('disconnect', function(data) { 
     console.log('Client disconnected'); 
    }); 
}); 

console.log('Server running at http://'+cfg.server_public_ip+':'+cfg.server_port+'/'); 
+0

Oui il le: redis_client = redis.createClient (cfg.redis.port, cfg.redis.host), et: redis_client.get (data.sid, function (err, reply) { Et ne sert rien? – thecodeassassin

+0

Désolé, mon oeil doit avoir glacé sur une barre de défilement. Il semblerait que vous ayez détruit votre connexion mysql trop tôt (il semble que lorsque vous avez une connexion socket, vous établissez une connexion mysql, définissez des gestionnaires qui dépendent de cette connexion, puis fermez la connexion). – ebohlman

Répondre

0

Je l'ai fixé en créant le client Redis lorsqu'un client se connecte:

io.on('connection', function (socket) { 
var redis_client = redis.createClient(cfg.redis.port, cfg.redis.host); 
}); 
Questions connexes