智能体刷屏的背后,是 AI 应用拐点的来临?AICon 北京站议程重磅公布,50+ 硬核分享不容错过 了解详情
写点什么

桌面版应用程序的前世今生

  • 2019-11-04
  • 本文字数:3479 字

    阅读完需:约 11 分钟

桌面版应用程序的前世今生

互联网出现之前,C/S 架构是软件产品的主流,后面渐渐地被 B/S 架构所取代(因为不需要配置客户端),但由于浏览器有刷新机制,服务器的负载等因素,C/S 架构的响应速度和流畅性是好于 B/S 架构的,所以现在软件开发的趋势是两者的融合,一般是 B/S 架构开发的产品可以非常方便地转移到 C/S 架构下。客户端(client)是 C/S 架构软件产品中重要的一部分,除了和用户交互、本地处理数据的强大功能,顺畅的体验和美观的样式也是客户端技术追求的目标。这里和大家介绍桌面版应用程序的一些历史和现在比较流行的 electron 技术。

桌面版应用程序历史

桌面应用程序,又称为 GUI 程序。可以分为以下几个阶段:


  • VB,上古程序员的开发工具,曾经全球第一的开发语言,拖拽式的图形化开发让它成为极佳的桌面开发工具。微软依靠其操作系统的优势,一直压制同时期的竞争对手 delphi。微策略早期应用该技术,开发了管理智能商务平台的大杀器 developer。

  • C++、win32API 的 MFC 方案是基于窗口中组合控件和消息传递机制。这也是 20 多年前的技术,所以 API 设计的不是很友好。几年前微软已经停止维护,简单来说它已经过时了。

  • Winform 微策略几年前基于该技术研发第一代的 Desktop 版本,但是从开发体验角度来说自定义、美化控件会比较麻烦。

  • C# .net framework,代表就是 WPF,它的原生特性是其他类库无法比拟的:High DPI、Split Screen 以及对 DirectX 的天然优势。但是并不开源,需要依赖.net 框架,还有就是启动会比较慢。Workstation Windows 的新客户端就是基于该技术研发。

  • Java swing/javaFx,这是一类比较大的阵营,优势是跨平台和流行开发语言 Java 的天然结合,但开发出来的界面作者个人认为并不美观。

  • C++ Qt,这是很多客户端跨平台的首选,因为开源、UI 库和各种功能的类库非常丰富,但是学习成本比较高。

  • C++ duilib,这是 windows 下开源的 directUI(微软提出的分离 UI 和逻辑的思想)库,它是迎合互联网桌面软件小而美的趋势发展起来的,可能大家对它的关注度比较少。但是用它开发出的产品大名鼎鼎,比如 QQ、微信、爱奇艺等很多知名度高的软件。

  • Objective-c/swift cocoa,这是 mac 平台下的方案。可以方便调用底层的 API,缺点是不跨平台,文档不友好,UI 库并不丰富。现在这种方式开发的越来越少了。

基于 Web 技术的桌面应用开发

从 B/S 和 C/S 架构逐渐融合的角度来说,基于 Web 技术进行桌面程序的开发渐渐变成了主流。因为对界面的代码部分可以做到复用。


这类技术早期的方案是用 vb 内嵌 webBrowser 控件,基于 IE 内核,正好很多网页开发也有用 activeX 的需求,但这种方式具有明显的缺陷——非常依赖于用户的环境,会因为组件缺失导致程序各种崩溃。第二类是嵌入式网页框架,这类技术主要是基于浏览器引擎实现 UI 渲染。比较典型的就是 appkit 上面 UIWebView 和 CEF(chro-mium embeded framework)。这种方法可以使用网页 HTML5+CSS 实现各种酷炫的效果,但是缺点也比较明显,就是桌面程序里面嵌入了一个类似 Chrome 的浏览器,内存的开销会比较大。


后面出现了 nwjs 和 electron,electron 相比 CEF 有了单独执行 js 的 v8 引擎,可以运行 NodeJS 来完成服务器端功能,通过和内部浏览器的 v8 引擎交互可以实现一个独立的客户端,这不同于 CEF 需要寄宿在其他程序内部。

Electron


用 Electron 来做桌面程序开发的优势明显,相当于是完全的网页编程,有 Web 开发经验的前端开发上手非常容易。Web 开发生态广泛,开发成本低,可扩展性强,一些流行的前端框架例如 React、Angular、Vue 都可以和 electron 结合进行开发。另外它也具备和 Qt 一样跨平台的优良特性。对性能要求不高的桌面版程序来说,一份代码同时得到网页版和各个平台的桌面版,开发的效率是其他方案无法比的。可以说,这是大部分人看好的趋势。

