我正在尝试学习节点JS,目前正在尝试扩展这篇文章。
http://www.gianlucaguarini.com/blog/push-notification-server-streaming-on-a-mysql-database/
我遇到了重大问题,因为我在SQL查询中获得了多个更新。
我只想发送一个套接字更新。
此问题出现在事务循环中,我得到多个套接字更新。
我一直在努力解决这个问题超过一个月,似乎无法自己解决(或使用谷歌搜索)
有人可以告诉我如何才能完成这项工作,所以每个客户端只能获得一次套接字更新。
我想要发生的事情是,当其中一个交易发生变化时,双方(买方和卖方)是唯一获得套接字更新的交易。
我该如何使这项工作?它非常接近我想要的但我无法克服最后的挑战。
请帮忙。
提前谢谢。
<html>
<head>
<title>GAT UPDATER</title>
<script src="/socket.io/socket.io.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<script src = "http://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
<script type="text/javascript" src="http://board.gameassettrading.com/js/jquery.cookie.js"></script>
</head>
<body>
<script>
var nodeuserid;
function getUserId() {
var url = window.location.href;
var user_id = url.replace('http://heartbeat.gameassettrading.com:4000/id/', '');
return user_id;
}
user_id = getUserId();
$.cookie('useridcookie', user_id, { expires: 1 });
var useridcookie = $.cookie("useridcookie");
// Get Base Url for development between local and dev enviroment
function getBaseURL() {
var url = location.href; // entire url including querystring - also: window.location.href;
var baseURL = url.substring(0, url.indexOf('/', 14));
if (baseURL.indexOf('http://localhost') != -1) {
// Base Url for localhost
var url = location.href; // window.location.href;
var pathname = location.pathname; // window.location.pathname;
var index1 = url.indexOf(pathname);
var index2 = url.indexOf("/", index1 + 1);
var baseLocalUrl = url.substr(0, index2);
return baseLocalUrl + "/";
}
else {
// Root Url for domain name
return baseURL + "/";
}
}
// set the base_url variable
base_url = getBaseURL();
document.domain = "transactionsserver.com"
// create a new websocket
var socket = io.connect('http://heartbeat.transactionsserver.com:4000');
socket.on('connect',function() {
var data = {
url: window.location.href,
};
socket.emit('client-data', data);
});
// this is always open you have to filter out the data you want
socket.on('notification', function (data) {
if(data.hasOwnProperty("data")) {
if(data.data[0]['seller_id'] != ''){
$('#StatusUpdate', window.parent.document).text( data.data[0]['seller_id']+ ':' + data.data[0]['seller_status'] +':'+ data.data[0]['buyer_id']+':'+ data.data[0]['buyer_status']).click();
}
}
window.parent.checkData(data,user_id);
if(data.hasOwnProperty("changed_user_id")) {
$('#StatusUpdate', window.parent.document).text( data.changed_user_id+ ':' + data.changed_user_status +':'+ data.changed_user_id).click();
}
});
</script>
</body>
</html>
服务器。 JS
var app = require("express")();
var path = require('path');
var mysql = require("mysql");
var http = require('http').Server(app);
var io = require("socket.io")(http);
var sockets = {};
var mysql = require('mysql'),
connectionsArray = [],
connection = mysql.createConnection({
multipleStatements: true,
host: 'localhost',
user: '*****',
password: '******',
database: 'transactionsdb',
port: 3306
}),
POLLING_INTERVAL = 1000,
pollingTimer;
// Add Redis For Comparing SQL Results againts Cache
var redis = require('redis');
var client = redis.createClient();
var express = require('express');
/* Creating POOL MySQL connection.*/
var pool = mysql.createPool({
connectionLimit: 100,
host: 'localhost',
user: '*****',
password: '*****',
database: 'transactionsdb',
debug: false
});
var count = 0;
var clients = [];
function processAllTransactions(sellsreply) {
pool.query('SELECT t.id,t.status,t.original_status, t.active, t.buyer_id, t.seller_id, t.seller_acked, t.seller_complete, t.buyer_complete, b.user_status as buyer_status,t.chat_ended, s.user_status as seller_status FROM transaction t LEFT JOIN sf_guard_user_profile s ON s.user_id = t.seller_id LEFT JOIN sf_guard_user_profile b ON b.user_id = t.buyer_id WHERE active = 1 LIMIT 1', [sellsreply], function (err, sells) {
if (sells != '') {
// attempt to stop the updates if it's not the the active transaction
client.get('active transaction id:'+sellsreply, function (err, active_transaction_id) {
passed_active_transaction_id = active_transaction_id;
});
// is there a trasnaction with status defined and transation id does not equal the active transaction id
if(sells[0].status !== undefined && sells[0].id !== passed_active_transaction_id )
{
client.get('active transaction:'+sellsreply, function (err, data1) {
if(JSON.stringify(sells) != data1){
client.set('active transaction id:'+sellsreply,sells[0]["id"]);
client.set('active transaction:'+sellsreply,JSON.stringify(sells));
console.log(JSON.stringify(sells));
updateSockets({
data: sells // pass the database result
});
}
});
}
}
});
}
// Method
function getUserInfo(user_id, callback) {
var query = connection.query('SELECT user_status from sf_guard_user_profile WHERE user_id = ' + connection.escape(user_id));
query.on('result', function (row) {
callback(null, row.user_status);
});
}
var updateSockets = function (data) {
// adding the time of the last update
data.time = new Date();
console.log('Pushing new data to the clients connected ( connections amount = %s ) - %s', connectionsArray.length , data.time);
// sending new data to all the sockets connected
connectionsArray.forEach(function (tmpSocket) {
console.log(tmpSocket);
tmpSocket.volatile.emit('notification', data);
});
};
var pollingLoop = function () {
var socket;
for (var id in sockets) {
socket = sockets[id];
client.get("uuid:" + socket.id, function (err, useridreply) {
processAllTransactions(useridreply);
});
}
connection.query('SELECT * FROM sf_guard_user_profile; select * FROM transaction', function (err, result) {
// error check
if (err) {
console.log(err);
updateSockets(err);
throw err;
} else {
// loop through the queries
var element =
// compare the cache results againt the database query for users
result[0].forEach(function (element, index, array) {
client.get('logged_in:' + element.user_id, function (err, reply) {
if (reply === null) {
// console.log( element.user_id + ' is disconnected');
}
else {
// console.log(reply);
}
});
client.get("user:" + element.user_id, function (err, userreply) {
if (element.user_status != userreply) {
client.set('user:' + element.user_id, +element.user_status);
changed_users.push(element);
console.log(element.user_id + " is now set to: " + element.user_status);
updateSockets({
changed_user_id: element.user_id,
changed_user_status: element.user_status
});
}
});
});
}
// loop on itself only if there are sockets still connected
if (connectionsArray.length) {
pollingTimer = setTimeout(pollingLoop, POLLING_INTERVAL);
// reset changed users and changed transactions arrays
changed_users = [];
changed_transactions = [];
} else {
console.log('The server timer was stopped because there are no more socket connections on the app');
}
});
};
// count the connections array
Array.prototype.contains = function (k, callback) {
var self = this;
return (function check(i) {
if (i >= self.length) {
return callback(false);
}
if (self[i] === k) {
return callback(true);
}
return process.nextTick(check.bind(null, i + 1));
}(0));
};
io.sockets.on('connection', function (socket) {
// runs for every connection
sockets[socket.id] = socket;
socket.on('client-data', function (data) {
// get the user id from the url that is passed onload
var user_id = data.url.replace('http://servernameremoved.com:4000/id/', '');
console.log('user id ' + user_id + ' is connected with session id ' + socket.id);
client.set('uuid:' + socket.id, +user_id);
});
console.log('Number of connections:' + (connectionsArray.length));
// starting the loop only if at least there is one user connected
if (!connectionsArray.length) {
pollingLoop();
}
socket.on('disconnect', function (socketIndex) {
delete sockets[socket.id];
client.get("uuid:" + socket.id, function (err, userreply) {
console.log('user id ' + userreply + ' got redis disconnected');
});
socketIndex = connectionsArray.indexOf(socket);
console.log('socketID = %s got disconnected', socketIndex);
if (~socketIndex) {
connectionsArray.splice(socketIndex, 1);
}
});
connectionsArray.push(socket);
});
// express js route
app.get('/id/:id', function (req, res) {
clients.contains(req.params.id, function (found) {
if (found) {
console.log("Found");
} else {
client.set('logged_in:' + req.params.id, +req.params.id + 'is logged in');
}
});
res.sendFile(__dirname + '/client.html');
});
// build the server
http.listen(4000, function () {
console.log("Server Started");
});
这是控制台日志结果
Pushing new data to the clients connected ( connections amount = 2 ) - Sat May 30 2015 21:16:23 GMT-0700 (PDT)
30 2015 21:15:15 GMT-0700 (PDT)
user id 3 is connected with session id CRTtkRIl7ihQ2yaEAAAA
user id 2 is connected with session id wNG7XDcEDjhYKBEIAAAB
***********************************************
[{"id":1,"status":20,"original_status":15,"active":1,"buyer_id":2,"seller_id":1,"seller_acked":1,"seller_complete":0,"buyer_complete":1,"buyer_status":4,"chat_ended":"2015-05-31T03:58:40.000Z","seller_status":4}]
***********************************************
Pushing new data to the clients connected ( connections amount = 2 ) - Sat May 30 2015 21:16:23 GMT-0700 (PDT)
***********************************************
[{"id":1,"status":20,"original_status":15,"active":1,"buyer_id":2,"seller_id":1,"seller_acked":1,"seller_complete":0,"buyer_complete":1,"buyer_status":4,"chat_ended":"2015-05-31T03:58:40.000Z","seller_status":4}]
***********************************************
Pushing new data to the clients connected ( connections amount = 2 ) - Sat May 30 2015 21:16:23 GMT-0700 (PDT)