原本只覺得應該只是知道 短時間內沒機會用到...
結果今天點歌系統做個小改版發現其實頗適合用的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