2014-10-23 1 views
5

Sono completamente nuovo a Nodejs e sto provando a familiarizzarmi con esso. Bene, al momento, sto tentando di inviare notifiche sul browser web se si verificano cambiamenti nel database. Ho un pezzo di codice che ho usato per testare prima. A seguito di codice funziona bene per inviare gli aggiornamenti al browser quando il contenuto delle tabelle del database cambiano:Ascolto su URL specifici anziché sulla porta

Server.js

var app = require('http').createServer(handler).listen(8000), 
    io = require('socket.io').listen(app), 
    fs = require('fs'), 
    mysql = require('mysql'), 
    connectionsArray = [], 
    connection = mysql.createConnection({ 
    host: 'localhost', 
    user: 'root', 
    password: '', 
    database: 'nodejs', 
    port: 3306 
    }), 
    POLLING_INTERVAL = 3000, 
    pollingTimer, 
    pollingTimer_2; 


// If there is an error connecting to the database 
connection.connect(function(err) { 
    // connected! (unless `err` is set) 
    console.log(err); 
}); 


// 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); 
    }); 
} 




/* 
* This function loops on itself since there are sockets connected to the page 
* sending the result of the database query after a constant interval 
* 
*/ 

var pollingLoop = function() { 

    // Doing the database query 
    var query = connection.query('SELECT * FROM users'), 
    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 
     console.log(err); 
     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(pollingLoop, POLLING_INTERVAL); 

     updateSockets({ 
      users: users 
     }); 
     } 
    }); 

}; 


// creating a new websocket to keep the content updated without any AJAX request 
io.sockets.on('connection', function(socket) { 

    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() { 
    var socketIndex = connectionsArray.indexOf(socket); 
    console.log('socket = ' + socketIndex + ' disconnected'); 
    if (socketIndex >= 0) { 
     connectionsArray.splice(socketIndex, 1); 
    } 
    }); 

    console.log('A new socket is connected!'); 
    connectionsArray.push(socket); 

}); 

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); 
    }); 
}; 

Client.html

<html> 
    <head> 

     <title>Push notification server streaming on a MySQL db</title> 
     <style> 
      dd,dt { 
       float:left; 
       margin:0; 
       padding:5px; 
       clear:both; 
       display:block; 
       width:100%; 

      } 
      dt { 
       background:#ddd; 
      } 
      time { 
       color:gray; 
      } 
     </style> 
    </head> 
    <body> 
     <time></time> 
     <div id="container">Loading ...</div> 
    <script src="socket.io/socket.io.js"></script> 
    <script src="http://code.jquery.com/jquery-latest.min.js"></script> 
    <script> 

     // create a new websocket 
     var socket = io.connect('http://localhost:8000'); 
     // on message received we print all the data inside the #container div 
     socket.on('notification', function (data) { 
     var usersList = "<dl>"; 
     $.each(data.users,function(index,user){ 
      usersList += "<dt>" + user.user_name + "</dt>\n" + 
         "<dd>" + user.user_desc + "\n" + 
          "<figure> <img class='img-polaroid' width='50px' src='" + user.user_img + "' /></figure>" 
         "</dd>"; 
     }); 
     usersList += "</dl>"; 
     $('#container').html(usersList); 

     $('time').html('Last Update:' + data.time); 
     }); 
    </script> 
    </body> 
</html> 

Ora, come si può vedere che attualmente il server è in ascolto allo port 8000. Mi chiedo solo come posso cambiarlo per ascoltare un URL specifico? Perché se ho intenzione di implementare sul progetto server, non userò l'url per l'ascolto sulle porte? Piuttosto, voglio usarlo come semplice URL in quanto posso inviare senza problemi notifiche se qualche utente è connesso a un URL specifico?

Qualsiasi aiuto?

+2

Gli utenti non ascoltano gli URL. Ascoltano su una data porta per un dato indirizzo IP. Non puoi cambiarlo. Se vuoi dire che non vuoi inserire il numero di porta nell'URL, allora vuoi che il tuo server ascolti sulla porta 80 (la porta http predefinita). La connessione non è fatta per un URL. È fatto per una data porta su un determinato server e quindi il percorso dell'URL viene passato come dati dopo la connessione. – jfriend00

+0

Non capisco come mi piacerebbe applicare le notifiche push su url specifici? Diciamo che ho il seguente link in cui l'utente è il log in 'http: // www.example.com/updates'. Ora, come posso inviare gli aggiornamenti su questo link se si verificano cambiamenti nel database? con lo scenario attuale sarebbe come questo: 'http: //www.example.com: 8000/updates'. – Princess

+0

Fai in modo che il tuo server ascolti sulla porta 80 e fai in modo che il tuo server di nodo risponda al percorso '/ updates'. È così che ti colleghi a "http: // www.example.com/updates". Se nessun numero di porta è nell'URL e il protocollo è 'http', la porta passa automaticamente alla porta 80. – jfriend00

risposta

4

Se si desidera che il server di nodi risponda all'URL http://www.example.com/updates, il server deve essere in attesa sulla porta 80 (la porta predefinita se nessuna porta è elencata e il protocollo è "http"). E poi fai in modo che il tuo server risponda alla route "/updates".

I server sono in attesa su una porta specifica a uno specifico indirizzo IP. Non ascoltano un percorso o un URL. Il browser utilizza il DNS per ottenere un indirizzo IP per l'host nell'URL. Se c'è un numero di porta nell'URL, usa quella porta. In caso contrario, utilizza la porta predefinita per il protocollo specifico. Quindi effettua una connessione TCP a quell'indirizzo IP su quella porta. Quindi, se il protocollo è http, invia una richiesta su quella connessione e include il percorso.

Quindi, il server riceve la connessione in ingresso e quindi come parte del protocollo HTTP, riceve il verbo (GET, POST, DELETE, ecc.) E il percorso che è quindi il lavoro dei server per decidere cosa fare in base al comando/percorso in entrata.

+0

beh, ho provato a modo tuo, ma appare su 'EADDRINUSE'. È perché il mio apachi è anche in esecuzione sulla stessa porta. Pertanto, mi chiedo solo come evitare questo? – Princess

+2

Il modo corretto sarebbe ovviamente quello di utilizzare porte diverse. Ma ho avuto fortuna ad usare l'indirizzo IP di loopback localhost differente (127.0.0.5) con express ('express(). Listen (80, '127.0.0.5')') invece di http. – laggingreflex

+1

@Principessa: può esistere un solo listener per porta per un dato indirizzo IP.È necessario utilizzare un indirizzo IP diverso (che di solito significa un server diverso, eccetto quando le connessioni multi-rete su una scatola) o una porta diversa o combinare le funzioni dei server Express e Apache in un unico server. – jfriend00