前言

实际上,个人感觉,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. 对比DOM和jQuery完善度

    <input type="text" id="username" value="请输入你的用户名"> <script> ...

  2. maven 创建Hadoop程序

    这里用来将新建的maven project 放入到现有的maven working set 中,这样我们就能看到项目之间的层级关系 选择下面的程序 在父项目中创建公共的pom,在pom中维护项目所需要 ...

  3. php中英文截取无乱码 包括全角下的字符

    符合UTF-8下,如果GBK下  改为  $content .= $str[$sing].$str[$sing+1];        $sing += 3; 改为 $sing += 2; /**    ...

  4. C# 基础(3)

    跳转语句 Goto(现在一般不使用) 标志位 Flag true false 常量:(不可改变的量) 语法: Const 类型 变量名 = 常量值 在定义时赋值,其他地方不能赋值 枚举 是自己定义了一 ...

  5. Qt 无法解析外部文件2001,2019之类的

    一般是部分代码出错,比如构造函数的实参没有对应或者设置好: 还有尝试删除debug生成的文件试试,清理当前项目->重新构建: 以及看下有没有变量没有初始化或者变量定义的时候父类错了等. 以及其他 ...

  6. Jade之Includes

    Includes jade允许利用include将其他文件(支持filters所支持的类型)中的代码嵌入当前代码中. jade: //- index.jade doctype html html in ...

  7. jsp_属性范围_session

    session属性设置后,不管是客户端跳转还是服务器端跳转,只要属性设置了就可以取得. 下面写个小例子来验证一下: (1)session_demo.jsp <%@ page contentTyp ...

  8. HDU 5023 A Corrupt Mayor's Performance Art (据说是线段树)

    题意:给定一个1-n的墙,然后有两种操作,一种是P l ,r, a 把l-r的墙都染成a这种颜色,另一种是 Q l, r 表示,输出 l-r 区间内的颜色. 析:应该是一个线段树+状态压缩,但是我用s ...

  9. SQL优化笔记—CPU优化

    补充:常规服务器动态管理对象包括,下面有些资料可能会应用到 dm_db_*:数据库和数据库对象dm_exec_*:执行用户代码和关联的连接dm_os_*:内存.锁定和时间安排dm_tran_*:事务和 ...

  10. 『TCP/IP详解——卷一:协议』读书笔记——01

    从今日起开始认真研读TCP/IP详解这本经典制作,一是巩固我薄弱的计算机网络知识,二来提高我的假期的时间利用率.将心得与思考记录下来,防止白看-哦耶 2013-08-14 18:47:06 第一章 概 ...