下面我們要做的就是把MySQL這邊一張表數據的更新實時的推送到客戶端,比如MySQL這邊表的數據abc變成123了,那使用程序就會把最新的123推送到每一個連接到服務器的客戶端。如果服務器的連接的客戶端為0,也就是這時候沒有客戶端連接,那程序也不會執行推送信息的代碼以免產生不必要的資源消耗,當有客戶端連上的時候又開始推送。demo的代碼大家可以到下面的Download按鈕去下載。
要運行首先我們要安裝nodejs要用到的mysql模塊:
$ npm install mysql
更多關於mysql模塊的使用請訪問:https://github.com/felixge/node-mysql
再安裝Socket.io模塊:
$ npm install socket.io
更多關於socket.io模塊的使用請訪問:http://socket.io/
新建數據庫nodejs,表articles(也可以把表建在你現有的的數據庫上,修改一下相應的源代碼):
CREATE DATABASE `nodejs`CHARACTER SET utf8 ; USE `nodejs`; SHOW DATABASES; USE `nodejs`; CREATE TABLE `nodejs`.`articles`(`title` TEXT , `author` TEXT ,`description` TEXT);
進入nodejs-push-MySQL目錄運行demo:
$ node server.js
測試效果:
- 打開瀏覽器輸入http://localhost:8080 (可以多開幾個,明顯能感覺到實時的推送效果)
- 使用MySQL工具登錄到MySQL數據庫,修改數據庫nodejs里面articles表的數據
- 一旦表數據被保存,那些打開的客戶端將收到最新的更改
- client.html源代碼:
<html>
<head>
<title>使用Nodejs實現實時推送MySQL數據庫最新信息到客戶端</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>
// 創建websocket連接
var socket = io.connect('http://localhost:8080');
// 把信息顯示到div上
socket.on('notification', function (data) {
var articlesList = "<dl>";
$.each(data.articles,function(index,article){
articlesList += "<dt>" + article.title + "</dt>\n" +
"<dd>" + article.author + "\n" +
"<dd>" + article.description + "\n"
"</dd>";
});
articlesList += "</dl>";
$('#container').html(articlesList);
$('time').html('最后更新時間:' + data.time);
});
</script>
</body>
</html>
//建立MySQL連接, 根據自己環境修改相應的數據庫信息
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: 'root',
database: 'nodejs',
port: 3306
}),
POLLING_INTERVAL = 1000,
pollingTimer;
// 檢查數據庫連接是否正常
connection.connect(function(err) {
// 不出現錯誤信息,那表示數據庫連接成功
console.log(err);
});
//啟動HTTP服務,綁定端口8080
app.listen(8080);
// 加載客戶端首頁
function handler(req, res) {
fs.readFile(__dirname + '/client.html', function(err, data) {
if (err) {
console.log(err);
res.writeHead(500);
return res.end('加載客戶端首頁發生錯誤...');
}
res.writeHead(200);
res.end(data);
});
}
/*
* 這個就是實現主要功能的方法,間隔3秒去查詢數據庫表,有更新就推送給客戶端
*/
var pollingLoop = function() {
// 查詢數據庫
var query = connection.query('SELECT * FROM articles'),
articles = []; // 用於保存查詢結果
// 查詢結果監聽
query
.on('error', function(err) {
// 查詢出錯處理
console.log(err);
updateSockets(err);
})
.on('result', function(user) {
// 加入查詢到的結果到articles數組
articles.push(user);
})
.on('end', function() {
// 檢查是否有客戶端連接,有連接就繼續查詢數據庫
if (connectionsArray.length) {
pollingTimer = setTimeout(pollingLoop, POLLING_INTERVAL);
updateSockets({
articles: articles
});
}
});
};
// 創建一個websocket連接,實時更新數據
io.sockets.on('connection', function(socket) {
console.log('當前連接客戶端數量:' + connectionsArray.length);
// 有客戶端連接的時候才去查詢,不然都是浪費資源
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('有新的客戶端連接!');
connectionsArray.push(socket);
});
var updateSockets = function(data) {
// 加上最新的更新時間
data.time = new Date();
// 推送最新的更新信息到所以連接到服務器的客戶端
connectionsArray.forEach(function(tmpSocket) {
tmpSocket.volatile.emit('notification', data);
});
};
