近几年互联网的一个发展重点是社交网站。Facebook、linkedin、开心网等这些社交网站在短时间内便聚集了巨量的用户数量、社交网络数据、应用数量和应用数据。在这些网站上,应用从设计之初就考虑了社交网络的存在。结果是优秀的应用和数据通过社交网络的病毒式传播得到更快的共享。开发人员从中得到启发,重新思考如何使用社交数据来重新设计应用,更好的实现协作;如何重新组织应用内容和数据,更好的分享;如何使用社交网络实现产品的营销等。越来越多的组织在考虑使用社交应用的形式来提供服务和数据。
随着社交网站的蓬勃发展,社交网站从最初的交友目的发展到了应用平台。不同的社交网站提出了私有的技术来构建社交网站应用。例如 Facebook 提供了私有的应用的定义,以及私有的访问 Facebook 社交网络数据的技术。
OpenSocial 和它的组件模型 OpenSocial Gadget
不同的社交网站向开发人员提供了不同的私有 API 来访问社交网站数据。这造成了开发人员的困惑,一个应用如果需要部署到多个社交网站,需要提供不同的实现。
OpenSocial 提供了统一的标准来定义社交网站的应用和访问社交网站的数据,提供了一个开放的解决方案:统一的 Gadget 应用模型和 Gadget 容器;统一的 OpenSocial API 来访问社交网站的数据;以及相应的兼容性测试工具。这里需要注意,Opensocial 组织提供相应标准和规范,但不提供实现方法。Apache 基金会的 Shindig 项目提供了 Opensocial 的参考实现。各大社交网站也在向 Opensocial 靠拢。如果一家社交网站支持 Opensocial 标准,则所有的 Opensocial Gadget 都可以运行在这家社交网站的网页上,这些 Gadget 都可以通过 Opensocial 定义的标准 JavaScript API 来访问该网站的社交网络数据,即使这些 Gadget 最初不是为这个网站所开发。
OpenSocial 标准通过观察社交网站的数据,抽取了基本的社交概念:Person、Relation、Activity、ActivityStreams[部分 OpenSocial 容器支持]、AppData、Gadget。OpenSocial 标准提供了统一的 API 来访问社交网站的数据:Person、Activity、ActivityStreams、AppData 数据。
Gadget 是一个独立的应用。它由一个特定格式的 XML 文件定义,这个 XML 文件中包含定义 Gadget 应用行为的 HTML、CSS、JavaScript 代码和图片、声音、视频等资源。HTML 可以用来展现内容。JavaScript 用于获取服务器数据,执行应用逻辑,动态修改展现内容。CSS 用来指定内容展现的样式。下面的例子(helloworld.xml)展示了 Gadget 基本的元素。
在这个例子中,开发人员可以看到定义 Gadget 行为的几个重要元素:
<?xml version="1.0" encoding="UTF-8" ?> <Module> <ModulePrefs title="Hello World!"> <Require feature="opensocial-0.8" /> </ModulePrefs> <Content type="html"> <![CDATA[ Hello, world! ]]> </Content> </Module> |
前面介绍了 OpenSocial 中的基本概念,这一节将介绍 OpenSocial 中如何通过 JavaScript API 来描述 Person、Activity、ActivityStreams、AppData 等社交网站概念。
OpenSocial 中的 JavaScript API 通过 Feature 来组织。每个 Feature 是一个可以单独加载的 JavaScript 模块。通过以下的语法,Gadget 可以声明加载某个 Feature。
<Require feature="xxx" /> |
opensocial.x 定义了 OpenSocial 中的实体。重要的实体有 Person、Activity、MediaItem、ActivityStream。opensocial.x 提供了 JavaScript API 来访问实体中的属性。
opensocial.Person | 表示社交网络中用户的概念。提供 API 读取用户的属性数据,获取用户相关的应用数据,判断用户的身份。 opensocial.Person.getField opensocial.Person.getDisplayName opensocial.Person.getAppData opensocial.Person.isOwner opensocial.Person.isViewer |
opensocial.Activity | 在 OpenSocial 中,表示 Activity 的概念。例如一次讨论就是一个 Activity。Activity 数据包括 Activity 标题和可选的 Activity 内容。 opensocial.Activity.getField opensocial.Activity.setField |
ActivityStreams [部分 OpenSocial 容器支持] |
ActivityStreams 是 ActivityStreamEntry 的聚集。简单的 ActivityStreamEntry 包括 Actor, verb 和 object,描述了 Actor 通过动作 verb 对 social object 的行为。ActivityStreams 包含的 ActivityStreamEntry 可以是不同类型。例如一篇文档,一个评论。您可以访问 ActivityStreams 的主页获取更多的信息 http://activitystrea.ms/ |
AppData | AppData 给 Gadget 应用提供了持久化数据的机制。AppData 是基于应用和用户的。不同的应用的 AppData 不同。同一应用,不同的用户,AppData 也不相同。 opensocial.DataRequest.newUpdatePersonAppDataRequest opensocial.DataRequest.newFetchPersonAppDataRequest opensocial.DataRequest.newRemovePersonAppDataRequest |
osapi.x 定义了针对 OpenSocial 中实体的操作。具体的操作有创建、读取、更新、删除(CRUD)。osapi.x 提供了 JavaScript API 来创建支持批处理的 Ajax 请求和创建操作 OpenSocial 中实体对象的数据请求。一次批处理的 Ajax 请求可以包括多个 OpenSocial 数据请求。
定义批处理的 Ajax 请求,支持在一个 Ajax 请求中包括多个 OpenSocial 数据请求。执行 Ajax 请求。例如一个 Ajax 请求中获取页面作者,登陆用户的 Person 数据,同时获取页面作者,登陆用户的 ActivityStreams 数据。 osapi.newBatch osapi.BatchRequest.add osapi.BatchRequest.execute |
构建获取用户数据的请求。例如获取页面作者,已登陆用户,页面作者的朋友,已登陆用户的朋友的 Person 数据。 osapi.people.get |
构建创建,读取,更新,删除 opensocial.Activity 的请求。例如读取页面作者的所有 opensocial.Activity。 osapi.activities.create osapi.activities.get osapi.activities.update osapi.activities.delete |
构建创建,读取,更新,删除 opensocial.ActivityStreamEntry 的请求。例如读取页面作者的 opensocial.ActivityStreams。 osapi.activitystreams.create osapi.activitystreams.get osapi.activitystreams.update osapi.activitystreams.delete |
构建创建,读取,更新,删除 opensocial App Data 的请求 osapi.appdata.create osapi.appdata.get osapi.appdata.update osapi.appdata.delete |
构建 HTTP GET, POST, PUT, DELETE, HEAD 请求。用于和第三方数据源交互。 osapi.http.get osapi.http.post osapi.http.put osapi.http.delete osapi.http.head |
gadget.x 定义了和 Gadget 实例相关的操作。
完整的 OpenSocial JavaScript API 可以参考 JavaScript API 参考手册。
测试:开发人员完成 Gadget 开发后,首先需要测试功能是否达到要求。iGoogle 提供了 Gadget Checker 工具来检查语法,并给出改进建议。
部署:必要的功能测试通过后,您可以把 Gadget 部署到任何支持 OpenSocial 的网站。支持 OpenSocial 的网站列表可以参考:http://wiki.opensocial.org/index.php?title=Main_Page#Container_Information。部署的主要步骤是:
具体的部署过程请参考每个网站的文档。
OpenSocial 版本:在部署过程中,开发人员需要注意 Gadget 所使用的 OpenSocial API 的版本。现在常用的版本有 V0.7, V0.8 和 V0.9。在部署前,请检查网站所支持的 OpenSocial API 的版本。开发人员也可以在 Gadget 定义文件中指定使用具体版本的 OpenSocial API。例如:
<Require feature="opensocial-0.8" /> |
代码保护:OpenSocial Gadget 部署后,它的源代码在互联网上是公开的。开发人员可以通过压缩工具来混淆 JavaScript/CSS 代码,以保护自己的产品。比较常用的工具有 YUI Compressor。您可以访问它的 主页 获取更多的信息。
如果您的网站支持 OpenSocial 标准,那您网站的页面就可以加载 OpenSocial Gadget。由于互联网上已经有大量优秀的 OpenSocial Gadget 应用可供使用,您的网站的内容质量很快可以得到提升。
Apache Shindig 子项目提供了 OpenSocial 标准的参考实现。通过与 Shindig 的集成,您的网站可以支持 OpenSocial 标准。您可以访问 Shindig 主页 获取更多的信息。
在 OpenSocial Gadget 示例一节中,本文给出了一个简单的 Gadget 例子来说明 Gadget 的结构和重要的语法元素,这个例子不涉及使用社交网站数据。下面本文给出一个通过 OpenSocial JavaScript API 来获取社交网站好友数据的例子。并把 Gadget 部署到多个支持 OpenSocial 的社交网站,达到一次实现,多次部署。
<?xml version="1.0" encoding="UTF-8"?> <Module> <ModulePrefs title="listfriends"> <Require feature="settitle"/> <Require feature="opensocial-0.8"/> <Require feature="dynamic-height" /> </ModulePrefs> <Content type="html"> <![CDATA[ <script type="text/javascript"> function loadFriends() { var req = opensocial.newDataRequest(); req.add(req.newFetchPersonRequest(opensocial.IdSpec.PersonId.VIEWER), 'viewer'); var viewerFriends = opensocial.newIdSpec({"userId":"VIEWER", "groupId":"FRIENDS"}); var opt_params = {}; opt_params[opensocial.DataRequest.PeopleRequestFields.MAX] = 100; req.add(req.newFetchPeopleRequest(viewerFriends, opt_params), 'viewerFriends'); req.send(onLoadFriends); } function onLoadFriends(data) { var viewer = data.get('viewer').getData(); var viewerFriends = data.get('viewerFriends').getData(); html = new Array(); html.push('<ul>'); viewerFriends.each(function(person) { if (person.getId()) { html.push('<li>', person.getDisplayName(), '</li>'); } }); html.push('</ul>'); document.getElementById('friends').innerHTML = html.join(''); gadgets.window.adjustHeight(); } function init() { gadgets.window.setTitle("Friends"); loadFriends(); } gadgets.util.registerOnLoadHandler(init); </script> <div id='main'> Your friends: <div id='friends'></div> </div> ]]> </Content> </Module> |
listfriends.xml Gadget 使用了 OpenSocial JavaScript API 来获取社交网站的好友数据,然后使用列表显示好友的名字。