后端程序员福音 -- TellMe 推送助手

[Geek工具箱] 后端程序员福音 – TellMe 类Server酱的 推送助手

为什么做这个

身为后端程序员,需要管理很多服务器,再加上自己折腾Nas,树莓派,智能家居等等,有很多消息需要推送,比如:

  1. 系统运行状态定时推送
  2. 异常报告推送
  3. 在线、离线状态
  4. 程序运行完成状态等等

我尝试了很多办法,但都没有完全满足我的需求:

  1. QQ \ 微信 机器人, 失败。 原因是这些都已经关闭了,且认证麻烦,使用不便。
  2. 邮箱推送, 失败。 邮箱推送的延迟不可控,且容易受手机杀后台的影响。
  3. Server酱, 目前在使用。 在这里还是要感谢Server酱为大家免费很多优质的服务,但在我目前使用过程中有很多不太方便的地方,比如: 内容自定义程度不高

既然没有,那就只能自己撸一个工具了,我对其定位是: 简单( 只做推送), 可扩展(方便开发新功能), 开源(人多力量大)

功能设计

目前我设想的几个特性:

  1. 无需登录。 打开APP即获取ID,往该ID发GET/POST请求即可推送到APP
  2. 发送普通消息。 GET /push/{id}?title=标题&content=内容
  3. 宕机监测。 重复发送 GET /downCheck/{id}?timeout=10&title=宕机了&content=设备1宕机了,timeout没收到,则向APP推送宕机消息

核心功能解析

长连接

  1. Websocket长连接。 APP通过websocket与服务器保持长连接,避免轮训消耗。
  2. 心跳监测。定时检查连接状态,离线自动重连。

消息的可靠推送

ACK + ID, 对消息编号,通过ACK确保消息传输的可靠性。

其中,最关键的ACK机制流程如下:

  1. GET \ POST收到 发送给device1的消息msg
  2. 对消息编号,并存储到消息缓存:message_buffer
    ConcurrentHashMap<String:device_id, TreeMap<Integer:message_id, Message>>
    这样的结构中。 device_id -> 消息map。外层使用ConcurrentHashMap是为了提高并发访问消息缓存的效率,内层使用TreeMap是为了实现消息的有序访问(message_id是自增的)。
    同时,向device1推送该消息
  3. device1收到消息之后,返回message_id的ACK,并存储到本地数据库
  4. 服务器收到ACK,从message_buffer中清除该消息。
  5. 设备重新上线,获取所有消息(TreeMap有序的),并推送到设备
       public class MessageBuffer {
           private static ConcurrentHashMap<String, TreeMap<Integer, Msg>> buffer = new ConcurrentHashMap<>();  // 待优化
       
           /**
            * 添加消息
            * @param dst
            * @param mId
            * @param msg
            */
           public void addMessage(String dst, Integer mId, Msg msg) {
               synchronized (this) {
                   TreeMap<Integer, Msg> temp;
                   if (!buffer.containsKey(dst)) {  // 新设备,新TreeMap
                       temp = new TreeMap<>();
                   } else {
                       temp = buffer.get(dst);
                   }
       
                   temp.put(mId, msg);
                   buffer.put(dst, temp);
               }
           }
       
       
           /**
            * 获取所有
            * @param dst
            * @return
            */
           public List<MessageBean> getMessages(String dst) {
               if (!buffer.containsKey(dst)) return null;
       
               synchronized (this) {
                   TreeMap<Integer, Msg> temp = buffer.get(dst);
                   return temp.entrySet().stream().map((entry) -> {  // 获取所有消息
                       MessageBean m = new MessageBean();
                       m.setId(entry.getKey());
                       m.setTitle(entry.getValue().getTitle());
                       m.setContent(entry.getValue().getContent());
                       return m;
                   }).collect(Collectors.toList());
               }
           }
       
           /**
            * 删除消息
            * @param dst
            * @param mId
            */
           public void deleteMessage(String dst, Integer mId) {
               if (!buffer.containsKey(dst)) return;
       
               synchronized (this) {
                   TreeMap<Integer, Msg> temp = buffer.get(dst);  // 移除
                   temp.remove(mId);
               }
           }
       }

进度及安排

目前已完成

  1. 核心功能的初步实现
  2. 可以推送消息到APP端
    正常推送
    离线推送

第二阶段

  1. 完善核心功能,如自动获取ID,宕机检测
  2. 项目部署上线,供大家免费使用

第三阶段

  1. 代码整理开源
  2. 邀请IOS程序员开发IOS端(目前只有Android客户端)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值