实时消息推送的几种实现方式
相较于手机端的消息推送(一般都是以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的数据结构设计如下
OSChina的留言表设计
- id : 留言主键字段,自增长
- user : 留言的主人
- friend : 对方的ID
- sender : 留言发送者
- receiver : 留言接收者
- type : 留言类型(普通消息、系统消息)
- content : 留言内容
- send_time : 发送时间
- read_time : 阅读时间
- status : 留言状态
一条留言保存两条记录:因为每个人都有收到的留言和已发送留言,当发送人删除了已发送留言,不会影响到接收人查看收到的留言
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
查询所有关于我的留言
|
|
列出我跟每个人的最后一条留言的话(就好象留言箱首页显示的内容)
|
|
参考内容
- Worktile中的实时消息推送服务实现
- OSChina 的留言表设计说明
- GitHub - samuraisam/pyapns: An APNS provider with multi-app support.