消息推送入门

Posted by YueLng Chen on 2018-02-02

实时消息推送的几种实现方式

相较于手机端的消息推送(一般都是以socket方式实现),web端是基于http协议,很难像tcp一样保持长连接。但随着技术的发展,出现了websocket, comet等新的技术可以达到类似长连接的效果,这些技术大体可分为以下几类:

  • 短轮询。页面端通过js定时异步刷新,这种方式实时效果较差。
  • 长轮询。页面端通过js异步请求服务端,服务端在接收到请求后,如果该次请求没有数据,则挂起这次请求,直到有数据到达或时间片(服务端设定)到,则返回本次请求,客户端接着下一次请求。
  • Websocket。浏览器通过websocket协议连接服务端,实现了浏览器和服务器端的全双工通信。需要服务端和浏览器都支持websocket协议。消息队列+websocket
  • comet+redis
  • socket.io + java netty

comet

先讲起源,在http1.0时每次都要为每一个http请求进行套接字连接,这样造成许多资源浪费,为了避免这种浪费,在http1.1开始,对同一台客户端发起的多个请求使用相同的套接字完成,这就是keep-alive技术,在聊天室等应用中需要时时收到服务器端消息,通过keep-alive保持的套接字,由服务器向客户端推送消息,这个被称为comet技术。所以在服务端,需要支持更多的keep-alive连接,由此带来的C10k问题。可以说comet以可扩展性为代价来换取实时性。

websocket在各个浏览器支持的情况

粉红色区域表示不支持Websocket。
至于IE浏览器,以及部分陈旧的桌面浏览器,可以选择Flashsocket作为替代品。

Notice表的参考设计

Worktile 中 Notice的数据结构设计如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
nid: { type: String, unique: true },
published: { type: Number, default: Date.now },
verb: { type: String },
template: { type: String },
is_read: { type: Number, index: true, default: 0 },
is_pending: { type: Number, index: true, default: 0 },
filter: {
ftype: { type: String }
},
sender: { type: Actor },
receiver : { type: String , index: true},
data: {
entity: { type: Entity },
source: { type: Entity },
target: { type: Entity }
}
}

OSChina的留言表设计

  • id : 留言主键字段,自增长
  • user : 留言的主人
  • friend : 对方的ID
  • sender : 留言发送者
  • receiver : 留言接收者
  • type : 留言类型(普通消息、系统消息)
  • content : 留言内容
  • send_time : 发送时间
  • read_time : 阅读时间
  • status : 留言状态
  1. 一条留言保存两条记录:因为每个人都有收到的留言和已发送留言,当发送人删除了已发送留言,不会影响到接收人查看收到的留言

  2. user/friend/sender/receiver 这四个字段是不是多余?
    那么以冗余来换性能的思路,我们对这个表进行了小改造。
    增加两个字段 user 和 friend,当 A 发送留言给 B 时,会写入两条记录:
    记录1. user=A,friend=B,sender=A,receiver=B
    记录2. user=B,friend=A,sender=A,receiver=B
    查询所有关于我的留言

1
SELECT * FROM osc_msgs WHERE user = <我> ORDER BY id DESC

列出我跟每个人的最后一条留言的话(就好象留言箱首页显示的内容)

1
SELECT MAX(id) AS id, COUNT(id) AS msgCount FROM osc_msgs WHERE user = ? GROUP BY friend ORDER BY id DESC

参考内容

  1. Worktile中的实时消息推送服务实现
  2. OSChina 的留言表设计说明
  3. GitHub - samuraisam/pyapns: An APNS provider with multi-app support.