和 Web 开发的区别

前端开发的一个痛点就是经常需要考虑多种浏览器之间的兼容,但是使用 electron 开发则不存在这样的问题,它只需要考虑 electron 中对应 Chrome 的版本。另一个使用 electron 解决的痛点是跨域,它可以绕过客户端直接通过 NodeJS 里的 request 通信模块发出请求,这样就无需被跨域所困扰。

扩展能力

node-ffi 可以在 NodeJS 环境中调用动态链接库接口。通过这种方式,我们可以把 JavaScript 方法映射到动态链接库接口,从而实现 C++ 类库的接入。

Electron 运行原理


Electron 的运行机制可以从两种进程说起:主进程和渲染进程。运行 package.json 的称为主进程,它可以负责创建渲染进程(多个)。下图是一段主进程代码,主进程负责创建一个浏览器实例来加载网页。每个创建的浏览器实例都在它自己的渲染进程内返回一个 Web 页面。当 BrowserWindow 实例销毁时,相应的渲染进程也会终止。主进程负责掌管所有的 Web 页面和它们相应的渲染进程。每个渲染进程都是相互独立的,它们只关心自己所运行的 Web 页面。


const electron = require('electron');const app = electron.app;const BrowserWindow = electron.BrowserWindow;
var window = null;
app.on('ready', function() { window = new BrowserWindow({width: 800, height: 600}); window.loadURL('https://microstrategy.com');});
复制代码


主进程还负责应用程序的生命周期(app 打开退出)和一些 app 事件的监听,同时负责系统底层 API 的调用。创建的渲染进程用来展示 HTML + CSS 技术编写的 Web 页面, 同时可以运行 JavaScript 实现交互,可以把渲染进程简单理解为 Chrome 上打开的一个浏览器进程。


<html>  <body>  <script>    const remote = require('electron').remote;    console.log(remote.app.getVersion());  </script>  </body></html>
复制代码


在渲染进程中是不允许调用原生 GUI 相关的 API,那是因为在网页中掌管原生 GUI 很危险,易造成内存泄露。如果你想在网页中进行 GUI 的操作,渲染进程必须向主进程传达请求,然后在主进程中完成操作。


Electron 封装了一系列自己的 API 可供主进程和渲染进程调用。可以通过如下方式获取:


const {app, BrowserWindow, ipcMain, ... } = require('electron'); // 仅主进程可用const {ipcRender, remote, ... } = require('electron'); // 仅渲染进程可用
复制代码


主进程和渲染进程均可直接调用 NodeJS 的 API:


