(English) A New year starts and this one will be the year of Google Wave. In this new post we talk about what we expect about Google Wave and everything related.
1.在本地debug或者run你的机器人程序,去http://localhost:8080/_wave/capabilities.xml (或者其他你指定端口号 port number),你应该看见机器人的
功能设置capabilities.xml 文件。
2. 在本地debug或者run你的机器人程序,去 http://localhost:8080/_wave/robot/jsonrpc 你应该看见网页显示 Error: HTTP method GET is not supported by this URL.
如果不是这样的话,你的设置肯定有问题,请检查。
This website uses IntenseDebate comments, but they are not currently loaded because either your browser doesn't support JavaScript, or they didn't load fast enough.
开发你第一个谷歌浪波机器人
这篇文章我们将介绍如何用Eclipse 集成开发环境开发一个简单的Java谷歌浪波机器人。
当前,只能把浪波机器人部使用任何与google app engine兼容的JVM(Java虚拟机)语言,比如Groovy,JRuby,Scala。这篇文章只涉及Java。
这篇文章是基于谷歌官方机器人开发的文章。
开发和测试浪波机器人的要求:
Java 6 http://java.sun.com/javase/downloads/index.jsp
谷歌机器人Java 库(lib) http://code.google.com/p/wave-robot-java-client/downloads/list
Eclipse http://www.eclipse.org/
谷歌Eclipse插件 http://code.google.com/eclipse/
Google App engine 帐户 https://appengine.google.com
谷歌浪波帐户 http://wave.google.com/
注意: 这篇文章, 我将使用 Eclipse3.4 (Ganymede), 但是谷歌也有对于Galileo的插件。所以应该没有大的区别。
第一步:安装谷歌插件:
在 Eclipse里面, 点击 “Help” -> “Software Updates…”, 然后在跳出的窗口中点击“Add Site” in the popup window,在location里面输入 http://dl.google.com/eclipse/plugin/3.4,点击安装 Google Update Site for Eclipse 3.4 (包括 Plugin 和 SDKs) . (if 如果你使用的是 Galileo 那么安装地址 update location 就应该是 http://dl.google.com/eclipse/plugin/3.5 )
在接受 使用协议(the term of use), 插件和谷歌app engine 开发包SDK 就开始安装,如果安装成功, Eclipse 会要求重启, 点击 ok后,安装完毕。
现在,我们可以开始开发了。
第二步:创建项目:
点击(图)创建一个新的“Web Application project” by click the icon in the toolbar.
1. 给项目一个名字, 比如: first-Robot
2. 给项目的包 package 一个名字, (可选,但是一个好习惯 ), 比如 com.onthetopofthewave
3. 反选 (uncheck)“Use Google Web Toolkit”, 因为我们的机器人不会有任何用户界面。请确保“Use Google App Engine“是选上的 ,写这篇文章时 google App engine SDK Java的版本是 1.2.6
4. 点击“Finish”
Project Overview
图一.1 项目结构
你项目的结构应该和上图相似。
第三步 引入(Import) 库(libraries)
到http://code.google.com/p/wave-robot-java-client/downloads/list , 下载所有的 jar 文件。

