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+'/');
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
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