前言

实际上,个人感觉,pomelo 目前提供的两个默认sioconnectorhybridconnector 使用的协议并不适合用于做手机推送平台,在pomelo的一份公开ppt里面,有提到过, 网易的消息推送平台是基于pomelo开发的 (一个frontend 支持30w 长连接,消耗了3g 内存,如果我没记错数据应该是这样),不过,这里用的前端(frontend)实现的是基于MQTT协议,我估计这个基于MQTT协议实现的frontend,基本不可能开源出来.这里只是说,默认提供的frontend不适合用于构建大型的推送平台(c10m规模的),一般而言(c10k级别的),个人感觉还是够用的.

为了展示,更多pomelo 的相关特性,可能这里的逻辑业务,与实际有所不同.敬请注意

推送平台的架构图

整个应用的架构图:

后端

  • 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"
}

客户端访问用的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
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

用Pomelo 搭建一个简易的推送平台的更多相关文章

  1. 使用SignalR ASP.NET Core来简单实现一个后台实时推送数据给Echarts展示图表的功能

    什么是 SignalR ASP.NET Core ASP.NET Core SignalR 是一种开放源代码库,可简化将实时 web 功能添加到应用程序的功能. 实时 web 功能使服务器端代码可以立 ...

  2. Angularjs,WebAPI 搭建一个简易权限管理系统

    Angularjs,WebAPI 搭建一个简易权限管理系统 Angularjs名词与概念(一)   1. 目录 前言 Angularjs名词与概念 权限系统原型 权限系统业务 数据库设计和实现 Web ...

  3. 使用EF Code First搭建一个简易ASP.NET MVC网站,允许数据库迁移

    本篇使用EF Code First搭建一个简易ASP.NET MVC 4网站,并允许数据库迁移. 创建一个ASP.NET MVC 4 网站. 在Models文件夹内创建Person类. public ...

  4. express + mongodb 搭建一个简易网站 (四)

    express + mongodb 搭建一个简易网站 (四) 目前网站整体页面都已经能全部展示了,但是,整个网站还有两个块需要做完才能算完整,一个连接数据库,目前网站上的数据都是抓取的本地假数据,所以 ...

  5. express + mongodb 搭建一个简易网站 (三)

    express + mongodb 搭建一个简易网站 (三) 前面已经实现了基本的网站功能,现在我们就开始开搞一个完整的网站,现在整个网站的UI就是下面的这个样子. 我们网站的样子就照着这个来吧. 1 ...

  6. express + mongodb 搭建一个简易网站(二)

    express + mongodb 搭建一个简易网站 (二) 在搭建网站(一)中,实现了简单的路由功能,这离一个完整的网站还差的有点远,继续撸代码吧. 1.首先在根目录下新建一个views文件夹,用来 ...

  7. express + mongodb 搭建一个简易网站(一)

    express + mongodb 搭建一个简易网站(一) 前言:后台使用node.js的express框架,数据库使用mongodb,模板使用ejs.大概就这些. 开始第一个简易网站之旅吧.... ...

  8. 如何搭建一个简易的 Web Terminal(一)

    前言 在介绍本篇文章的时候,先说一下本篇文章的一些背景.笔者是基于公司的基础建设哆啦 A 梦(Doraemon)一些功能背景写的这篇文章,不了解.有兴趣的同学可以去 袋鼠云 的 github 下面了解 ...

  9. vivo推送平台架构演进

    本文根据Li Qingxin老师在"2021 vivo开发者大会"现场演讲内容整理而成.公众号回复[2021VDC]获取互联网技术分会场议题相关资料. 一.vivo推送平台介绍 1 ...

随机推荐

  1. C# web winform 路径

    string path = "";                if (System.Environment.CurrentDirectory == AppDomain.Curr ...

  2. WebStorm License Activation (WebStorm许可证激活)

    User or company name(用户或公司名称):  EMBRACE License key(许可证密钥):  ===== LICENSE BEGIN =====89374-12042010 ...

  3. 用SQL语句,删除掉重复项只保留一条

    用SQL语句,删除掉重复项只保留一条 在几千条记录里,存在着些相同的记录,如何能用SQL语句,删除掉重复的呢1.查找表中多余的重复记录,重复记录是根据单个字段(peopleId)来判断 select ...

  4. 50条LINUX命令整理

    1. find 基本语法参数如下: find [PATH] [option] [action] # 与时间有关的参数: -mtime n : n为数字,意思为在n天之前的“一天内”被更改过的文件: - ...

  5. Titanium系列--安装Titanium Studio 中的Android SDK,JDK以及环境变量的配置(二)

    Ubuntu安装配置JDK 1.先去 Oracle下载Linux下的JDK压缩包,我下载的是jdk-8u25-linux-x64.tar.gz文件,下好后直接解压 Step1:# 将解压好的jdk1. ...

  6. [Leetcode][JAVA] Pascal's Triangle I, II

    Pascal's Triangle: Given numRows, generate the first numRows of Pascal's triangle. For example, give ...

  7. RHEL5.8使用yum安装应用时包冲突的处理

    RHEL5.8使用yum安装应用时包冲突的处理办法记录,总体思路是如果发现包冲突的情形,那么就把冲突的包给删除掉,然后再重新使用yum安装即可. 冲突示例: Transaction Check Err ...

  8. 重启EBS

    http://www.cnblogs.com/toowang/archive/2012/03/28/2421275.html 概述步骤(此操作没有停止数据库): 1.登陆FTP,终止应用:cd $CO ...

  9. solr与.net系列课程(八)solr中重跑索引的注意事项

    solr与.net系列课程(八)solr中重跑索引的注意事项 我们如果在项目中使用solr,那肯定就是把数据库中的数据跑进solr服务器中,solr有两种操作一种是新建索引,一种是增量索引,这里我们来 ...

  10. 设计模式之美:Singleton(单件)

    索引 意图 结构 参与者 适用性 缺点 效果 相关模式 实现 实现方式(一):使用 Static 变量初始化 Singleton. 实现方式(二):使用 Lazy Initialization 来实现 ...