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

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

总结:

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

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

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
PyCharm是一款强大的Python集成开发环境(IDE),可以帮助开发者更高效地编写和调试Python代码。虽然PyCharm内置了许多功能,但无法直接提供微信自动发送的功能。 要实现PyCharm的微信自动发送功能,我们可以借助其他Python库。首先,我们需要安装itchat这个库,它是一个用于微信个人号的微信API接口,可以通过Python与微信进行互动。 使用itchat,我们可以通过代码实现微信自动发送消息的功能。首先,我们需要通过itchat库登录微信账号,可以使用`itchat.auto_login()`函数实现。登录后,可以用`itchat.search_friends()`函数通过好友的昵称或备注来查找对应的好友,并得到好友的唯一标识。 通过`itchat.send()`函数,我们可以传入对应的好友标识和要发送的消息,实现自动发送。例如,可以使用`itchat.send('Hello, world.', toUserName=friend['UserName'])`来向指定好友发送消息。 在实现自动发送功能时,我们还可以结合其他功能,如从文件中读取要发送的消息,使用定时器来定时发送消息,等等。这样,我们就可以利用PyCharm和itchat库来实现微信自动发送消息的功能。 需要注意的是,使用itchat库发送消息前,可能需要扫描二维码进行登录验证,这时需要准备微信手机客户端,并保持手机端与电脑端登录同一个账号。 总之,使用PyCharm结合itchat库可以实现微信自动发送功能,使我们更方便地与微信好友进行沟通和交流。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值