本文转载自微信公众号「UP技术控」,作者conan5566。转载本文请联系UP技术控公众号。

背景

做微信公众号开发的时候,其中有个接收普通消息、接收事件推送 API。

有这么条规则, ”微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次。假如服务器无法保证在五秒内处理并回复,可以直接回复空串,微信服务器不会对此作任何处理,并且不会发起重试。详情请见“发送消息-被动回复消息””。

概括起来就2点

1、就是说5s没响应,这个请求就会被放弃;

2、会重新发起请求,具有幂等性;

问题

这样就会产生2个问题。

1、假设我的方法就正好需要6s,那么即使返回结果也是没用的,因为请求被放弃了。

2、我需要返回给用户正确的回信,假设第一次超时没法及时回信,比如绑定操作,第一次没回信,第二次再来总不能回复绑定过了,这样显然不合理。

或者直接回复 success ,这样显然没法正常的进行消息提醒。

那么怎么做到既执行了操作(第一次超时了),(第二次微信重试)又及时回复正确的回信呢 。

代码实现

1、定义缓存的key,就是消息MsgId。

string cacheKey = model.MsgId.ToString();

2、使用缓存机制,把结果缓存起来,下次进来,直接回复上次执行的结果。

TimeSpan expired = new TimeSpan(0, 0, 20);

string cacheKey = model.MsgId.ToString();

return_cacheLayer.Get(cacheKey, () =>

{

MsgReply param = new MsgReply() { ToUserName = model.FromUserName, FromUserName = model.ToUserName };

string Jsonstr = WeiXinHelper.ReadAccess(HttpRuntime.AppDomainAppPath.ToString() + "/App_Data/WeChat/KeyWordReplay.json");

var r = JsonConvert.DeserializeObject(Jsonstr);

param.Content = r.content;

if (String.Equals(model.MsgType, "text", StringComparison.CurrentCultureIgnoreCase))

{

var item = r.keywordcontent.FirstOrDefault(o => o.keyword.Contains(model.Content));

if (item != null)

{

param.Content = item.content;

}

}

string response = _weChatAlertsService.SubscribeReply(param);

AddReceiveLog(model, xml, response);

returnresponse;

}, expired);

3、这样既解决幂等问题,也返回了正确的结果。

4、这里需要注意,缓存取得每个 Key专有的 lock object;若同时有多个 thread要求相同资料,只会(到数据库)查第一次,剩下的从 cache读取。

publicT Get(stringkey, Func getDataWork, TimeSpan absoluteExpireTime, bool forceRefresh =false, bool returnCopy =true)whereT : class

