使用Node.js+Socket.IO搭建WebSocket实时应用
Web領(lǐng)域的實(shí)時(shí)推送技術(shù),也被稱(chēng)作Realtime技術(shù)。這種技術(shù)要達(dá)到的目的是讓用戶(hù)不需要刷新瀏覽器就可以獲得實(shí)時(shí)更新。它有著廣泛的應(yīng)用場(chǎng)景,比如在線(xiàn)聊天室、在線(xiàn)客服系統(tǒng)、評(píng)論系統(tǒng)、WebIM等。
作者:潘良虎鏈接:https://www.zhihu.com/question/20215561/answer/26419995
來(lái)源:知乎
原文地址:http://www.plhwin.com/2014/05/28/nodejs-socketio/
WebSocket簡(jiǎn)介
談到Web實(shí)時(shí)推送,就不得不說(shuō)WebSocket。在WebSocket出現(xiàn)之前,很多網(wǎng)站為了實(shí)現(xiàn)實(shí)時(shí)推送技術(shù),通常采用的方案是輪詢(xún)(Polling)和Comet技術(shù),Comet又可細(xì)分為兩種實(shí)現(xiàn)方式,一種是長(zhǎng)輪詢(xún)機(jī)制,一種稱(chēng)為流技術(shù),這兩種方式實(shí)際上是對(duì)輪詢(xún)技術(shù)的改進(jìn),這些方案帶來(lái)很明顯的缺點(diǎn),需要由瀏覽器對(duì)服務(wù)器發(fā)出HTTP request,大量消耗服務(wù)器帶寬和資源。面對(duì)這種狀況,HTML5定義了WebSocket協(xié)議,能更好的節(jié)省服務(wù)器資源和帶寬并實(shí)現(xiàn)真正意義上的實(shí)時(shí)推送。
WebSocket協(xié)議本質(zhì)上是一個(gè)基于TCP的協(xié)議,它由通信協(xié)議和編程API組成,WebSocket能夠在瀏覽器和服務(wù)器之間建立雙向連接,以基于事件的方式,賦予瀏覽器實(shí)時(shí)通信能力。既然是雙向通信,就意味著服務(wù)器端和客戶(hù)端可以同時(shí)發(fā)送并響應(yīng)請(qǐng)求,而不再像HTTP的請(qǐng)求和響應(yīng)。
為了建立一個(gè)WebSocket連接,客戶(hù)端瀏覽器首先要向服務(wù)器發(fā)起一個(gè)HTTP請(qǐng)求,這個(gè)請(qǐng)求和通常的HTTP請(qǐng)求不同,包含了一些附加頭信息,其中附加頭信息”Upgrade: WebSocket”表明這是一個(gè)申請(qǐng)協(xié)議升級(jí)的HTTP請(qǐng)求,服務(wù)器端解析這些附加的頭信息然后產(chǎn)生應(yīng)答信息返回給客戶(hù)端,客戶(hù)端和服務(wù)器端的WebSocket連接就建立起來(lái)了,雙方就可以通過(guò)這個(gè)連接通道自由的傳遞信息,并且這個(gè)連接會(huì)持續(xù)存在直到客戶(hù)端或者服務(wù)器端的某一方主動(dòng)的關(guān)閉連接。
作者:潘良虎鏈接:https://www.zhihu.com/question/20215561/answer/26419995
來(lái)源:知乎
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。
前面講到WebSocket是HTML5中新增的一種通信協(xié)議,這意味著一部分老版本瀏覽器(主要是IE10以下版本)并不具備這個(gè)功能, 通過(guò)百度統(tǒng)計(jì)的公開(kāi)數(shù)據(jù)顯示,IE8目前仍以33%的市場(chǎng)份額占據(jù)榜首,好在chrome瀏覽器市場(chǎng)份額逐年上升,現(xiàn)在以超過(guò)26%的市場(chǎng)份額位居第二,同時(shí)微軟前不久宣布停止對(duì)IE6的技術(shù)支持并提示用戶(hù)更新到新版本瀏覽器,這個(gè)曾經(jīng)讓無(wú)數(shù)前端工程師為之頭疼的瀏覽器有望退出歷史舞臺(tái),再加上幾乎所有的智能手機(jī)瀏覽器都支持HTML5,所以使得WebSocket的實(shí)戰(zhàn)意義大增,但是無(wú)論如何,我們實(shí)際的項(xiàng)目中,仍然要考慮低版本瀏覽器的兼容方案:在支持WebSocket的瀏覽器中采用新技術(shù),而在不支持WebSocket的瀏覽器里啟用Comet來(lái)接收發(fā)送消息。
WebSocket實(shí)戰(zhàn)
本文將以多人在線(xiàn)聊天應(yīng)用作為實(shí)例場(chǎng)景,我們先來(lái)確定這個(gè)聊天應(yīng)用的基本需求。
需求分析
1、兼容不支持WebSocket的低版本瀏覽器。
2、允許客戶(hù)端有相同的用戶(hù)名。
3、進(jìn)入聊天室后可以看到當(dāng)前在線(xiàn)的用戶(hù)和在線(xiàn)人數(shù)。
4、用戶(hù)上線(xiàn)或退出,所有在線(xiàn)的客戶(hù)端應(yīng)該實(shí)時(shí)更新。
5、用戶(hù)發(fā)送消息,所有客戶(hù)端實(shí)時(shí)收取。
在實(shí)際的開(kāi)發(fā)過(guò)程中,為了使用WebSocket接口構(gòu)建Web應(yīng)用,我們首先需要構(gòu)建一個(gè)實(shí)現(xiàn)了 WebSocket規(guī)范的服務(wù)端,服務(wù)端的實(shí)現(xiàn)不受平臺(tái)和開(kāi)發(fā)語(yǔ)言的限制,只需要遵從WebSocket規(guī)范即可,目前已經(jīng)出現(xiàn)了一些比較成熟的WebSocket服務(wù)端實(shí)現(xiàn),比如本文使用的Node.js+http://Socket.IO。為什么選用這個(gè)方案呢?先來(lái)簡(jiǎn)單介紹下他們兩。
Node.js
Node.js采用C++語(yǔ)言編寫(xiě)而成,它不是Javascript應(yīng)用,而是一個(gè)Javascript的運(yùn)行環(huán)境,據(jù)Node.js創(chuàng)始人Ryan Dahl回憶,他最初希望采用Ruby來(lái)寫(xiě)Node.js,但是后來(lái)發(fā)現(xiàn)Ruby虛擬機(jī)的性能不能滿(mǎn)足他的要求,后來(lái)他嘗試采用V8引擎,所以選擇了C++語(yǔ)言。
Node.js支持的系統(tǒng)包括*nux、Windows,這意味著程序員可以編寫(xiě)系統(tǒng)級(jí)或者服務(wù)器端的Javascript代碼,交給Node.js來(lái)解釋執(zhí)行。Node.js的Web開(kāi)發(fā)框架Express,可以幫助程序員快速建立web站點(diǎn),從2009年誕生至今,Node.js的成長(zhǎng)的速度有目共睹,其發(fā)展前景獲得了技術(shù)社區(qū)的充分肯定。
http://Socket.IO
http://Socket.IO是一個(gè)開(kāi)源的WebSocket庫(kù),它通過(guò)Node.js實(shí)現(xiàn)WebSocket服務(wù)端,同時(shí)也提供客戶(hù)端JS庫(kù)。http://Socket.IO支持以事件為基礎(chǔ)的實(shí)時(shí)雙向通訊,它可以工作在任何平臺(tái)、瀏覽器或移動(dòng)設(shè)備。
http://Socket.IO支持4種協(xié)議:WebSocket、htmlfile、xhr-polling、jsonp-polling,它會(huì)自動(dòng)根據(jù)瀏覽器選擇適合的通訊方式,從而讓開(kāi)發(fā)者可以聚焦到功能的實(shí)現(xiàn)而不是平臺(tái)的兼容性,同時(shí)http://Socket.IO具有不錯(cuò)的穩(wěn)定性和性能。
編碼實(shí)現(xiàn)
本文一開(kāi)始的的插圖就是效果演示圖:可以點(diǎn)擊這里查看在線(xiàn)演示,整個(gè)開(kāi)發(fā)過(guò)程非常簡(jiǎn)單,下面簡(jiǎn)單記錄了開(kāi)發(fā)步驟:
作者:潘良虎鏈接:https://www.zhihu.com/question/20215561/answer/26419995
來(lái)源:知乎
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。
安裝Node.js
根據(jù)自己的操作系統(tǒng),去Node.js官網(wǎng)下載安裝即可。如果成功安裝。在命令行輸入node -v和npm -v應(yīng)該能看到相應(yīng)的版本號(hào)。
<img src="https://pic4.zhimg.com/9bae01a50a77c4f238d7afe632873343_b.jpg" data-rawwidth="278" data-rawheight="79" class="content_image" width="278">搭建WebSocket服務(wù)端
這個(gè)環(huán)節(jié)我們盡可能的考慮真實(shí)生產(chǎn)環(huán)境,把WebSocket后端服務(wù)搭建成一個(gè)線(xiàn)上可以用域名訪(fǎng)問(wèn)的服務(wù),如果你是在本地開(kāi)發(fā)環(huán)境,可以換成本地ip地址,或者使用一個(gè)虛擬域名指向本地ip。
先進(jìn)入到你的工作目錄,比如 /workspace/wwwroot/plhwin/http://realtime.plhwin.com,新建一個(gè)名為package.json的文件,內(nèi)容如下:
<img src="https://pic1.zhimg.com/3d487b79444ca0d1e69004ba8aa1ac54_b.jpg" data-rawwidth="372" data-rawheight="105" class="content_image" width="372">接下來(lái)使用npm命令安裝express和http://socket.io
<img src="https://pic1.zhimg.com/e2177bce610448a115a9716219448878_b.jpg" data-rawwidth="268" data-rawheight="45" class="content_image" width="268">安裝成功后,應(yīng)該可以看到工作目錄下生成了一個(gè)名為node_modules的文件夾,里面分別是express和http://socket.io,接下來(lái)可以開(kāi)始編寫(xiě)服務(wù)端的代碼了,新建一個(gè)文件:index.js
<img src="https://pic1.zhimg.com/e636acfe7577ee8511dc4840cdd92198_b.jpg" data-rawwidth="437" data-rawheight="180" class="origin_image zh-lightbox-thumb" width="437" data-original="https://pic1.zhimg.com/e636acfe7577ee8511dc4840cdd92198_r.jpg">命令行運(yùn)行node index.js,如果一切順利,你應(yīng)該會(huì)看到返回的listening on *:3000字樣,這說(shuō)明服務(wù)已經(jīng)成功搭建了。此時(shí)瀏覽器中打開(kāi) http://localhost:3000 應(yīng)該可以看到正常的歡迎頁(yè)面。
如果你想要讓服務(wù)運(yùn)行在線(xiàn)上服務(wù)器,并且可以通過(guò)域名訪(fǎng)問(wèn)的話(huà),可以使用Nginx做代理,在nginx.conf中添加如下配置,然后將域名(比如:http://realtime.plhwin.com)解析到服務(wù)器IP即可。
<img src="https://pic3.zhimg.com/f3614ed8bd74aa69f74f10aa7a52f2c2_b.jpg" data-rawwidth="326" data-rawheight="131" class="content_image" width="326">完成以上步驟,http://realtime.plhwin.com:3000的后端服務(wù)就正常搭建了。
<img src="https://pic1.zhimg.com/3defa7f8c03ac8a9edcd56ec9faac8d0_b.jpg" data-rawwidth="424" data-rawheight="114" class="origin_image zh-lightbox-thumb" width="424" data-original="https://pic1.zhimg.com/3defa7f8c03ac8a9edcd56ec9faac8d0_r.jpg">服務(wù)端代碼實(shí)現(xiàn)
前面講到的index.js運(yùn)行在服務(wù)端,之前的代碼只是一個(gè)簡(jiǎn)單的WebServer歡迎內(nèi)容,讓我們把WebSocket服務(wù)端完整的實(shí)現(xiàn)代碼加入進(jìn)去,整個(gè)服務(wù)端就可以處理客戶(hù)端的請(qǐng)求了。完整的index.js代碼如下:
<img src="https://pic3.zhimg.com/9f83d36396cf25fc5c26c28e48027482_b.jpg" data-rawwidth="785" data-rawheight="901" class="origin_image zh-lightbox-thumb" width="785" data-original="https://pic3.zhimg.com/9f83d36396cf25fc5c26c28e48027482_r.jpg">客戶(hù)端代碼實(shí)現(xiàn)
進(jìn)入客戶(hù)端工作目錄/workspace/wwwroot/plhwin/http://demo.plhwin.com/chat,新建一個(gè)index.html:
<img src="https://pic2.zhimg.com/443f426e187102685e738c18e127b879_b.jpg" data-rawwidth="930" data-rawheight="719" class="origin_image zh-lightbox-thumb" width="930" data-original="https://pic2.zhimg.com/443f426e187102685e738c18e127b879_r.jpg">上面的html內(nèi)容本身沒(méi)有什么好說(shuō)的,我們主要看看里面的4個(gè)文件請(qǐng)求:
1、http://realtime.plhwin.com:3000/socket.io/socket.io.js
2、style.css
3、json3.min.js
4、client.js
第1個(gè)JS是http://Socket.IO提供的客戶(hù)端JS文件,在前面安裝服務(wù)端的步驟中,當(dāng)npm安裝完http://socket.io并搭建起WebServer后,這個(gè)JS文件就可以正常訪(fǎng)問(wèn)了。
第2個(gè)style.css文件沒(méi)什么好說(shuō)的,就是樣式文件而已。
第3個(gè)JS只在IE8以下版本的IE瀏覽器中加載,目的是讓這些低版本的IE瀏覽器也能處理json,這是一個(gè)開(kāi)源的JS,詳見(jiàn):JSON 3
第4個(gè)client.js是完整的客戶(hù)端的業(yè)務(wù)邏輯實(shí)現(xiàn)代碼,它的內(nèi)容如下:
<img src="https://pic1.zhimg.com/a1589ae83cf934578d4b1832cabe9c44_b.jpg" data-rawwidth="929" data-rawheight="2094" class="origin_image zh-lightbox-thumb" width="929" data-original="https://pic1.zhimg.com/a1589ae83cf934578d4b1832cabe9c44_r.jpg">至此所有的編碼開(kāi)發(fā)工作全部完成了,在瀏覽器中打開(kāi) http://demo.plhwin.com/chat/ 就可以看到效果了。
上面所有的客戶(hù)端和服務(wù)端的代碼可以從Github上獲得,地址:https://github.com/plhwin/nodejs-socketio-chat
<img src="https://pic2.zhimg.com/6841cebd770b3ec0cc850356eff9d185_b.jpg" data-rawwidth="620" data-rawheight="45" class="origin_image zh-lightbox-thumb" width="620" data-original="https://pic2.zhimg.com/6841cebd770b3ec0cc850356eff9d185_r.jpg">
下載本地后有兩個(gè)文件夾 client 和 server,client文件夾是客戶(hù)端源碼,可以放在Nginx/Apache的WebServer中,也可以放在Node.js的WebServer中。后面的server文件夾里的代碼是websocket服務(wù)端代碼,放在Node.js環(huán)境中,使用npm安裝完 express 和 http://socket.io 后,node index.js 啟動(dòng)后端服務(wù)就可以了。
留給我們的思考
1、假設(shè)是一個(gè)在線(xiàn)客服系統(tǒng),里面有許多的公司使用你的服務(wù),每個(gè)公司自己的用戶(hù)可以通過(guò)一個(gè)專(zhuān)屬URL地址進(jìn)入該公司的聊天室,聊天是一對(duì)一的,每個(gè)公司可以新建多個(gè)客服人員,每個(gè)客服人員可以同時(shí)和客戶(hù)端的多個(gè)用戶(hù)聊天。
2、又假設(shè)是一個(gè)在線(xiàn)WebIM系統(tǒng),實(shí)現(xiàn)類(lèi)似微信,qq的功能,客戶(hù)端可以看到好友在線(xiàn)狀態(tài),在線(xiàn)列表,添加好友,刪除好友,新建群組等,消息的發(fā)送除了支持基本的文字外,還能支持表情、圖片和文件。
有興趣的同學(xué)可以繼續(xù)深入研究。
--------------------------
上面是我前段時(shí)間寫(xiě)的一篇與WebSocket這個(gè)主題相關(guān)的文檔,就直接貼過(guò)來(lái)了,原文請(qǐng)見(jiàn):使用Node.js+Socket.IO搭建WebSocket實(shí)時(shí)應(yīng)用
轉(zhuǎn)載于:https://www.cnblogs.com/ameile/p/6692263.html
總結(jié)
以上是生活随笔為你收集整理的使用Node.js+Socket.IO搭建WebSocket实时应用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 八大排序算法的java实现
- 下一篇: shinhan是什么银行