My favorites | Sign in
Project Home Downloads Wiki Issues Source
Search
for
OneRing  
OneRing设计介绍
Updated Sep 20, 2010 by hongqn

桌面应用框架 OneRing

框架目标

OneRing是一个跨平台的桌面应用框架。和Adobe AIR类似,它支持用html/js/css制作用户界面,与之不同的是,它的应用为本地程序,可以直接访问操作系统的数据。

架构

一个OneRing应用程序分为两个部分:框架部分和应用部分。

框架部分

框架部分为通用框架,各应用都一样。其提供各操作系统上的界面展现,为本地窗口内嵌一个WebKit浏览器,并提供一致的js接口让应用和操作系统功能进行交互。

框架以运行时库的形式提供。

框架以系统原生语言编写,提供其他语言的绑定。

应用部分

应用部分为一个web server,负责应用逻辑,用html/css描述界面,用js提供用户交互。

运行流程

  1. 应用启动时,会加载框架的运行时库,注册应用url的访问方法(如WSGI),并调用框架的loop函数。
  2. loop函数会访问应用的 /init URL,得到一个json数据,描述初始应用窗口的相关参数,如位置、大小、窗口属性、初始页面url等。
  3. 框架根据该数据创建窗口,并让该窗口内的浏览器访问初始页面url,渲染用户界面,然后等待UI事件。
  4. 用户在界面上操作时,可以通过超链接改变整个窗口内容,也可以使用AJAX技术更新窗口内部分内容。
  5. 应用可以让浏览器调用ONERING名字空间下的js函数,和操作系统进行交互,该名字空间由url onering://onering/onering.js 加载。
  6. 应用通过 bind(event, function) 函数监听窗口更改大小、移动等操作系统UI事件。
  7. 可以使用pub/sub机制主动推送消息给浏览器。
  8. 调用 ONERING.exit() 可以退出应用;所有窗口都关闭后也会退出应用。

Python应用示例

#!/usr/bin/env python
import json
import web
import onering

urls = (
    '/init', 'init',
    '/', 'index',
)

class init:
    def GET(self):
        web.header('Content-Type', 'application/json')
        return json.dumps({'width': 400, 'height': 300, 'url': '/'})

class index:
    def GET(self):
        web.header('Content-Type', 'text/html')
        return """<html>
<head><script type="text/javascript" src="onering://onering/onering.js"></script></head>
<body>
<p>Hello, world!</p>
<button onclick="javascript:ONERING.exit()">Exit</button>
</body></html>"""

app = web.application(urls, globals())

if __name__ == '__main__':
    onering.register_wsgi_app("demo", app.wsgifunc())
    onering.loop("demo")

各组件之间的交互

一个OneRing应用中,存在三个需要互相通讯的组件:

  1. 操作系统 OS ,控制窗口行为(如最小化窗口),及操作系统相关界面元素(如系统通知图标)
  2. 运行在WebKit内的javascript,控制界面内元素(如程序界面里的按钮)
  3. WSGI应用,控制HTML/JS的生成逻辑,以及应用相关的后台逻辑

js -> os

当js需要通知os对js所在窗口做某个行为(如最小化),通过调用 onering.js 中的get_current_window()返回值(为Window对象)的相应方法实现:

var current_window = ONERING.get_current_window();
current_window.minimize();

当js需要os执行整个应用层面的操作时(如结束应用),通过调用 onering.js 中的函数实现:

ONERING.exit();

当js需要os创建一个新窗口时,通过调用createWindow函数实现,并获得新建窗体的句柄实例:

new_window = ONERING.createWindow('/a_dialog', 400, 300);

当js需要向另一个窗口做某个os行为时(如隐藏另一个窗口),通过调用窗体的句柄实例的方法实现:

new_window.hide();

os -> js

js可以通过bind机制,关注操作系统发生的时间(如窗口大小改变):

current_window.bind('resize', function(event) {
    if (event.width < 300) {
        $('#sidebar').hide();
    }
});

js -> app

js可以通过类AJAX调用,从app获取数据。

ONERING.getJSON('/userdata.json', function(data) {
    ...
});

app -> js

app希望向窗体内的js主动推送消息时,可以采用pub/sub机制。

首先js通知框架自己关注的事件:

current_window.subscribe("a_file_scanned", function(fileinfo) {
  ...
});

然后当app希望发送消息时,调用onering框架提供的publish方法:

for fileinfo in scan_files():
    onering.publish("a_file_scanned", fileinfo);

其中的fileinfo为可以转化为JSON的python对象(即 json.dumps(fileinfo) 不会抛出异常)。

Comment by iWinux, Sep 20, 2010

好像很好玩...可是...Python 的GUI原本就挺迟钝的,用这种方式的话会不会更慢 = =...

Comment by yzhr...@gmail.com, Sep 20, 2010

这种想法已经在一个手机操作系统上实现了,它叫做:webOS

Comment by linjunhalida, Sep 20, 2010

用户拖拽界面的速度顶多是10毫秒级别的, 完全够了.

Comment by jhuangjiahua@gmail.com, Sep 20, 2010

@iWinux 迟钝的是 PyWx? 这个特例吧,

