发布于2019-09-02 12:29 阅读(849) 评论(0) 点赞(10) 收藏(1)
最近的工作是给微信做一个消息类的后台类的应用。
消息类的后台类的应用的意思就是,这个应用不需要界面,不需要美工,也不需要客户端。它只是微信的一个普通账号。你可以加这个账号为好友。然后你可以和这个账号聊天获取你想要的内容。这个账号也会自动发消息给你。其实有点像聊天机器人。
我写的这个后台类的应用是为泰国用户写的。会根据用户发过来的日期发送这个用户当天的运气好坏。包括财运、霉运、桃花运和幸运数字这些。世界上真的有人信这些? 我谨慎的表示怀疑。
我是在linux平台上用Python写的。第一个需要解决的问题就是如何保持在后台运行不退出。幸好Python保持了很好的和C语言libc库函数的兼容性,用几行代码可以搞定。
import os
if os.fork():
os.setsid()
....
else:
os.exit()
和libc的函数原型几乎一模一样。这段代码的意思是先fork出一个子进程。然后在让子进程脱离原进程组创建一个新的后台进程组,从而与终端脱离,成为后台运行的不死进程。关于这方面的知识可以看《UNIX环境高级编程》9.6控制终端。
我用了3个后台进程来实现产品的需求。 首先用户发送生日的日期,我需要返回该日期对应的星期几的今日的运程。比如用户发送1/11/1985, 这代表1985年11月1日。 我需要计算这一天是星期五,然后给他返回星期五这一天出生的人今天的运气怎么样。运气怎么样不是我说的,据说是泰国合作方聘请了一个真正的算命的人每天去编辑的。所以我需要从一个url来拉取每一天,出生于一周的每一天的人的当天运气情况。于是第一个后台进程的功能就是需要去定时去拉取这个url的最新内容,并存放在本地。比较糟糕的一点是,我不知道这个算命的人每天会在什么时候去更新。他可能是头一天晚上8点钟更新,也可能是当天的4点。这比较烦,我需要每隔一段时间去拉取。然后还需要从内容中分析这是哪一天的内容。这是第一个进程。
解决了内容的来源问题之后我所要面临的第二个问题是我从哪里获取用户的消息。从微信那里拿来了一份MessageAPI文档。这份文档现在我还不能公开因为没有对外发布。微信可以通过HTTP长连接不断的向你PUSH用户发送的消息过来,而你所需要做的就是拿到消息做处理。就跟用电饭煲做米饭那么简单。那么这里所需要解决的问题就只有一个,Python如何保持HTTP长连接,并能不断的收取数据包?
嗯,我知道你会想到的urllib2。 这也是我的第一反应。不过可惜的是urllib2并不提供保持长连接的办法。直接用recv、read这些系统调用监听fd? 我知道你是一个不怕麻烦不惧艰险的人。可我并不像你。经过一番google和stackoverflow的查询之后我得到了一个好东西——urlgrabber。不过在这篇文章里我不打算舍本逐末的去介绍urlgrabber的使用细节。而且我也没有详细的研究过它。不过经过我的测试,urlgrabber确实能很好的处理长连接HTTP的消息接收。所以我强烈的推荐这种方式而不是去用更底层的TCP连接API。
使用方法也很简单:
import urllib2
from urlgrabber.keepalive import HTTPHandler
keepalive_handler = HTTPHandler()
opener = urllib2.build_opener(keepalive_handler)
urllib2.install_opener(opener)
f = urllib2.urlopen('http://www.python.org')
然后你就能像读一个文件一样从HTTP连接中源源不断的读出数据来了。不过值得注意的一点是,这个文件打开的是阻塞式的IO。阻塞式IO在python中的处理和libc中不太一样。假如一个连接没有关闭且是阻塞式的,在python中你无法一次读到当前已收到所有数据。解决的方法有: 1 改成非阻塞。 2 每次读一个字节,直到读到一个完整数据包的结束。
很遗憾的告诉大家,在时间不充裕的情况下,方法1我没能成功。而keepalive的HTTP发送来的数据,每一段数据都是有规律的。比如标准的HTTP trunked的数据的开始总是会告诉你这一次会发送多少个字节,然后你读相应的字节数就可以了。而微信的message API在每一个数据包的最后都会出现\r\n。凭这个规律,我们足以判断出是否收完一个数据包了。
大概的代码如下,仅用来说明我的思路:
while True:
sPkg += f.read(1)
if sPkg.endswith('\r\n'):
#package over
sPkg = ''
嗯,这是第二个进程。收取微信的消息。
然后剩下的工作就是需要把消息发给微信用户了。当然你不能保证每次发送的消息都是成功的。因此我利用数据库做了一个消息队列。实现起来非常简单,就是每次从数据库中获取10条待发的消息发送。发送成功的消息在数据库中标记发送成功,以保证不会重复发送。发送不成功消息,在数据库中将发送次数增加1,这样这条消息会在下一次出队列时继续发送,直到发送的次数达到一个阈值。这是第三个进程。
不过现在微信的open message api还没有对外公开发布,不好更多的透露更多技术细节了。有兴趣的可以和我联系。我的邮箱是xxb.sklse@gmail.com。 在此处留言也可以。只是觉得有了这个API大家可以做出一些更多有意思的东西,比如电子商务网站可以通过这个来做到免费的订单到达的提醒。 甚至餐饮店可以利用微信免费点餐。呵呵。这个微信API早晚会发布,算我做了一点广告吧。
作者:希望
链接:https://www.pythonheidong.com/blog/article/77986/e69fed6efd4340877af3/
来源:python黑洞网
任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任
昵称:
评论内容:(最多支持255个字符)
---无人问津也好,技不如人也罢,你都要试着安静下来,去做自己该做的事,而不是让内心的烦躁、焦虑,坏掉你本来就不多的热情和定力
Copyright © 2018-2021 python黑洞网 All Rights Reserved 版权所有,并保留所有权利。 京ICP备18063182号-1
投诉与举报,广告合作请联系vgs_info@163.com或QQ3083709327
免责声明:网站文章均由用户上传,仅供读者学习交流使用,禁止用做商业用途。若文章涉及色情,反动,侵权等违法信息,请向我们举报,一经核实我们会立即删除!