Mais conteúdo relacionado Semelhante a 基于XMPP的Gtalk机器人 (20) 基于XMPP的Gtalk机器人1. 基于 XMPP 的 Gtalk 机器人 [email_address] 2010.9.4 2. 缘起: 1, 手动更新测试仓库的 SVN 给同事用 2, 在 BlackBerry 上快速访问服务器 给自己用 3, 安排菜谱,讲笑话 给媳妇用 ;) 6. XMPP :原名 Jabber eXtensible Messaging Presence Protocol 可扩展的消息状态协议 用于 Gtalk 就是基于 XMPP 协议,并对协议进行了扩充 Google Wave 也是,虽然“出师未捷身先死” Orz 延伸阅读 http://knb.im/67y 7. XMPP 的架构? 简单来说,就是 Client-Server , Server-Server 一个分散型的通信网络哦 复杂来说, $%^&#*#$ 9. 出发之前的一些基础: JID : XMPP 的 client 端和 server 端统称为 XMPP 实体,用 JID 作为一个全局唯一的标识符。 格式为: node@domain/resource zhoo.xuan@ngosoft.com/xxxx 就是我了 -_- 13. 出发之前的一些基础: xmpp stanza : xmpp 节。是以 xml 表达的最小的信息项,每个 stanza 都有以下的公共属性: from: 源 xmpp 实体的 JID to: 目标 xmpp 实体的 JID id: 这次对话的可选标识符 type: stanza 的可选子类型 15. import xmpp jid = xmpp.JID('bot@gmail.com/python') message = xmpp.Message('say something') presence = xmpp.Presence('I'm at NGOsoft.com ') iq = xmpp.Iq() 对象简单明了,开工 ~ 16. 问题一,该如何让我的 bot 登录呢? jid = 'bot@gmail.com' pwd = 'password' jid_instance = xmpp.JID(jid) cl = xmpp.client(jid_instance.getDomain(), debug[] ) cl.connect() cl.auth(jid_instance.getNode(), pwd) 17. 问题二,该如何让我的 bot 持续在线? status = xmpp.Presence(status=' 小萝莉 ') cl.sendInitPresence() cl.send(status) while 1: cl.Process(1) send 函数可以用来发送三种类型的内容 18. 问题三,如何给 bot 注册 handler ? cl.RegisterHandler('message', message_handler) cl.RegisterHandler('presence', presence_handler) cl.RegisterHandler('iq', iq_handler) 一旦 bot 收到这三种类型的内容,就交由响应的 handler 函数来处理。 19. 问题四,如何让 bot 处理添加好友的请求? 所谓的添加好友,其实就是两个实体的互相”订阅“。 此信息为 presence 类型: cl.send(xmpp.Presence(to='xx@xx.xx', typ=' subscribe ')) cl.send(xmpp.Presence(to='xx@xx.xx', typ=' subscribed ')) 20. 问题五,如何让 bot 处理我们发给她的信息? 发给 bot 的信息 ===> 要传递的指令 因此要先把这些指令和发送者提取出来 def message_handler(self, conn, mess): who = mess.getFrom() content = mess.getBody() 处理 content ,获得 cmd 和 arguments if cmd in commands: cmd_xxx(arguments) #commands 为命令列表 #cmd_xxx 为命令函数 23. 出现了一个问题: 选择执行 cmd_xxx() 函数的时候,由于 xxx 是一个可变化的值,改如何实现? 解决方法:使用 commands[xxx]() 来做函数的选择。 commands={'xxx':func, ...} 可是,如何能动态的生成 commands{ } ? 24. 解决办法:定义一个 register_commands() 的函数,让其在 __init__() 中执行,动态的检测 class 中存在的 cmd_xxx 函数,并给 commands 赋值。 def register_commands(self): self.commands={} for name, value in inspect.getmembers(self): if inspect.ismethod(value) and getattr(value, '_is_method', Falsa): self.commands[name] = value 25. 并且,我们并不在每个 cmd_ 函数中设置 "_is_command" 属性,而是使用 @ 修饰符来加工 cmd_ 函数,为其设置属性。 def botcommands(*args): func = args[0] setattr(func, '_is_command', True) return func @botcommands def cmd_xxx(): 26. def bootcommands(*args): func = args[0] setattr(func, '_is_command', True) return func 使用修饰符函数,来建立我们的 commands system 28. 到目前为止,我们自己的 bot 小框架就算是完成了,粗略回顾一下: client-->connect-->auth-->register_handler verify_request-->presence_handler-->log message-->message_handler-->cmd_xx-->log 添加新的 cmd 功能: @botcommands() def cmd_xx(): Perfect ;) 30. bot 的雏形搞完了,可最初的功能还没实现呢 ~~ 目前只写了两个 cmd_ 函数 cmd_help 打印帮助信息 cmd_server 基于 xmpp 来控制服务器 cmd_work 与 server 类同,都是在 server 端执行命令,只是要用脚本配合罢了 但是给媳妇用的 cmd_eat 和 cmd_joy 还没想好如何来实现,是从网上抓数据,还是用本地的数据库呢? Orz 31. 问题 & 讨论 推荐: http://xmpppy.sourceforge.net http://code.google.com/p/pygtalkrobot/ http://www.ibm.com/developerworks/cn/xml/tutorials/x-realtimeXMPPtut/index.html Notas do Editor 只有 client 认证通过后,才就可以注册 handler 只有 client 认证通过后,才就可以注册 handler 只有 client 认证通过后,才就可以注册 handler 不是手动的添加 commans{} 的元素 只有 client 认证通过后,才就可以注册 handler 只有 client 认证通过后,才就可以注册 handler xmpp 的实时性没有讨论 xmpp 在游戏中的作用 xmpp 的