node1.addEventListener('click', () => {   console.log(os.path.basename('xxxx');})
复制代码

进程通信

渲染进程如何向主进程发送消息

通信本质上基于 nodeJS 的事件基础类 Event-Emitter,ipcMain 和 ipcRender 都是该类的实例,通过事件模型需要的接口方法,采用了发布 / 订阅的方式来发送和监听消息。


异步方式:


import { ipcRender } from 'electron'; // 在渲染进程引入 ipcRender,它是 EventEmitter 的一个实例ipcRender.send('async', 'I am from webview'); // 可以异步发送
复制代码


同步方式:


import { ipcRender } from 'electron'; // 在渲染进程引入 ipcRenderipcRender.sendSync('sync', 'I am sync sent from webview'); // 同步方式
复制代码


通过同步方式发送会 block 整个渲染进程,直到主进程响应。


主进程会加载 ipcMain 来进行监听。


import { ipcMain } from 'electron'; // 在主进程引入 ipcMainipcMain.on('async', (event, info) {    console.log(info);});
复制代码


除此以外, electron 还提供了一种简单的方案(remote 模块)来实现渲染进程和主进程的通信。这样就可以不必显示地发送消息。


import { remote } from 'electron'; // 在渲染进程引入 remoteremote.mainProcessObject.invokeMethod(); // 调用主进程才有的方法});
复制代码

主进程如何向渲染进程发送消息

主进程通过找到渲染进程对应的 browserWindow 就可以发送消息。


constant window = BrowserWindow.fromId(global.id); // 通过 id 来进行对应window.webContents.send('msg', 'hello world');
复制代码


渲染进程监听:


ipcRender.on('msg', (event, info) => {    console.log(info)});
复制代码

渲染进程之间共享数据

一种可行的方案是在主进程实现消息的转发。还有比较简单的方案是通过浏览器实现的 HTML API,比如 localStorage, sessionStorage 或者 IndexedDB,或者通过主进程创建全局变量 sharedObject 来实现渲染进程的数据共享。


以上是一些 electron 技术的初步介绍,有兴趣的读者可以继续阅读详细的官方文档来深入学习。目前来看 electron 不能算一个年轻的开源项目, 还有不少新的桌面替代技术在涌现(比如 miniblink)。


作者介绍:


徐瑞青,高级软件工程师,毕业于鲁汶大学电子工程系。2014 年加入微策略,目前在数据 gateway 部门参与数据建模、清洗的开发工作,也参与过 Workstation 数据导入的早期开发。


本文转载自微信公众号:微策略 商业智能


2019-11-04 19:194264

评论 2 条评论

发布
用户头像
管理智能商务平台的大杀器 developer是什么东西?Java的话,RCP更流行吧?
2019-11-04 20:08
回复
没有更多了
发现更多内容

HIVE3 深度剖析 (上篇)

明哥的IT随笔

大数据 hie

当.Net撞上BI可视化,这3种“套路”你必须知道

葡萄城技术团队

看板 数据大屏 BI数据分析

CountDownLatch、CyclicBarrier和Semaphore区别及底层原理

爱好编程进阶

Java 程序员 后端开发

ansible 模块:add_host

ghostwritten

ansible

hive踩过的小坑

爱好编程进阶

Java 程序员 后端开发

无形资产管理系统解决方案

低代码小观

资产管理 CRM 财务审核系统 CRM系统 企业管理软件

Apache DolphinScheduler 2.X保姆级源码解析,中国移动工程师揭秘服务调度启动全流程

白鲸开源

Apache 大数据 开源 DolphinScheduler workflow

IntelliJ IDEA开发最佳配置

爱好编程进阶

Java 程序员 后端开发

IO流详细解答,博主亲自手敲代码,快速上手

爱好编程进阶

Java 程序员 后端开发

“银行家算法”大揭秘!在前端表格中利用自定义公式实现“四舍六入五成双”

葡萄城技术团队

银行家算法 纯前端表格技术

基于 FFI 的 PyFlink 下一代 Python 运行时介绍

Apache Flink

大数据 flink 编程 流计算 实时计算

拿起手中的键盘做公益侠客,让你的第一个低代码应用为公益发光发热!

InfoQ写作社区官方

低代码 公益 大学生 热门活动 码上公益

容器化 | 构建 RadonDB MySQL 集群监控平台

RadonDB

MySQL 数据库 容器化 RadonDB KubeSphere

AIRIOT物联网低代码平台如何配置MQTT驱动?

AIRIOT

物联网 低代码平台 驱动配置

Cloud-借助消息队列解决分布式事务

爱好编程进阶

Java 程序员 后端开发

Day346&347&348&349

爱好编程进阶

程序员 后端开发

ansible 模块:set_fact

ghostwritten

ansible

萌新看过来,你还学不懂VScode插件吗?

葡萄城技术团队

报表

还在写SQL做SAP二开?通过RFC调用NetWeaver,让HANA数据库操作更可靠

葡萄城技术团队

ERP 全套信息化系统 二开

ansible template jinja2 渲染

ghostwritten

ansible

「码」力集结!他们用作品为FinClip黑客松打造出一道靓丽的风景线

Speedoooo

小程序 hackathon 黑客马拉松 黑客松 小程序容器

Day274

爱好编程进阶

Java 程序员 后端开发

企业文档爆炸,如何管?

小炮

企业文档管理工具

ansible 模块:blockinfile

ghostwritten

ansible

Day177

爱好编程进阶

Java 程序员 后端开发

idea启动tomcat报错,org

爱好编程进阶

Java 程序员 后端开发

Hugging Face创始人亲述:一个GitHub史上增长最快的AI项目

OneFlow

人工智能 深度学习 nlp 开源社区

docker下kibana搭建

爱好编程进阶

Java 程序员 后端开发

Eclipse中查看源代码

爱好编程进阶

Java 程序员 后端开发

ansible 模块:script

ghostwritten

ansible

美哭了,一款开发者必备的接口管理工具!

Liam

Postman 开发工具 API API接口管理 接口管理工具

桌面版应用程序的前世今生_大前端_徐瑞青_InfoQ精选文章