微信服务器发送三次重复的排重问题
来源:互联网 发布:linux $ 编辑:程序博客网 时间:2024/05/17 01:13
问题来源:http://www.zhihu.com/question/22685171
微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次
由于微信官方的服务器在处理消息时候的特殊方式,导致了这种问题的发生
微信的本意是为了在丢包稍微严重的情况下服务依旧能正常运行,但是这样给开发者确提升了难度
一般是每隔5s发送一次请求的,但是如果我们的处理是耗时操作怎么办呢,我们在第10s才能结束操作,这怎么办>>>>>>>>>>>>>>>>>>
--------仅用于企业号和服务号
1.就和回答中的Aloong兄弟那样说的,我们可以先给微信服务器反馈一个空白或者不空白的数据(XML或者非XML都行),然后调用微信的高级接口,给用户发送数据即可(理由:我们反馈了一个任意数据,微信服务器认为他的工作完成了,就不会再重复发送数据了,此时我们再调用高级接口发送数据也就不会有干扰了-即使是用户短时间内多次发送请求)
流程:
a.得到数据response.getWriter();
b.得到数据request下的所有数据--->写入一个HashMap中
c.使用response的writer返回一个空白,并且关闭writer,注意如果不关闭的话,那么这个空白消息是不会被传给微信服务器的
d.使用之前的HashMap的值做我们的超时处理
--------通用方法
2.和李一峰兄弟说的那样,建立一个简单的list缓冲-相当于消息队列,来了一个消息之后就和list比对(有msgid的消息使用msgid排重。事件类型消息推荐使用FromUserName + CreateTime[重复发送相同消息这个值是一样的] 排重。),遍历list发现如果在list中存在那么就不加入list,直接return,否则的话加入list,然后继续执行操作,执行完成后反馈即可---必须使用AsyncContext这种异步操作
流程:
a.新建一个静态全局ArrayList<XXX>,添加一个类XXX{msgid, FromUserName, CreateTime}
b.遍历list如果在list中,那么直接return || 如果不在list中,list.add就行了(return之后由于Async的存在连接不会断开,所以request和response不会释放,也就不会断开本次回话,如果不使用Async的话,微信的结束自己的任务,不会重复发送,问题是我们也发不出数据回去了)
c.耗时操作,并反馈XML数据回去
模拟:只在第三次的时候返回数据,其他时候挂起
Servlet中
int coutn = 1;@Overridepublic void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {final AsyncContext asyncContext = request.startAsync(request, response);asyncContext.setTimeout(5000);//asyncContext.addListener(new AsyncListener()); 这里需要自己添加asyncContext.start(new Deal_Thread(asyncContext)); //新建一个自己的Thread类,类中执行应尽的操作 }DealThread中
@Overridepublic void run() {Date nDate = new Date(System.currentTimeMillis());PrintWriter pw = null;Map<String, String> userSendMap = null;try {pw = ((HttpServletResponse)this.context.getResponse()).getWriter();userSendMap = new dealXML().toMap((HttpServletRequest)this.context.getRequest());//if(is_exist(CoreServlet.list, (HashMap<String, String>)userSendMap))if(CoreServlet.coutn == 3) {Message_Text message_Text = new EasyFunctions().genaText(userSendMap.get("FromUserName"), userSendMap.get("ToUserName"), "wocao");pw.print(message_Text.toXMLString_And_enCode());}else{CoreServlet.coutn++;return;}pw.flush();pw.close();} catch (Exception e1) {e1.printStackTrace();}}
总结:
第一种方法用着思维挺简单,操作也挺简单,但是要求必须是企业号或者是服务号,要求不高的话可以用这个方法,操作简单并且基本上不需要考虑多线程的问题
第二种方法比较好,适用于各种情况,不仅仅是在微信上的,但是需要考虑到请求的时间问题,所以比较复杂
- 微信服务器发送三次重复的排重问题
- 微信服务器发送三次重复的排重问题
- 微信服务器之三次数据传递,排重的问题
- 重启服务器svn不发送email的问题
- SQL 数据排重,去掉重复数据
- SQL 数据排重,去掉重复数据
- ajax重复发送请求的问题
- 后台收到微信重复请求问题
- 关于字符串或者列表排重的问题
- 关于微信公众号服务器设置token的问题
- 关于微信公众号服务器设置token的问题
- 微信开发第六篇服务器主动发送信息
- linux排重的方法
- 微信服务器在五秒内无响应多次请求去重
- 浅谈用Java微信公众号开发时向微信服务器发送JSON数据包返回47001错误码问题
- 微信重复回调的坑
- 使用信锐无线控制器对接营运商portal服务器的原理分析与排错
- 关于HTTP客户端重复发送请求的问题
- Android-JSON解析
- 谁说程序员总是没对象?我跟你急。。
- 基于HTML5的WebGL呈现A星算法的3D可视化
- 3.7.2 - Escape Sequences
- Git工作流指南:Gitflow工作流
- 微信服务器发送三次重复的排重问题
- iOS中的触摸事件和手势处理
- Python简单实现基于VSM的余弦相似度计算
- lightOj 1107 - How Cow
- 3.7.3 - Basic String Operations
- 3.7.4 - Indexing and Slicing Strings
- 钢管切割Java
- 第二讲 数学模型方法
- 插入排序算法中的直接插入法和希尔排序