由於上一篇寫的實在有點空泛,趁著空閒之餘趕緊再補上一篇陸續的研究與實作,此次還是專注在 node.js 跟 php 兩方面來介紹,廢話不多說:
1. node.js
首先安裝node.js再用內建的npm安裝socket.io恭喜你已經完成50%,接下來就可以專注在程式的串接溝通邏輯上了;使用node.js配合socket.io的好處在於node.js的安裝和啟動非常簡單。托socket.io的福,他讓你在寫socket時不管是client或server端的javascript都能使用近乎相同的函式來操作;此外還能自動幫你調整目前要使用websocket或輪巡等方式。以下為一簡單範例:
node.js :
var io = require(‘socket.io’).listen(socket port,socket ip);
io.sockets.on(‘connection’, function (socket) {
socket.emit(‘message’, { type: 1});
socket.on(‘message’, function (data) {
console.log(data);
});
});
client :
<script src=”/socket.io/socket.io.js”></script>
<script>
var socket = io.connect(‘http://socket ip:socket port’);
socket.on(‘connect’, function() {
socket.emit(‘message’, {state: 1,str:’hello’});
});
socket.on(‘message’, function(data) {
alert(data.type);
});
</script>
然而在實際的測試上遇到了一個比較麻煩的問題是,有些地方的電腦不允許連到有帶port的網址,若是你頁面上的網址是架在apache或iis或其他非node.js的server上,你的socket就沒辦法使用80port了。
於是我們使用了獨立的一台虛擬機器專門跑node.js的程式,由此台server專門處理socket的串接,終於可以愉快的使用socket!錯,若是你有兩個網站都要使用到socket的串接處理不同的事項呢?總不好開出許多新的80port。
目前我們嘗試使用node-http-proxy來搭配socket.io,讓此程式來做80port的偵聽再分配不同的網址到其他的port去,如此一來就可以在各自的端口分別做事;話雖如此,理論與現時總有差距,像是以下的範例仍然有個問題,當socket.io透過proxy有時client端會出現連接不上的問題,所以目前仍在尋求其它的解決方法,有新想法的讀者歡迎一起討論:
node.js :
proxyServer.js
var httpProxy = require(‘http-proxy’);
var options = {
router: {
‘socket ip/targetA/’: ‘127.0.0.1:portA’,
‘socket ip/targetB/’: ‘127.0.0.1:portB’,
}
};
var proxyServer = httpProxy.createServer(options);
proxyServer.listen(80);
socketA.js
var io = require(‘socket.io’).listen(portA,127.0.0.1);
io.sockets.on(‘connection’, function (socket) {
socket.emit(‘message’, { type: 1});
socket.on(‘message’, function (data) {
console.log(data);
});
});
socketB.js
var io = require(‘socket.io’).listen(portB,127.0.0.1);
io.sockets.on(‘connection’, function (socket) {
socket.emit(‘message’, { type: 1});
socket.on(‘message’, function (data) {
console.log(data);
});
});
client :
web A
<script src=”/socket.io/socket.io.js”></script>
<script>
var socket = io.connect(‘http://socket ip’,{
resource:’targetA/socket.io’
});
socket.on(‘connect’, function() {
socket.emit(‘message’, {state: 1,str:’hello’});
});
socket.on(‘message’, function(data) {
alert(data.type);
});
</script>
web B
<script src=”/socket.io/socket.io.js”></script>
<script>
var socket = io.connect(‘http://socket ip’,{
resource:’targetB/socket.io’
});
socket.on(‘connect’, function() {
socket.emit(‘message’, {state: 1,str:’hello’});
});
socket.on(‘message’, function(data) {
alert(data.type);
});
</script>
node.js搭配socket.io看似方便,但也不是全能工具,在查看文件的過程中會發現不少問題;例如node.js是單線程的架構,適合跑大量但處理邏輯單純,而非複雜運算的程式。此外socket.io在單線程的模式且有大量使用者的情況下是容易崩潰的,雖然網路上有配合redis使用或其他程式等解決方案;但是實作上還是須要看案子的規模跟手上擁有的資源去設定跟調整。
此為公司聖誕節專案 http://www.webgene.com.tw/xmas2013/,可以玩玩看順便幫我們衝KPI(疑?)
參考資料 :
node.js : http://nodejs.org/
socket.io : https://github.com/learnboost/socket.io/wiki
node-http-proxy : https://github.com/nodejitsu/node-http-proxy
2. PHP
php使用內建的socket function在同時大量的連線數下校能將會被拖垮,因此pecl event的出現,讓php事件處理上達到非常良好的效能,不過由於篇幅有限…請靜待下回分曉!
參考資料 :
pecl event : http://pecl.php.net/package/event