微信公众平台开发时,微信推送消息的机制是推送过来后如果5秒内收不到响应则认为没有推送成功,会再次推送,如果5秒内仍没有收到响应继续推送,总共推送三次。
微信文档原文:
普通消息
1、关于重试的消息排重,推荐使用msgid排重。
2、微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次。假如服务器无法保证在五秒内处理并回复,可以直接回复空串,微信服务器不会对此作任何处理,并且不会发起重试。
2、微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次。假如服务器无法保证在五秒内处理并回复,可以直接回复空串,微信服务器不会对此作任何处理,并且不会发起重试。
事件推送:
微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次
关于重试的消息排重,推荐使用FromUserName + CreateTime 排重。
假如服务器无法保证在五秒内处理并回复,可以直接回复空串,微信服务器不会对此作任何处理,并且不会发起重试。
关于重试的消息排重,推荐使用FromUserName + CreateTime 排重。
假如服务器无法保证在五秒内处理并回复,可以直接回复空串,微信服务器不会对此作任何处理,并且不会发起重试。
我的解决方案:
1.创建判断重复消息的DuplicateRemovalMessage类;
2.把微信推送的消息解析赋值给DuplicateRemovalMessage对象实例;
3.用静态变量list当缓存,判断DuplicateRemovalMessage实例是否存在于缓存list中,如果存在则为重复消息,如果不存在则不是重复消息并把消息放到缓存list中。
此方案弊端:
1.缓存list会无限增大,所以用setMessageToCache方法限制了list最大容量为1000;
2.解决了list最大容量依然还有弊端,就是两条重复的消息之间如果有超过999个DuplicateRemovalMessage对象依然会判断不准,只能增大list容量来缓解,由于这种情况比较极端,目前远没有那么大业务量,所以暂时这么用着了。
大家有什么好的解决方案一起交流,欢迎拍砖。
下面是具体实现代码:
注意:DuplicateRemovalMessage别忘记复写hashcode、equals方法
private static final int MESSAGE_CACHE_SIZE = 1000; private static List<DuplicateRemovalMessage> MESSAGE_CACHE = new ArrayList<DuplicateRemovalMessage>(MESSAGE_CACHE_SIZE); /** * @Description: 判断微信请求是否重复 * @return boolean 如果重复返回true */ public static boolean isDuplicate(Map<String, String> request) { String fromUserName = request.get("FromUserName"); String createTime = request.get("CreateTime"); String msgId = request.get("MsgId"); DuplicateRemovalMessage duplicateRemovalMessage = new DuplicateRemovalMessage(); if (msgId != null) { duplicateRemovalMessage.setMsgId(msgId); } else { duplicateRemovalMessage.setCreateTime(createTime); duplicateRemovalMessage.setFromUserName(fromUserName); } if (MESSAGE_CACHE.contains(duplicateRemovalMessage)) { // 缓存中存在,直接pass return true; } else { setMessageToCache(duplicateRemovalMessage); return false; } } private static void setMessageToCache(DuplicateRemovalMessage duplicateRemovalMessage) { if (MESSAGE_CACHE.size() >= MESSAGE_CACHE_SIZE) { MESSAGE_CACHE.remove(0); } MESSAGE_CACHE.add(duplicateRemovalMessage); }
DuplicateRemovalMessage对象:
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; } public String getMsgId() { return MsgId; } public void setMsgId(String msgId) { MsgId = msgId; } public String getFromUserName() { return FromUserName; } public void setFromUserName(String fromUserName) { FromUserName = fromUserName; } public String getCreateTime() { return CreateTime; } public void setCreateTime(String createTime) { CreateTime = createTime; } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("DuplicateRemovalMessage [MsgId="); builder.append(MsgId); builder.append(", FromUserName="); builder.append(FromUserName); builder.append(", CreateTime="); builder.append(CreateTime); builder.append("]"); return builder.toString(); } }
相关推荐
实现 SQL SERVER 数据库中的微信推送功能,可以将一些报警消息发送到微信讨论组或者微信订阅号、公众号、服务号,需要有认证的微信订阅号或者微信服务号
自从用了老毛子固件中的微信推送,就再也放弃不了了,由于路由器的性能不够,改换LEDE软路由的门厅,但是LEDE软路由中又没有微信推送相关的功能,实在是太不方便了,于是在网上四处寻找软路由的推送脚本,可惜有关软...
php编写 微信信息推送接口、钉钉推送接口、企业微信推送接口
主要介绍了C#微信公众号开发之接收事件推送与消息排重的方法,详细分析了事件推送与消息排重的使用技巧,对微信开发有一定参考借鉴价值,需要的朋友可以参考下
java实现企业微信消息推送
VC++实现通过HTTPS以JSON数据格式微信推送消息,包含HTTPS协议和JSON协议,VS2008,VS2015
根据微信官方文档,个人整理出来的微信推送的一个简单的流程图(仅是个人理解)
c#winform开发微信企业号推送文本消息,图片,图文,视频,语音等消息
springboot实现微信公众号模版消息推送,用的是构架:springboot+redis,详细教程:https://blog.csdn.net/chenhongming888/article/details/95173079
给女朋友做的微信公众号消息每日自动推送天气及纪念日通知教程,该教程为github每日自动线上运行版本。本人亲测妹子很喜欢~女孩子都喜欢这种用心做的东西! 1.最新版本 成品 +源码 +消息模板 (需要自己申请 天行 ...
java二次开发接微信公众号接口,实现根据用户授权,获取用户code,再获取openid,然后向其推送模版消息
thinkphp 5.0 对接微信公众号,向指定用户发送模板消息
(VB源码)微信公众号消息推送修改版,现在可以根据数据库自动获取accesstoken,方便大家更好的测试。(代码中的数据库连接要换成自己的) 这个代码是从本网下载后修改的,原版:...
企业微信发送推送消息以及上传媒体文件完整代码及测试,jdk1.6+ecplise
C#版的微信的推送例子,稍微改一下就可以直接用
springboot实现微信模板消息推送,包含微信端代码。简单封装,方便二次开发!
本文实例为大家分享了php微信模板消息推送的具体代码,供大家参考,具体内容如下 1.微信公众号模板消息配置 2.PHP代码 /** * 发送模板消息 */ public function send_notice(){ //获取access_token if ($_COOKIE...
1、通过企业微信,获取对应的accs_token 2、向企业微信发送对应的消息。
dotnet-DotNETCore实现微信公众号被关注时推送消息dotnet-DotNETCore实现微信公众号被关注时推送消息dotnet-DotNETCore实现微信公众号被关注时推送消息dotnet-DotNETCore实现微信公众号被关注时推送消息dotnet-...
微信推送分析方案.docx