微信开发中的消息排重机制实现

简介: 微信公众平台开发时,微信推送消息的机制是推送过来后如果5秒内收不到响应则认为没有推送成功,会再次推送,总共推送三次。如果我们服务器接收到消息没有及时响应,就会微信的触发“重推机制”,这就需要我们在服务端对微信推送过来的消息进行排重。

微信公众平台开发时,微信推送消息的机制是推送过来后如果5秒内收不到响应则认为没有推送成功,会再次推送,总共推送三次。如果我们服务器接收到消息没有及时响应,就会触发微信的“重推机制”,这就需要我们在服务端对微信推送过来的消息进行排重。
我们不应该让服务器出现处理时间过长的情况,对于业务复杂、处理时间长度不可控的代码可以进行异步处理,每次接收到微信推送后都立即返回空串,当然这是另外一回事了,不是今天要说的。


先看微信公众号开发文档原文

普通消息

1、关于重试的消息排重,推荐使用msgid排重。
2、微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次。假如服务器无法保证在五秒内处理并回复,可以直接回复空串,微信服务器不会对此作任何处理,并且不会发起重试。

事件推送:

微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次

关于重试的消息排重,推荐使用FromUserName + CreateTime 排重。
假如服务器无法保证在五秒内处理并回复,可以直接回复空串,微信服务器不会对此作任何处理,并且不会发起重试。

微信推送过来的消息无外乎上面两种,微信文档也给出了排重方法,下面说说我的方案:

方案一

  1. 创建判断重复消息的DuplicateRemovalMessage类;
  2. 把微信推送的消息解析赋值给DuplicateRemovalMessage对象实例;
  3. 用静态变量List当缓存,判断DuplicateRemovalMessage实例是否存在于缓存list中,如果存在则为重复消息,如果不存在则不是重复消息并把消息放到缓存List中。

此方案弊端:

  1. 缓存list会无限增大,所以用setMessageToCache方法限制了list最大容量为1000;
  2. 解决了list最大容量依然还有弊端,就是两条重复的消息之间如果有超过999个DuplicateRemovalMessage对象依然会判断不准,只能增大list容量来缓解。

实现代码:
别忘记复写hashcode、equals方法

public class DuplicateRemovalMessage {

    private String MsgId;
    
    private String FromUserName;
    
    private String CreateTime;

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((CreateTime == null) ? 0 : CreateTime.hashCode());
        result = prime * result + ((FromUserName == null) ? 0 : FromUserName.hashCode());
        result = prime * result + ((MsgId == null) ? 0 : MsgId.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        DuplicateRemovalMessage other = (DuplicateRemovalMessage) obj;
        if (CreateTime == null) {
            if (other.CreateTime != null)
                return false;
        } else if (!CreateTime.equals(other.CreateTime))
            return false;
        if (FromUserName == null) {
            if (other.FromUserName != null)
                return false;
        } else if (!FromUserName.equals(other.FromUserName))
            return false;
        if (MsgId == null) {
            if (other.MsgId != null)
                return false;
        } else if (!MsgId.equals(other.MsgId))
            return false;
        return true;
    }
      省略set和get方法...

}

方案一升级版

方案一的解决并不优雅,而且无法在负载均衡环境下使用。

改进方式是在【方案一】的基础上,使用redis替换List作为存储中介,将DuplicateRemovalMessage对象存储到redis中,存储的key可以用msgId,事件消息可以用FromUserName + CreateTime 拼接,同时给对象设置一个15秒的超时时间,这样就不会有List那种集合存储元素无限增多的情况。

最后

微信推送消息的CreateTime 精确到秒值,这就可能出现一个用户正常操作的情况下触发两条FromUserName 和CreateTime 完全相同的消息,也就是说按照微信文档上提供的排重方法会过滤掉合法数据,我在线上环境遇到过一次。

