用Pomelo 搭建一個簡易的推送平台


實際上,個人感覺,pomelo 目前提供的兩個默認sioconnectorhybridconnector 使用的協議並不適合用於做手機推送平台,在pomelo的一份公開ppt里面,有提到過, 網易的消息推送平台是基於pomelo開發的 (一個frontend 支持30w 長連接,消耗了3g 內存,如果我沒記錯數據應該是這樣),不過,這里用的前端(frontend)實現的是基於MQTT協議,我估計這個基於MQTT協議實現的frontend,基本不可能開源出來.這里只是說,默認提供的frontend不適合用於構建大型的推送平台(c10m規模的),一般而言(c10k級別的),個人感覺還是夠用的.

為了展示,更多pomelo 的相關特性,可能這里的邏輯業務,與實際有所不同.敬請注意

整個應用的架構圖:

Pushapp

  • pomelo@0.4.3
  • android
  • web browser

 

1
2
3
4
5
{
    "role": "client/server",
    "apikey": "String",
    "clientId": "String"
}

 

發給web management

 

1
2
3
4
5
{
    "code": "Int httpCode ex: 200",
    "msg": "String",
    "users": "Array 客戶端的clientId 值 ex:["android1"] "
}

發給android客戶端

 

 

1
2
3
4
{
    "code": "Int httpCode ex: 200",
    "msg": "String"
}

 

android:

connector route = sio-connector.entryHandler.enter, 用於把當前客戶端加入到推送頻道當中

WebManagement:

connector route = hybrid-connector.entryHandler.enter,用於連接服務器.
backend route = pushserver.pushHandler.pushAll, 把消息推送到所有已連接的客戶端.

Pomelo 有個特點,就是約定開發,很多地方是約定好的配置,優點是,架構清晰,可讀性好,缺點是,需要大量的文檔支持,目前而言,pomelo的官方文檔做的不好的地方就是,雖然文檔都有了,但是太零散了,分類不清楚,還有就是文檔沒跟上開發,有時候,你不閱讀里面源碼根本不知道這個api要傳那些參數.

由於pomelo 0.3 以后新增了一個新的connector:hybridconnector,支持socket和websocket,使用二進制通訊協議,但是除了,網頁js版本和c 客戶端實現了這個connector,其他客戶端均還沒實現,所以,我們還需要一個兼容android 客戶端的connector: siocnnector,關於兩個connector 具體比較,以后有空重寫這篇的時候,暫時,你只要知道,這個兩個connector,一個基於socket.io,一個基於socket和websocket 即可.

app.js 由於我們用到了兩個不同的connector,所以要在app.js寫上:

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 支持 socket.io
app.configure('production|development', 'sio-connector', function(){
	app.set('connectorConfig',
		{
			connector : pomelo.connectors.sioconnector
		});
});

//支持 websocket 和 socket
app.configure('production|development', 'hybrid-connector', function(){
    app.set('connectorConfig',
        {
            connector : pomelo.connectors.hybridconnector,
            heartbeat : 300,
            useDict: true,
            useProtobuf: true

        });
});

經過這樣的配置,我們就能夠使用兩個不同的connector了.

 

用pomelo 進行消息的推送,非常便捷,由於,我們現在只關注推消息給全部客戶端,那樣就非常簡單了.

推送流程:

  • 根據uuid 把 android 客戶端添加到各自的推送頻道當中.
  • web 端根據uuid 把消息推送的全部在線的客戶端.

為了教學的方便,這里的uuid 硬編碼為: xxx-xx--xx-xx

把客戶端添加到相應的channel

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//把客戶端添加到推送列表中
PushRemote.prototype.add = function(uid, role, sid, channelName, cb){
    var channel = this.channelService.getChannel(channelName, true);
    if(role === 'server'){
		//web 服務端直接返回用戶列表
        cb(null ,this.getUsers(channelName));
    }else {
        if(!!channel){
            channel.add(uid ,sid);
        }
        //uuid 告訴給服務端onAdd 事件
        // [{uid: userId, sid: frontendServerId}]
        var server = [{uid: channelName, sid: sid}];
       this.channelService.pushMessageByUids('onAdd', {msg: "add ok", users:this.getUsers(channelName)},server, function(err){
           if(err){
               console.log(err);
               return;
           }
       });
    }
};

Frontend 利用rpc 調用pushserver 添加客戶端到相應頻道的方法.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
 //sid 統一為web managment 所在的 frontend server.
    this.app.rpc.pushserver.pushRemote.add(session, uid,role, 'connector-server-client', uuid, function(err, users){
        if(err){
            console.log(err);
            return;
        }

        if(users){
            next(null, {code: 200, msg: 'push server is ok.', users: users});
        }else{
            next(null,{code: 200, msg: "add ok", users: users});
        }
    });

web 管理端調用消息推送

 

 

1
2
3
4
5
6
7
8
9
10
11
12
Handler.prototype.pushAll = function(msg, session, next){
    var pushMsg = this.channelService.getChannel(msg.apikey, false);
    pushMsg.pushMessage('onMsg',{msg: msg.msg}, function(err){
       if(err){
           console.log(err);
       } else{
           console.log('push ok');
           next(null, {code: 200, msg: 'push is ok.'});
       }
    });

};

以上就是主要客戶端如何加入到推送隊列的代碼,以及web 管理端進行消息推送的主要代碼,是不是很簡單! 完整代碼可以參閱我的github https://github.com/youxiachai

 

有一點要注意的,如果pomelo 項目要部署到外網或者局域網,frontend 的host 要填寫當前host 主機的ip 地址

例如:

 

1
2
3
"connector": [
    {"id": "connector-server-1", "host": "127.0.0.1", "port": 3150, "clientPort": 3010, "frontend": true}
        ]

部署到某台服務器,需要修改

 

 

1
2
3
"connector": [
    {"id": "connector-server-1", "host": "192.168.1.107", "port": 3150, "clientPort": 3010, "frontend": true}
        ]

客戶端訪問相應的host 的地址.

 

客戶端和服務端的github 地址: https://github.com/youxiachai/pomelo-pushServer-Demo

如果,你現在對pomelo感興趣的話,你可以看下我寫的pomelo 的系列教程(因為還沒寫好所以暫時只發布在我的博客)暫時一共四篇.基本涵蓋了pomelo 大部分基本知識點.

http://blog.gfdsa.net/tags/pomelo/

廣州有招nodejs 程序員(有兩年android 開發經驗..orz)的嗎...能否給個面試機會,聯系郵箱: youxiachai@gmail.com

參與的相關社區:

github: https://github.com/youxiachai

cnodejs(Top積分榜 14 ...): http://cnodejs.org/user/youxiachai


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM