上次終於得知Long Polling之後
原本只覺得應該只是知道 短時間內沒機會用到...
結果今天
點歌系統做個小改版發現其實頗適合用的XDD
原本點歌系統點播清單那塊是隨著換曲時重載
(因為每次換曲點歌數一定會減少啊XD)
不過這樣要是別人點了歌並不會馬上更新
除非自己手動更新或換了歌才會知道
這樣不就不符合即時系統了嗎!!!!!! (請無視此人的發瘋
所以就開始準備動手修改一下
但... 很明顯的用polling絕對不是好方法(理想大概要1s的間隔吧...)
所以就來弄弄Long Polling啦
因為Long Polling會有相當數量的持續連線
當然不能用PHP寫啦~~~ (其實用PHP寫daemon應該可行?)
這回用的是node.js 順便來玩玩這用JS來寫Server XDD
(題外話... 原本想要裝forever來跑這server 不過好像npm registry被衝爆了...)
因為需求上是點歌系統點的一首歌後送出訊息要求客戶端更新
設計上只要一個簡單的訊息交換就夠了
所以這js還頗小的www
server.js
// http
var http = require("http"),
url = require("url");
http.globalAgent.maxSockets = 200;
var pendingRequests = [];
// 客戶端連線時讓連線進入等待狀態
function processPendingRequest(request, response) {
// 連線被強制關閉時移除
response.on('close', function() {
clearTimeout(this.timeout);
var id = pendingRequests.indexOf(this);
if (id != -1) pendingRequests.splice(id, 1);
});
// force reconnect
response.timeout = setTimeout(function (){
response.writeHead(200, { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' });
response.write(JSON.stringify({ "message": "" }));
response.end();
var id = pendingRequests.indexOf(response);
if (id != -1) pendingRequests.splice(id, 1);
}, 30000);
pendingRequests.push(response);
}
// 送出訊息時針對所有等待中連線送出訊息
function processSendingRequest(request, response) {
var u = url.parse(request.url, true);
var msg = u.query.msg, dat = u.query.dat;
while (pendingRequests.length > 0) {
var element = pendingRequests.shift();
clearTimeout(element.timeout);
element.writeHead(200, { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' });
element.write(JSON.stringify({ "message": msg, "data": dat }));
element.end();
}
response.writeHead(200, { 'Content-Type': 'application/json' });
response.write("{\"result\":\"complete\"}");
response.end();
}
// 建立HTTP伺服器
http.createServer(function(request, response) {
var u = url.parse(request.url, true);
if (/* 此處為訊息傳送端驗證 */) processSendingRequest(request, response);
else processPendingRequest(request, response);
}).listen(13453);
沒有寫的很複雜
整體就很簡單的訊息交換而已
而點歌頁面也做了對應的調整
function polling_call() {
$.ajax({
cache: false,
dataType: 'json',
type: "GET",
crossDomain: true,
url: "http://live.sbsstudio.twbbs.org:13453/",
error: function () {
setTimeout(polling_call, 15000);
},
success: function (p) {
switch (p.message) {
case "NeedUpdateRequireList":
requestlist_call();
break;
}
polling_call();
}
});
}
Long Polling的客戶端總是很簡單XD
只需要反覆的ajax請求就好
要是伺服器端沒有支援的話,這可是比Polling還糟糕啊XDD
最後後台點歌的PHP檔只需要在點歌成功後外加一個CURL請求就好
就沒多放程式碼啦~~~
這永遠BETA的點歌系統又往正式版前進一步了~~~
(這句話矛盾的很嚴重啊XDD