我们微信公众号开启了获取用户地理位置的功能,用户打开微信后点击菜单进入了某个页面,此时微信后台向我们推送了用户地理位置事件消息和用户点击公众号菜单事件消息,这两个消息的CreateTime 和FromUserName 相同。

所以最后建议做排重的时候,事件消息使用FromUserName + CreateTime+Event三个字段进行排重。

本文最初发布在iteye,由于iteye编辑博客内容提示我有敏感词,可是又不告诉我是哪个敏感词(真2b),无法编辑老文章,所以文章和更新以后都发到这里了。
(全文完)

相关文章
|
7月前
|
小程序 安全 数据安全/隐私保护
微信小程序全栈开发中的身份认证与授权机制
【4月更文挑战第12天】本文探讨了微信小程序全栈开发中的身份认证与授权机制。身份认证包括手机号验证、微信登录和第三方登录,而授权机制涉及角色权限控制、ACL和OAuth 2.0。实践中,开发者可利用微信登录获取用户信息,集成第三方登录,以及实施角色和ACL进行权限控制。注意点包括安全性、用户体验和合规性,以保障小程序的安全运行和良好体验。通过这些方法,开发者能有效掌握小程序全栈开发技术。
215 0
|
7月前
|
JSON 小程序 JavaScript
【微信小程序】-- 宿主环境 & 通信模型 & 运行机制介绍(五)
【微信小程序】-- 宿主环境 & 通信模型 & 运行机制介绍(五)
|
7月前
|
小程序 安全 JavaScript
.NET微信网页开发之通过UnionID机制解决多应用用户帐号统一问题
.NET微信网页开发之通过UnionID机制解决多应用用户帐号统一问题
.NET微信网页开发之通过UnionID机制解决多应用用户帐号统一问题
|
安全 JavaScript API
.NET微信网页开发之通过UnionID机制,解决用户在不同公众号,或在公众号、移动应用之间帐号统一问题
.NET微信网页开发之通过UnionID机制,解决用户在不同公众号,或在公众号、移动应用之间帐号统一问题
245 0
.NET微信网页开发之通过UnionID机制,解决用户在不同公众号,或在公众号、移动应用之间帐号统一问题
|
消息中间件 存储 缓存
【微服务】微信的消息收发机制
关注公众号“达摩院首座”,了解开发者最真实生活
1513 0
【微服务】微信的消息收发机制
|
JSON 数据格式 Python
利用Python了解微信通信机制,实现查询有多少好友删除你!!
此篇文章参考微信通信机制,收益匪浅!:http://lib.csdn.net/article/wechat/63831 QQ交流群127591054 当然也可以写发送消息的代码,机制和上述文章介绍的一样,大家可以参考学习! 偶遇:偶尔在论坛发现有外国友人在开源社区发布的Python微信删除好友查看,但是这个作者的代码我这边运行出现了点问题,就是各种问题,我在作者基础上进行研究修改!最终在Python2.7成功运行,之后又用了两天时间把运行环境转移到Python3.5。
1852 0
|
Web App开发
微信小程序的事件机制
事件机制是一种非常典型的通讯方式,可以在程序中的不同对象之间传递信息,也可以在一个应用的不同层面进行沟通协作。微信小程序中也采用了事件机制,我们这次来了解一下微信小程序框架提供的事件处理机制。
1234 0
|
前端开发
微信小程序的样式机制
之前,我已经介绍过在小程序开发中使用WXML来做界面布局,但是WXML只是一个界面的骨架。要让我们的小程序变得精致漂亮高大上起来,就需要一种为其添加样式的机制。
1123 0
|
API 开发工具
Senparc.Weixin.MP SDK 微信公众平台开发教程(十六):AccessToken自动管理机制
在《Senparc.Weixin.MP SDK 微信公众平台开发教程(八):通用接口说明》中,我介绍了获取AccessToken(通用接口)的方法。     在实际的开发过程中,所有的高级接口都需要提供AccessToken,因此我们每次在调用高级接口之前,都需要执行一次获取AccessT...
1724 0