用Pomelo搭建一个简易的推送平台

开发 前端
pomelo目前提供的两个默认sioconnector和hybridconnector 使用的协议并不适合用于做手机推送平台,在pomelo的一份公开ppt里面,有提到过,网易的消息推送平台是基于pomelo开发的 ,不过,这里用的前端(frontend)实现的是基于MQTT协议,我估计这个基于MQTT协议实现的 frontend,基本不可能开源出来。

前言

实际上,个人感觉,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.     "role""client/server",  
  3.     "apikey""String",  
  4.     "clientId""String" 

服务端返回对象

发给web management

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

发给android客户端

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

客户端访问用的route

android:

connector route = sio-connector.entryHandler.enter, 用于把当前客户端加入到推送频道当中

WebManagement:

connector route = hybrid-connector.entryHandler.enter,用于连接服务器.
backend route = pushserver.pushHandler.pushAll, 把消息推送到所有已连接的客户端.

 

后台编码

Pomelo 有个特点,就是约定开发,很多地方是约定好的配置,优点是,架构清晰,可读性好,缺点是,需要大量的文档支持,目前而言,pomelo的官方文档做的不好的地方就是,虽然文档都有了,但是太零散了,分类不清楚,还有就是文档没跟上开发,有时候,你不阅读里面源码根本不知道这个api要传那些参数.

 

sioconnector / hybridconnector

由于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. // 支持 socket.io  
  2. app.configure('production|development''sio-connector', function(){  
  3.     app.set('connectorConfig',  
  4.         {  
  5.             connector : pomelo.connectors.sioconnector  
  6.         });  
  7. });  
  8.  
  9. //支持 websocket 和 socket  
  10. app.configure('production|development''hybrid-connector', function(){  
  11.     app.set('connectorConfig',  
  12.         {  
  13.             connector : pomelo.connectors.hybridconnector,  
  14.             heartbeat : 300,  
  15.             useDict: true,  
  16.             useProtobuf: true 
  17.  
  18.         });  
  19. }); 

经过这样的配置,我们就能够使用两个不同的connector了.

 

 

 

推送实现

用pomelo 进行消息的推送,非常便捷,由于,我们现在只关注推消息给全部客户端,那样就非常简单了.

推送流程:

  • 根据uuid 把 android 客户端添加到各自的推送频道当中.
  • web 端根据uuid 把消息推送的全部在线的客户端.

为了教学的方便,这里的uuid 硬编码为: xxx-xx--xx-xx

把客户端添加到相应的channel

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

Frontend 利用rpc 调用pushserver 添加客户端到相应频道的方法.

  1. //sid 统一为web managment 所在的 frontend server.  
  2.     this.app.rpc.pushserver.pushRemote.add(session, uid,role, 'connector-server-client', uuid, function(err, users){  
  3.         if(err){  
  4.             console.log(err);  
  5.             return;  
  6.         }  
  7.  
  8.         if(users){  
  9.             next(null, {code: 200, msg: 'push server is ok.', users: users});  
  10.         }else{  
  11.             next(null,{code: 200, msg: "add ok", users: users});  
  12.         }  
  13.     }); 

web 管理端调用消息推送

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

以上就是主要客户端如何加入到推送队列的代码,以及web 管理端进行消息推送的主要代码,是不是很简单! 完整代码可以参阅我的github https://github.com/youxiachai

 

 

有一点要注意的,如果pomelo 项目要部署到外网或者局域网,frontend 的host 要填写当前host 主机的ip 地址

例如:

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

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

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

客户端访问相应的host 的地址.

 

 

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

原文链接:http://my.oschina.net/youxiachai/blog/138280

责任编辑:林师授 来源: OSCHINA
相关推荐

2010-03-08 17:20:56

搭建私有云

2022-10-20 11:49:49

JS动画帧,CSS

2022-08-15 18:01:23

网站Python

2021-04-25 08:58:00

Go拍照云盘

2024-04-03 15:20:08

2013-06-28 17:28:04

推送

2021-08-08 21:17:18

管理配置平台

2023-01-18 07:49:42

2023-10-06 11:48:37

reactvuenodejs

2021-05-19 14:22:46

代码开发项目

2022-11-14 08:01:48

2018-03-01 10:45:25

HTTP服务器程序

2014-07-21 10:25:12

ENode开发论坛

2022-02-25 08:32:07

nodemon搭Node.jsJavascript

2021-07-19 10:22:52

疫苗设计师百度

2016-03-01 14:37:47

华为

2022-01-10 11:04:41

单链表面试编程

2023-09-08 13:10:20

运营分析体系

2023-12-06 08:07:13

拖拽库可视化

2015-12-16 20:41:22

品高云云计算高校
点赞
收藏

51CTO技术栈公众号