引子:隨着nodejs蓬勃發展,雖然主要業務系統由於架構健壯性不會選擇nodejs座位應用服務器。可是大量的內部系統卻可使用nodejs試水,大量的前端開發人員轉入全堆開發也是一個因素。javascript
研究本例主要爲後期BI軟件,CRM圖標系統使用nodejs socket作鋪墊.主要實現的是一個分析表圖的推送。css
socketio.io 代碼庫以及官網html
https://github.com/socketio/socket.io前端
http://socket.io/java
使用redis來實現集羣讀寫 消息 (採用訂閱 分發的策略)node
https://github.com/socketio/socket.io-redis git
在非socket客戶行爲中發送socket事件(本例在http中調用)github
https://github.com/socketio/socket.io-emitterweb
node_redisredis
https://github.com/NodeRedis/node_redis
1.安裝和基本使用 npm install socketio.io --save
使用由於本人寫的例子是Express照搬官網說明,基本代碼結構以下
1 2 3 4 5 |
|
2.使用websocket初始化一個echart的圖片
socket.js 簡單封裝下socket.io的一些基本功能,socket.io 提供了三種默認的事件(客戶端和服務器都有):connect 、message 、disconnect 。當與對方創建鏈接後自動觸發 connect 事件,當收到對方發來的數據後觸發 message 事件(一般爲 socket.send() 觸發),當對方關閉鏈接後觸發 disconnect 事件。
除去自定義事件以外,本例中還定義了一個額外事件init chart data,用來初始化echart圖的數據。
服務端推送消息的主要方式
1.socket.emit() :向創建該鏈接的客戶端廣播
2.socket.broadcast.emit() :向除去創建該鏈接的客戶端的全部客戶端廣播
3.io.sockets.emit() :向全部客戶端廣播,等同於上面兩個的和
此處用到了socket.emit()
socket.io-redis 用來集羣推送消息,使用出版/訂閱的軟件模式,io.adapter()是設置消息緩存方式的,默認爲內存,可是集羣中內存顯然是沒法共享的,因此使用socket.io-redis用redis做爲緩存中心,注意https://github.com/socketio/socket.io-redis是基於node-redis的,socket.io-redis的說明文檔很長時間沒有更新了,若是redis有密碼一類的雁陣,必須使用
io.adapter(adapter({ pubClient: pub, subClient: sub })); 出版訂閱的緩存能夠用同一個redis服務器,redis能夠部署集羣,本例就不在這方面說明了。node-redis2.6以後密碼驗證使用password爲密碼參數,而不是官網所寫的auth_pass
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
var redis = require('redis'); var adapter = require('socket.io-redis'); var pub = redis.createClient({host:"192.168.0.13", port:"6379", password: "123456" }); var sub = redis.createClient({host:"192.168.0.13", port:"6379", password: "123456" ,return_buffers: true}); io.adapter(adapter({ pubClient: pub, subClient: sub })); //使用socket.io-adapter設置緩存依賴
1 |
|
app.js express項目主入口,建立8080端口web服務器的時候建立一個socket服務
1 2 3 4 5 6 7 8 |
|
推送入口,一個express的路由charts.js,其中2個路由,
simpleBarChart轉跳simpleBarChart頁面,由於用了handlebars的模版引擎設置layout:false來不包含layout模版片斷。
pollingChartData 爲推送socket消息請求路由,使用socket.io-emitter.js 來發送事件,注意socket.io-emitter.js也長時間沒有人維護了,修改了其中一段代碼來實現支持redis密碼驗證.
socket.io-emitter.js 59行修改以下
|
使用count基數器計數,每次推送重mockdata中取模獲得新的數據,經過emitter redis服務器,推送消息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
|
前端頁面,express引用socket.io後,自動能夠經過訪問/socket.io/socket.io.js 的前端庫,本例中接收了2種socket消息,一種剛進入頁面建立socket鏈接的時候接收的一條init chart data的消息,以及接收經過pollingChartData推送來的new chart data的消息.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
|
最後結果,經過http://localhost:8080/charts/simpleBarChart訪問得到一個簡單的echart圖表,
經過http://localhost:8080/charts/pollingChartData訪問推送新數據重繪圖表,每次發送一次請求,從新繪製一次圖片。