PyGtk? 很快的。

Comment by project member hongqn, Sep 20, 2010

OneRing的GUI是用WebKit?实现的,所以它的GUI响应速度取决于WebKit?的渲染和Javascript执行速度。

Comment by project member richie...@gmail.com, Sep 20, 2010

webOS和这个目标至少应该不同。 OneRing不是为了做一个OS,而是一个跨OS的应用开发平台

Comment by guye999, Sep 21, 2010

webkit内核运行javascript的速度已经相当快了,印象中曾看过一个图,比python和PHP还要快。

Comment by superpow...@gmail.com, Sep 22, 2010

有个问题,如果还要Python的binding的华似乎失去了作为一个Native的应用引擎的意义,8M多的打包下载再加上Python就很大了,还不如XULRunner了,那个打包差不多10M到11M的样子,用WebKit?的引擎不错,这样HTML5就能侵入桌面端了 希望这个东西能够减肥到5M左右,纯Native的就绝对霸道了

Comment by project member hongqn, Sep 22, 2010

OneRing本身的设计是跨语言的,只是目前的demo是用的python。

在我们的实测中,占发布包体积最大的还是WebKit?和Qt依赖库,Python运行时环境占的比例并不大。希望有对软件瘦身比较了解的朋友能加入进来,共同研究缩小发布包的方法。

Comment by renwofei...@gmail.com, Sep 24, 2010

非常支持这个!以前就想过开发这样个平台,没想到豆瓣已经做了! 试试!

Comment by project member hongqn, Sep 24, 2010

@renwofei423 来一起做吧 :)

Comment by sz83800...@gmail.com, Sep 26, 2010

2楼说中了。

刚看了一下palm的webos,就是这个概念。

Comment by dexter.yy, Oct 10, 2010

架构跟nodejs很类似,为何不实现CommonJS API,利用现有的大量js modules http://wiki.commonjs.org/wiki/CommonJS http://wiki.github.com/ry/node

Comment by project member hongqn, Oct 10, 2010

@dexter.yy 感谢建议。什么地方有用CommonJS API做桌面GUI程序的文档或者demo吗?

Comment by dexter.yy, Oct 11, 2010

firefox新的扩展开发架构Jetpack SDK:https://jetpack.mozillalabs.com/sdk/0.8/docs/#guide/packaging

我已经用它开发过一个GUI的自动化测试工具了

P.S.上一贴里module的链接帖错了…… http://github.com/ry/node/wiki/modules

Comment by project member hongqn, Oct 13, 2010

@dexter.yy 已经创建 issue 25 。如果你有什么实现上的想法(比如模块如何划分等),欢迎在 issue 25 下讨论。 :)

Comment by guolin.mobi, Jan 5, 2011

这个库没有持久化支持吧? HTML 写界面,JS 写逻辑,就是缺了数据持久化。 是打算使用 HTML5 的 webdatabase ?也有可能是基于豆瓣的产品形态,无需考虑持久化?

Comment by project member hongqn, Jan 5, 2011

OneRing本身通过HTML5提供持久化支持,例子可以见 demo 中的 Local Storage http://code.google.com/p/onering-desktop/source/browse/demo/templates/localstorage.html

HTML5提供了Key-Value和SQL两种持久化方式,如果还需要其他的持久化方式,可以利用OneRing提供的ajax方法把数据提交给app,由app的本地代码完成持久化(如直接写文件系统)。

Comment by Remember...@gmail.com, Feb 15, 2011

hi,如果需要进入本地文件系统进行读写,该如何?

Comment by project member hongqn, Feb 16, 2011

可以在app中读写本地文件系统,用OneRing提供的类ajax方法或call_app方法与app交互。

Comment by dugugu...@gmail.com, Apr 13, 2011

qt实在是太大了,为啥不考虑用小一点的库呐。

Comment by wonderbe...@gmail.com, Aug 29, 2011

听上去很美!

Comment by jiangjia...@gmail.com, Sep 21, 2011

不发展了吗?能不能借鉴titanium desktop的 kroll,把和python的交互透明化

Comment by eddyt...@gmail.com, Oct 2, 2011

win8好像有这样的开发方法

Comment by dongwei...@126.com, Oct 9, 2011

very good

Comment by androi...@hotmail.com, Dec 11, 2011

hongqn有没考虑过用chromium embedded代替qtwebkit呢

Comment by Richie.F...@gmail.com, Feb 10, 2012

有类似的想法,也是做类似的框架,不过目前是希望从chromium入手

Comment by consa...@gmail.com, Feb 29, 2012

记得chrome可以自行编译的吧?? 记得听某个兄弟说过,他们开发的项目要求客户一定要安装他们自行编译的Chrome 如果把Chrome的地址栏和按钮图标等一切不相关的都屏蔽掉,然后自己开发插件来进行OS->JS、JS->OS的部分(记得Chrome支持Native Code),是否可行呢??

Comment by cnJamesD...@gmail.com, May 13, 2012

webOS的庫,現在已經獨立出來的enyojs不是已經做得很好了?你們的與它區別在哪?


Sign in to add a comment
Powered by Google Project Hosting