把它们拖拽到你Eclipse IDE中项目的war/WEB-INF/lib 目录里,引入完毕后,你的war/WEB-INF/lib应该像图二。
图二 2 库Libraries
然后,右击你的项目,点Properties(项目属性),在属性窗口中,选择“Java Build Path”, 点击“Libraries” 标签(tab),然后点击 Add JARS;加入那些在你war/WEB-INF/lib 目录下的JARs。之后,仍然在属性窗口( Properties Window)中,选择“Google”, 选择 “Web Application”, 点击 “Add” 右边的按钮,加入那些新的JARs。点击“OK” 来关闭属性窗口。
第四步 开发机器人Servlet
在你的项目的包中,新建一个类(class),叫“FirstRobot” , 它继承 AbstractRobotServlet 类 (位于 com.google.wave.api 包)。这类名说明了它是个 servlet, 它能接受HTTP 请求。 (在谷歌浪波wave中, 几乎所有的请求都是POST)。在运行时( runtime),机器人所在服务器 (现在就是google app engine)会创建这个类的例子来处理该机器人参与的所有浪波(wave)的事件(比如 wavelet里面新的信息,新的用户被加入wavelet中)。这就是浪波机器人如何去和一个浪波(wave)中的其他参与者(包括其他机器人)的一个方法:回应事件(respone event)。另一个方法安排CRON工作(cron job),机器人会执行那些提前安排好的工作。目前浪波机器人就这么两种和其他参与者的交流方式。
AbstractRobotServlet 是一个抽象类,我们必须实现它的processEvent(RobotMessageBundle bundle) 方法。这个方法会在机器人接受到新事件(一个或多个)时被调用,这个方法需要一个参数 RobotMessageBundle (在 com.google.wave.api.RobotMessageBundle), 它是一个接口
(interface)代表了一个或多个事件的所有相关信息。目前只有一个类实现该接口:RobotMessageBundleImpl.
作为一个 hello world 级别的简单例子,我们的机器人只准备实现很简单的功能:发送信息,和其他参与者打招呼。下面是代码,让我们一步一步解释这代码。
package com.onthetopofthewave;
import com.google.wave.api.AbstractRobotServlet; import com.google.wave.api.Blip; import com.google.wave.api.Event; import com.google.wave.api.EventType; import com.google.wave.api.RobotMessageBundle; import com.google.wave.api.TextView; import com.google.wave.api.Wavelet; public class FirstRobot extends AbstractRobotServlet { private static final long serialVersionUID = 1L; @Override public void processEvents(RobotMessageBundle bundle) { Wavelet wavelet = bundle.getWavelet(); // send a pre-define message when the robot is added to a wave if(bundle.wasSelfAdded()){ Blip blip = wavelet.appendBlip(); TextView textView = blip.getDocument(); textView.append("I'm a robot from onthetopofthewave.com"); } // greet when participants change for (Event e: bundle.getEvents()){ if(e.getType() == EventType.WAVELET_PARTICIPANTS_CHANGED) { Blip blip = wavelet.appendBlip(); TextView textView = blip.getDocument(); textView.append("Hi everybody!"); } } }在第17行, Wavelet wavelet = bundle.getWavelet();
这句代码,我们获得机器人所接受到事 件(bundle)所在wavelet。如果你对wavelet的概念不太熟悉,在一个浪波(wave)中,有一个公共对话,也有可能有部分参与者之间私 人对话,wavelet就是保证这些对话隐私性的机制:一个wave至少有一个wavelet代表公共对话,私人对话由另外一个wavvelet来代表。 每一个wave和wavlet都有一个string代表的ID。
下一行的 bundle.wasSelfAdded()方法,是查这个机器人是否是被刚加入到这个wavelet中。我觉得这个方法应该起一个更好的名字,比如justAdded()。
如 果机器人刚被加入,我们想它去发送信息。首先,我们要加上一个新的blip在wavelet中。一个Blip是对话中的一个小单元(我们这个情况就是一个 信息)。wavelet中的Blip是存储成 树结构。树中的每一个结点(一个Blip)可能有一个父结点和多个子结点。(一个回应其他blip的blip,就是前者的子结点)。每一个Blip也有一 个String ID,Blip可以被删除。当一个blip被删除,它所有的子结点。Blip还包括一些元信息(metadata)来记录作者和版本号。
Blip blip = wavelet.appendBlip();
上面这句话,就在当前wavelet上追加一个Blip。
TextView textView = blip.getDocument();
getDocument 方法会返回 该blip的文件内容 (TextView类 位于 com.google.wave.api 包)。 该文件可以包含文本信息,XHTML(string),和非文本内容 (Element类 位于 com.google.wave.api 包)。
textView.append(“I’m a robot from onthetopofthewave.com”);
这行代码就是在文档末端加上一句话。我们的机器人的第二功能就是当wavelet中的参与者变化时,和大家打招呼。
如何察觉参与者变化那,我们需要读取 RobotMessageBudle 里面的信息。
bundle.getEvents()
这方法返回一个这个包(bunlde)中所有的事件,是以 列(List)的数据结构呈现。该列中至少有一个事件,所以我们遍历(iterate )一遍这个列,查看每一个事件的类型 (type:
e.getType()
这个方法返回事件的类型(EventType 枚举Enum 位于 com.google.wave.api 包) 。 EventType 是一个Java枚举, 它包含了下列事件类型:
BLIP_CONTRIBUTORS_CHANGED
Blip作者变化
BLIP_DELETED
Blip 被删除
BLIP_TIMESTAMP_CHANGED
Blip的最近修改日期变化
BLIP_VERSION_CHANGED
Blip’s 的版本变化
DOCUMENT_CHANGED
Blip的文档变化
FORM_BUTTON_CLICKED
Blip中表格的按钮被点击了
WAVELET_BLIP_CREATED
一个新 blip 在这个wavelet被创建了
WAVELET_BLIP_REMOVED
一个Wavelet中有Blip被删除了
WAVELET_PARTICIPANTS_CHANGED
wavelet的参与者发生了变化
WAVELET_SELF_ADDED
机器人被加入到新的wavelet中了
WAVELET_SELF_REMOVED
机器人从wavelet中被删除了
WAVELET_TIMESTAMP_CHANGED
Wavelet最新修改时间变化
WAVELET_TITLE_CHANGED
Wavelet的题目变化
WAVELET_VERSION_CHANGED
Wavelet的版本变化
可 以看出一些事件紧密相关。比如如果一个 blip 被删除, the BLIP_DELETED, WAVELET_BLIP_REMOVED, WAVELET_TIMESTAMP_CHANGED, WAVELET_VERSION_CHANGE 事件将会被触发。
除了事件类型,Event接口还包括其他相关信息,比如新加的,或者刚被删除的参与者的电子邮件地址,新的标题名字,等等。
对于我们的列子,我们只关心wavelet参与者的变化( EventType.WAVELET_PARTICIPANTS_CHANGED).
如果这事件发生,我们新建一个Blip,在文档最后加入问候的信息。
第5步。配置机器人
部署之前,我们的机器人需要一些XML来设置,就如其他Java EE程序。
首先, 在 war/WEB-INF.web.xml 文件, 我们需要把 /_wave/robot/jsonrpc/ URL 和我们的机器人servlet.
< ?xml version=”1.0″ encoding=”utf-8″?>
< xmlns=”http://java.sun.com/xml/ns/javaee“
xmlns:web=”http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd“
xsi:schemaLocation=”http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd” version=”2.5″>
<servlet>
<servlet-name>robot</servlet-name>
<servlet-class>com.onthetopofthewave.FirstRobot</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>robot</servlet-name>
<url-pattern>/_wave/robot/jsonrpc</url-pattern>
</servlet-mapping>
</web-app>
从这个xml里面,你可以看出 /_wave/robot/jsonrpc 是浪波机器人的交流URL。
除了web.xml, 我们还需要另外一个备置文件。在war目录下,新建一个目录名叫 _wave, 在这个目录里新建一个XML文件,叫 capabilities.xml ,该文件包括如下内容:
<?xml version=”1.0″ encoding=”utf-8″?>
<w:robot xmlns:w=”http://wave.google.com/extensions/robots/1.0″>
<w:version>1</w:version>
<w:capabilities>
<w:capability name=”WAVELET_PARTICIPANTS_CHANGED” content=”true” />
<w:capability name=”WAVELET_SELF_ADDED” content=”true” />
</w:capabilities>
<w:profile name=”onthetopofthewaveRobot”/>
</w:robot>
在这XML里面,我们引入了google wave robot 的namespace, http://wave.google.com/extensions/robots/1.0, 然后我们指出了这个机器人的能力 (capabilities)WAVELET_PARTICIPANTS_CHANGED,WAVELET_SELF_ADDED. 不要忘记写content=”true”。这个文件就是告诉浪波服务器WAVELET_PARTICIPANTS_CHANGED 或者 WAVELET_SELF_ADDED 事件发生时,给这个机器人在/_wave/robot/jsonrpc URL发送信息包
(bundle)。
还有其他重要事件:
WAVELET_BLIP_CREATED (wavelet中新建blip)
WAVELET_TITLE_CHANGED (wavelet的题目变化)
BLIP_CONTRIBUTORS_CHANGED(Blip作者改变)
BLIP_DELETED (Blip被删除)
BLIP_SUBMITTED (Blip被发送)
DOCUMENT_CHANGED (文档被改变)
当然,你的机器人有越多的能力,越多的信息包 bundles机器人会接受。 作为一个google app engine程序,流量和帐单总是一个问题
STEP 6. 部署
你需要给你的机器人一个google app engine程序ID( application ID)。
到 https://appengine.google.com/ 点击“create an application”新建一个程序, 复制你新建程序的名字(那个唯一的程序名称就是 the application ID)
右击你的项目, 选择Properties, 在 Properties窗口, 选择 “Google” > App Engine,输入你的your application ID 。
现在点击“Deploy to App engine” 按钮, 输入你的谷歌帐号电子邮件地址和密码, Eclipse会编译的项目,然后把war目录下的内容上传到 App Engine.
图三。机器人截图
第七步. 测试
登陆你的谷歌浪波,把你的机器人加为联系人,它的地址应该是它的 application ID 加上 appspot.com。比如ontopwaverobot@appspot.com。在你加载完毕之后,新建一个浪波把你的机器人加入其中,结果应该和上图相似。
机器人版本 Robot Versioning
在你第一上传之后,你每次修改capabilities.xml 文件,都需要更新你的你机器人的版本号(不是你google app engine 程序本身的版本号)。
<?xml version=”1.0″ encoding=”utf-8″?>
<w:robot xmlns:w=”http://wave.google.com/extensions/robots/1.0″>
<w:version>1</w:version>
<w:capabilities>
<w:capability name=”WAVELET_PARTICIPANTS_CHANGED” content=”true” />
<w:capability name=”WAVELET_SELF_ADDED” content=”true” />
</w:capabilities>
<w:profile name=”onthetopofthewaveRobot”/>
把1改成大点的数字: 1.1 , 1.2。这样 浪波服务器就不会再存储(cache) 你机器人的旧版本了。
常见错误:
目前阶段,测试机器人很麻烦,你必须把它们部署到google app engine,然后检查,你不能在本地测试机器人的功能。
但是,还是有些东西可以在本地测试
1.在本地debug或者run你的机器人程序,去http://localhost:8080/_wave/capabilities.xml (或者其他你指定端口号 port number),你应该看见机器人的
功能设置capabilities.xml 文件。
2. 在本地debug或者run你的机器人程序,去 http://localhost:8080/_wave/robot/jsonrpc 你应该看见网页显示 Error: HTTP method GET is not supported by this URL.
如果不是这样的话,你的设置肯定有问题,请检查。
如果一切正常,把程序上传到google app engine.
然后去点击
http://applicationID.appspot.com/_wave/capabilities.xml
http://applicaitonID.appspot.com/_wave/robot/jsonrpc
它们应该和在本地测试时结果一样。
另外一个debug的地方就是你的google app engine dashboard,登录你的 app engine 帐号, 查看你的机器人程序的日志 log. 你可以在那里看HTTP请求的记录。
谢谢阅读,希望这篇文章对你开发机器人和了解java版google wave api有帮助。
置于浪波之上! Stay onthetopofthewave!
标签: 开发, eclipse, featured, java, robot, 浪波开发机器人, sdk, 浪波机器人
If you like what you see, please, support us:
Posts that may be of your interest: