用Web技术开发桌面应用 OneRing项目介绍 One ring to rule them all, one ring to find them, One ring to bring them all and in the darkness bind them.
Jan 15, 2015
用Web技术开发桌面应用OneRing项目介绍
One ring to rule them all, one ring to find them,One ring to bring them all and in the darkness bind them.
OneRingOneRing是一个跨平台的桌面应用开发库,使用HTML5+CSS3制作用户界面,用Javascript编写交互逻辑,同时提供用写web后端的技术编写后台逻辑。
http://code.google.com/p/onering-desktop/License: LGPL
又一个AIR / Silverlight / XUL Runner?
Yes(只)支持用HTML+CSS+JS制作界面
No支持和操作系统的直接交互支持本地代码调用无sandbox
又一个MFC / GTK+ / Qt / wxWidgets?
Yes通过Javascript API封装系统调用
No无Control、Event等概念
界面全部交由HTML+CSS+JS实现
又一个webOS / Chrome OS?
No是库,不是操作系统
解释无力上demo
为什么做OneRing?希望用web技术来开发桌面应用
Web技术
浏览器
服务器HTTP
HTML CSS JS
设计迭代:1
浏览器
服务器HTTP
HTML CSS JS
App Launcher
监听本地端口打开默认浏览器
问题非本地应用体验
设计迭代:2
封装浏览器
服务器HTTP
HTML CSS JS
App Launcher
监听本地端口包含系统原生浏览器(IE)的自定义窗口
问题IE6 must DIE!
设计迭代:3
WebKit
服务器HTTP
HTML CSS JS
App Launcher
监听本地端口包含WebKit的自定义窗口
问题需要访问系统API
设计迭代:4
WebKit
服务器HTTP
HTML CSS JS
App Launcher
监听本地端口包含WebKit的自定义窗口
onering.js
问题防火墙 annoying
设计迭代:5
WebKit
服务call
backfunction call
HTML CSS JS
App Launcher
包含WebKit的自定义窗口
onering.js
注册callback
代码示例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")
JavaScript
OS App Backend
onering.js ajax/pubsub
三组件通信
多语言支持C API DLL
C API
typedef void (*onering_app_func_t) ( const char* method, const char* path, const char* body, /*OUT*/ const char** response, int* response_len);
int onering_register_app(const char* appname, onering_app_func_t app_func);
int onering_loop(const char* appname);
Python Binding
register_wsgi_app(appname, wsgiapp)
loop(appname)
当前实现基于QtWebKit
Dispatch Url To App Backend
GET onering://myapp/test↓ (via NetworkAccessManager)
app_func = registered_app_funcs.lookup("myapp");app_func("GET", "/test", NULL, &response, &response_len);
onering.jsframe->addToJavaScriptWindowObject("_OneRing", jsapi)
ONERING.Window.prototype.hide = function() { return _OneRing.Window_hide();}
onering.js Is Served By An OneRing App
onering://onering/onering.js
onering.js Is Served By An OneRing App
onering://onering/onering.js
void onering_app(const char* method, const char* path, const char* body, const char **response, int *response_len){ if (strcmp(method, "GET") == 0 && strcmp(path, "/onering.js") == 0) { *response = onering_js.constData(); *response_len = onering_js.size(); } else { // TODO: 404 *response = ""; *response_len = 0; }}
展望
Native GUI
RIA
Web OSHTML5
展望
Native GUI
RIA
Web OSHTML5
OneRing
Join USC++ / Qt / WebKit / Javascript / Python / Documenter /
User / Tester / Code Reviewerhttp://code.google.com/p/onering-desktop/