Tornado里面self.write("hello")出现"Broken pipe Error"怎么办,tornadoself.write,其实这里就是解决微信公众
Tornado里面self.write("hello")出现"Broken pipe Error"怎么办,tornadoself.write,其实这里就是解决微信公众
其实这里就是解决微信公众号的5秒重传机制,使得公众号后台能获得充裕的处理时间(5+5+5)s。
我的做法是(以下针对微信公众号的文本消息):
要想突破5秒时间的响应限制,可以根据文本消息中唯一值MsgId进行排重。当普通微信用户向公众账号发消息时,微信服务器将POST消息的XML数据包发到开发者填写的URL上进行处理,开发者服务器首先对每个到来的文本消息利用memcached,以MsgId为键,值为1,设置set(MsgId, 1),然后进行响应处理,若处理完成会更改MsgId对应的值为某一字符串。
www.iplaypy.com 编橙之家
而当这次请求响应无法在5秒内完成,微信服务器将用第一次同样的XML数据包(MsgId相同)发起第二次请求,这样开发者服务器通过get(MsgId)的值进行判断,若get(MsgId)为1,则令其自增incr(MsgId)为2。然后进行等待直到get(MsgId)不为1或2或3。若get(MsgId)不为1或2或3,则直接响应微信服务器,响应完成。第三次请求同理。下面是此想法的实现为代码:
class WeixinHandler(tornado.web.RequestHandler): def post(self): # 省略文本解析... key = msgId if mc.get(key) == None: mc.set(key, 1) elif mc.get(key) == 1 or mc.get(key) == 2: mc.incr(key) if mc.get(key) == 1: # 任务处理 elif mc.get(key) == 2: # 无限等待 mc.get(key) != 2 and mc.get(key) != 3 elif mc.get(key) == 3: if mc.get(key) == 3: mc.set(key, u'任务无法完成') else: pass else: pass # iplaypy.com self.write(mc.get(key)) mc.delete(key) # 每次请求都会调用,这样的话,一个失败的`write`(上面的 # 语句)就会导致其它的请求响应异常了。
这里的问题是对于同一个消息的三次请求,每次都要self.write(),而若微信服务器发起了第二次请求,第一次请求就会在self.write()时出现write error: broken pipe而且接着又调用mc.delete(key)了,这样一来就会导致后续的请求响应乱套了,原本的第二次请求可能又会进行任务处理,可能导致无法响应微信服务器。我尝试用异常进行处理:
try: self.write(mc.get(key)) except IOError as e: print "write error ..." return mc.delete(key)
却仍然没有用,查看了Tornado中的write函数源代码发现其并未对write error: broken pipe抛出异常,使得try... except ...无法捕获。
各位大神,这个该如何解决啊,已经困扰我好几个月了。
编橙之家文章,
相关内容
- requests爬取代理网站ip验证,登陆ip网站查询ip不变的原
- 用python将序列化之后的 json 存储在 mysql 中并且对于开发
- 编程语言的选择: Why choose Ruby or Python over PHP for web dev
- Django Web开发里面的url的重定向问题,比如这个abc.com/
- CentOS系统Python的版本太low了,该怎么升级呢》,centos
- Scrapy pipeline数据模块出现问题的解决,scrapypipeline,Scr
- django admin管理部分是否在一个页面inline外键的外键呢?
- django ueditor编辑器安装时怎样引用静态文件 jss css样式表
- redis数据库怎么样来实现全文搜索功能呢?,redis全文搜
- Python3版本中的 datetime.today() and datetime.now() 不一样的地
评论关闭