Implementacja socket.io, którą zrobiłem, jest nieprawidłowa. Próbuję wprowadzić długi polling na danych mysql.Serwer nodejs- socket.io przesyła te same dane wszystkim użytkownikom.
W tym wydaniu pobieram dane użytkownika dla każdego użytkownika podłączonego do utworzonego przez siebie serwera z długim pollingiem. Każdy użytkownik przekaże swój unikalny identyfikator użytkownika do serwera w celu pobrania danych, które go dotyczą. (W prawdziwej aplikacji chcę otrzymywać powiadomienia użytkowników)
Użytkownicy łączą się z serwerem, a serwer wykonuje również długie polling z DB. Problem polega jednak na tym, że te same dane są przesyłane do klienta, mimo że przekazuję unikalne identyfikatory od strony klienta.
Użytkownik 1 przeszedł ID 5 i użytkownik 2 przechodzi id 3. Obie te użytkownicy otrzymują te same dane jak odpowiedzi (1 użytkownika na dane)
oto klient kodu po stronie:
var user_id = 5; //hardcoded for now, but in real its fetched from a form
var params = {
userId: user_id,
};
// create a new websocket
var socket = io.connect('http://localhost:8000', { query: params });
// on message received we print all the data inside the #container div
socket.on('notification', function (data) {
console.log(data);
});
Tu jest kod po stronie serwera:
var app = require('http').createServer(handler),
io = require('socket.io').listen(app),
fs = require('fs'),
mysql = require('mysql'),
connectionsArray = [],
connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: '',
database: 'dumydb',
port: 3306
}),
POLLING_INTERVAL = 5000,
pollingTimer;
// If there is an error connecting to the database
connection.connect(function (err) {
// connected! (unless `err` is set)
if (err) {
console.log(err);
}
});
// creating the server (localhost:8000)
app.listen(8000);
// on server started we can load our client.html page
function handler(req, res) {
fs.readFile(__dirname + '/client.html', function (err, data) {
if (err) {
console.log(err);
res.writeHead(500);
return res.end('Error loading client.html');
}
res.writeHead(200);
res.end(data);
});
}
// creating a new websocket to keep the content updated without any AJAX request
io.sockets.on('connection', function (socket) {
var userId = socket.handshake.query.userId;
// starting the loop only if at least there is one user connected
if (!connectionsArray.length) {
pollingLoop(userId);
}
socket.on('disconnect', function() {
var socketIndex = connectionsArray.indexOf(socket);
console.log('socketID = %s got disconnected', socketIndex);
if (~socketIndex) {
connectionsArray.splice(socketIndex, 1);
}
});
console.log('A new socket is connected!');
connectionsArray.push(socket);
});
var pollingLoop = function (userId) {
var params = [userId];
// Doing the database query
var tempQuery = `SELECT full_name FROM users WHERE id=?`;
var query = connection.query(tempQuery, params),
users = []; // this array will contain the result of our db query
// setting the query listeners
query
.on('error', function (err) {
// Handle error, and 'end' event will be emitted after this as well
updateSockets(err);
})
.on('result', function (user) {
// it fills our array looping on each user row inside the db
users.push(user);
})
.on('end', function() {
// loop on itself only if there are sockets still connected
if (connectionsArray.length) {
pollingTimer = setTimeout(function() { pollingLoop(userId) }, POLLING_INTERVAL);
updateSockets({
users: users
});
} else {
console.log('The server timer was stopped because there are no more socket connections on the app')
}
});
};
var updateSockets = function (data) {
// adding the time of the last update
data.time = new Date();
// sending new data to all the sockets connected
connectionsArray.forEach(function (tmpSocket) {
tmpSocket.volatile.emit('notification', data);
});
};
console.log('Please use your browser to navigate to http://localhost:8000');
jest to poradnik Obserwuję: Link
Czy ktoś może mi pomóc dowiedzieć się, dlaczego te same dane są przesyłane do wszystkich użytkowników? Dzięki!
UPDATE 1
Próbowałem rozwiązania przewidziane przez Theo i Abdul Rab Memon zmieniłem updateSockets(), ale teraz dane jest wciśnięty tylko do pierwszego klienta podłączonego. Zrobiłem console.log() spojrzeć na to:
UPDATE 2:package.json
{
"name": "nodejs-MySQL-push-notifications-demo",
"version": "1.0.0",
"description": "nodejs-MySQL-push-notifications-demo",
"main": "server.js",
"dependencies": {
"express": "^4.16.2",
"mysql": "~2.5.4",
"socket.io": "~1.3.2"
},
"devDependencies": {},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node server.js"
},
"repository": {
"type": "git",
"url": "git://github.com/GianlucaGuarini/nodejs-MySQL-push-notifications-demo.git"
},
"author": "Gianluca Guarini",
"license": "BSD-2-Clause",
"bugs": {
"url": "https://github.com/GianlucaGuarini/nodejs-MySQL-push-notifications-demo/issues"
},
"homepage": "https://github.com/GianlucaGuarini/nodejs-MySQL-push-notifications-demo"
}
Funkcja updateSockets emituje zdarzenie powiadomienia o wszystkich gniazdach, więc te same dane są przesyłane do wszystkich użytkowników. –
, więc co powinienem tam zmienić? Jestem całkiem nowy w tych rzeczach. @ Cr. 25 – Annabelle
@AnnaBelle, czy możesz dostarczyć repozytorium git do debugowania? Ponieważ najlepiej jest używać dokładnie tych pakietów, z których korzystasz. –