{

try

{

lock (GetMemoryCacheLockObject(key))

{

privatestaticobject GetMemoryCacheLockObject(stringkey)

{

string cacheLockKey = string.Format(MemoryCacheLockObjectFormat, key);

lock (CacheObject)

{

var lockObject = CacheObject[cacheLockKey];

if (lockObject == null)

{

// 取得每個 Key專屬的 lock object;若同時有多個 thread要求相同資料,只會(到資料庫)查第一次,剩下的從 cache讀取

lockObject = new object();

CacheObject.Set(

cacheLockKey,

lockObject,

new System.Runtime.Caching.CacheItemPolicy()

{

AbsoluteExpiration = DateTimeOffset.UtcNow.AddMinutes(10)

}

);

}

returnlockObject;

}

}

总结

1、使用缓存机制,把第一次的结果保存下来,对方重试的时候,直接返回上次的结果。

2、使用lock ,保证并发的时候,若同时有多个 thread要求相同资料,只会(到数据库)查第一次,剩下的从 cache读取。

【编辑推荐】

【责任编辑:武晓燕 TEL:(010)68476606】

点赞 0

微信服务器缓存消息,使用缓存防击穿,解决微信”被动回复用户消息”重试回复问题...相关推荐

  1. 使用缓存防击穿,解决微信”被动回复用户消息”重试回复问题

    背景 做微信公众号开发的时候,其中有个接收普通消息.接收事件推送 API. 有这么条规则,  "微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次.假如服务器无法保证在五 ...

  2. Java开发微信公众号(四)---微信服务器post消息体的接收及消息的处理

    在前几节文章中我们讲述了微信公众号环境的搭建.如何接入微信公众平台.以及微信服务器请求消息,响应消息,事件消息以及工具处理类的封装:接下来我们重点说一下-微信服务器post消息体的接收及消息的处理,这 ...

  3. Java微信公众平台开发(二)--微信服务器post消息体的接收

    转自: http://www.cuiyongzhi.com/post/39.html 在上一篇的文章中我们详细讲述了如何将我们的应用服务器和微信腾讯服务器之间的对接操作,最后接入成功,不知道你有没有发 ...

  4. 订阅号服务器消息推送数量,如何解决微信公众号一个月只能发4次消息的问题...

    如何解决微信公众号一个月只能发4次消息的问题 发布时间:2021-01-19 09:49:16 来源:亿速云 阅读:120 作者:小新 这篇文章将为大家详细讲解有关如何解决微信公众号一个月只能发4次消 ...

  5. 微信公众平台对接C#-向微信服务器发送消息

    Get请求 #region 向微信服务器请求信息Get/// <summary>/// 向微信服务器请求信息Get/// </summary>/// <param nam ...

  6. 微信服务器保留几年记录_你以为微信只是个聊天工具?看完这些刷新对微信的认知...

    大家使用微信时间应该有几年时间了,随着产品的迭代,一年一个大版本,一个月一个小版本,产品界面和内置功能也一直在升级,应用的基础功能是不会变,但不乏会有些小众的功能还有一下黑科技技巧,这些都是我们没有使 ...

  7. java推送微信消息换行_微信公众号开发被动回复用户消息,回复内容Content使用了\n换行符还是没有换行...

    使用语言和框架:本人后端开发使用的Python的DRF(Django REST framework)框架 需求:在微信公众号开发时,需要实现自动回复,即被关注回复.收到消息回复.关键词回复 发现问题: ...

  8. 微信公众平台消息接口开发(34)微信墙之表白墙/婚礼墙/晚会墙/会议墙/晒单墙/照片墙/历史墙...

    微信公众平台开发模式 微信 公众平台 消息接口 开发模式 企业微信公众平台 微信墙 婚礼墙/晚会墙/会议墙/晒单墙/照片墙/历史墙 历史上的今天 作者:方倍工作室   原文: http://www.c ...

  9. 微信公众平台消息接口开发(34)微信墙之表白墙/婚礼墙/晚会墙/会议墙/晒单墙/照片墙/历史墙

    微信公众平台开发模式 微信 公众平台 消息接口 开发模式 企业微信公众平台 微信墙 婚礼墙/晚会墙/会议墙/晒单墙/照片墙/历史墙 历史上的今天 作者:方倍工作室   原文: http://www.c ...

最新文章

  1. MySQL 学习笔记(14)— 数据库设计流程、实体关系图、第一范式、第二范式、第三范式、外键使用
  2. [工具推荐]用了TrueCrypt 再无难掩之隐
  3. dispatch js实现_详解vuex中action何时完成以及如何正确调用dispatch的思考
  4. iview-admin webpack打包总结的几个问题
  5. Java 自增(++) 和 C语言中自增的区别
  6. 我们在进行着一场拔河比赛……
  7. UE3 内存使用和分析
  8. 开关电源磁性元件理论及设计pdf_2020年开关电源需求活跃 通讯运营商已多轮集采...
  9. [HNOI2012 Matrix]
  10. python导入模块找不到什么原因_python模块以及导入出现ImportError: No module named 'xxx'问题...
  11. NoteBurner Spotify Music Converter mac - 音乐转换器
  12. 泪目!java项目源码免费下载
  13. [转帖]变速齿轮的一种实现方法(内有中断门的创建与调用)
  14. was cached in the local repository, resolution will not be reattempted until the update interval of
  15. Cisco Encrypted Traffic Analysis(ETA)
  16. 40亿美金史上最大 ICO,EOS 疑云
  17. 生育指南(写给临产准妈妈)
  18. 计算机防火墙无法关闭,为什么我电脑的防火墙关不了(win7电脑防火墙怎么关)
  19. multimedia教学设计计算机英语,高中英语教学设计案例
  20. 网格员计算机基本操作,maxwell基本操作之——网格剖分

热门文章

  1. 朴素贝叶斯分类器原理介绍及python代码实现
  2. 统计扣分加分java_再也不怕违章扣分了,驾照也能够加分,最高+21分!快来看怎么加...
  3. iOS/Android SQLite 全文检索——FTS (Full Text Search)
  4. Altium Designer 自动保存
  5. armv8 汇编 绝对地址赋值_GNU风格 ARM汇编语法指南(非常详细)
  6. 游戏设计行业应该选哪一块去学习,然后就业?哪个前景更好
  7. (8)UVM 学会消息管理才会让你在验证中游刃有余
  8. 2019吃鸡服务器维修,2019绝地求生11.27日更新了什么 2019绝地求生11.27日更新内容汇总...
  9. 恭喜,他们终于复婚,网友:我又相信爱情了
  10. cmd 访问文件夹目录和文件命令