arrow link facebook search
2014-01-28 POSTED BY chris_lin

SOCKET SERVER – 網頁上的建置與應用 PART 2

由於上一篇寫的實在有點空泛,趁著空閒之餘趕緊再補上一篇陸續的研究與實作,此次還是專注在 node.jsphp 兩方面來介紹,廢話不多說:

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