微信服务器发送三次重复的排重问题

原创 2015年11月18日 01:49:26

问题来源: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;
@Override
	public 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中
@Override
	public 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();
		}
	}

总结:

第一种方法用着思维挺简单,操作也挺简单,但是要求必须是企业号或者是服务号,要求不高的话可以用这个方法,操作简单并且基本上不需要考虑多线程的问题

第二种方法比较好,适用于各种情况,不仅仅是在微信上的,但是需要考虑到请求的时间问题,所以比较复杂

相关文章推荐

微信开发页面请求重发问题

偶然的一次因为项目再生产上出了问题发现的 对于微信浏览器(安卓版本)如果页面请求结束等待响应时间超过10S微信浏览器会认为没响应,并主动重发上条ajax请求 对于该问题,暂时没想到解决方案,再生产中是...

微信服务器之三次数据传递,排重的问题

我们发送消息给微信,微信发送消息给我们的服务器,服务器处理,但是这个处理时间很长,那么微信在5秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次 其实这样有个好处,就是假设出现网络丢包现象,微信...

[JAVA]微信的请求重发解决办法

最近给客户做了个微信公众号,其中在菜单上配置的查询功能需要访问客户系统接口获取数据; 微信端的http请求在一定时间内(微信开发文档中写的是5s,实际开发查看报文是7s)无法得到返回的话会重发此请求...
  • ctbtcol
  • ctbtcol
  • 2015年04月22日 09:49
  • 2598

微信服务器发送三次重复的排重问题

问题来源:http://www.zhihu.com/question/22685171 微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次 由于微信官方的服务器在处理消息时...

微信服务器在五秒内无响应多次请求去重

微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次 解决方式:利用redis做缓存处理 redis后续会更新怎么配置如何使用,本次只单一真对微信请求问题做缓存解决微信请求问题 代...

微信小程序开发填坑,优雅地处理用户的误操作引起的多次请求

在互联网应用中,我们经常用到的场景,比如用户点击某个按钮,触发的操作会和后台api进行数据交互,生成一些记录,比如下单购买。如果后台api请求比较慢,而客户端体验又做得不到位,导致用户以为没点击到或者...

mina2多线程读取重复数据的解决方案

公司定制了一个可以控制设备的硬件,人家只支持socket,我用mina2做的客户端连接,因为是多个人可以控制的所以硬件控制设置的连接只能有一个,多个用户用这个连接来控制设备,用完链接放在缓存里面,超时...

微信多客户端导致重复调用服务接口问题

如果手机登陆微信,同时PC也登陆微信时,通过PC客户端请求应用时,例如请求微信的ouath接口,这时微信回调用2次接收ouath回调接口,如下图一;如果是通过手机操作请求应用时,则仅有1次回调。 图...

Java 微信发送模板消息

Java微信发送模板消息

微信第三方平台开发经验总结(六):接收微信用户发送的事件以及消息

接收微信用户发送的事件以及消息 进入第三方平台的管理中心,查看并保存以下信息 确认预设的公众号消息与事件接收URL 把token和key保存在项目的静态类中或...
  • lwx0313
  • lwx0313
  • 2017年08月21日 17:20
  • 602
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:微信服务器发送三次重复的排重问题
举报原因:
原因补充:

(最多只允许输入30个字)