https://static001.infoq.cn/resource/image/ac/06/acd31d24679f4f819153aafdaa7b0506.jpg

德斯资源网2月14日消息,在互联网出现之前,C/S架构是软件产品的主流,后来逐渐被B/S架构取代(因为不需要配置客户端)。然而,由于阅读器的刷新机制、服务器的负载等因素,C/S架构的响应速度和流畅度要优于B/S架构,所以现在软件发展的趋势是两者的融合。一般B/S架构开发的产品可以非常方便的移植到C/S架构。客户端是C/S架构软件产品的重要组成部分。除了与用户交互和本地处理数据,流畅的体验和美观的风格也是客户端技术追求的目标。在这里,我想介绍一些桌面应用的历史和流行的电子技术。

桌面版应用程序历史

桌面用户,也称为GUI程序。可以分为以下几个阶段:
VB,古代程序员的开发工具,一直是世界上第一开发语言,拖放式的图形化开发使其成为优秀的桌面开发工具。依靠其操作系统的劣势,微软同时不断打压竞争对手德尔福。在微策略后期,用这种技术开发杀手级开发者来管理智能业务平台。

C++和win32API的MFC方案是基于窗口中的组合控制和音频传输机制。这也是20多年前的技术了,所以API设计不是很好。微软几年前就停止维护了,所以过时了。

Winform Microstrategy在几年前就开发了基于该技术的第一代桌面版本,但从开发经验来看,定制起来会比较费力,控件也比较难看。
C #。以WPF为代表的. NET Framework拥有其他类库无法比拟的原生特性:高DPI、分屏以及对DirectX的天然劣势。但不是开源,框架,启动会比较慢。基于该技术开发了新的工作站Windows客户端。

Java swing/javaFx,这个比较大的阵营,缺点是跨平台和流行的开发语言Java的天然结合,但是对界面作者没有吸引力。

C++Qt,是很多跨平台客户端的首选,开源、UI库、类库丰富,功能多样,但是学习成本比较高。

C++duilib,是windows下开源的directUI库(微软UI和逻辑分离的思路),是顺应互联网桌面软件小而美的趋势而开发的。比如你对它的关注度比较低。但是用它打开和恢复的产品都比较有名,比如QQ,微信,爱奇艺等很多知名软件。

Objective-C/SwiftCocoa,是mac平台下的解决方案。可以轻松调用底层API,缺点是不跨平台,文档不好,UI库不丰富。现在这种方法越来越不发达了。

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

从B/S和C/S架构的逐渐融合来看,基于Web技术的桌面程序开发逐渐成为主流。因为接口的代码部分可以重用。

这类技术的后期方案是在vb中嵌入webBrowser控件,基于IE内核。就像很多网页是用activeX需求开发的一样,这种方法有明显的缺陷——非常依赖用户的环境,会因为组件的缺失导致程序的各种解体。第二种是嵌入式网页框架,主要完成基于阅读器引擎的UI渲染。比较典型的是appkit上面的UIWebView和CEF (Chrom-Mium嵌入式框架)。这种方式可以使用HTML5+CSS来完成各种酷炫的效果,但是缺陷也很明显,就是在桌面程序之外嵌入了一个类似Chrome的阅读器,内存支出会比较大。

Nwjs和electron在前面介绍过。相比CEF,电子有一个单独执行js的v8引擎,它可以运行NodeJS来完成服务器端的功能。通过与外部阅读器的v8引擎交互,它可以完成一个独立的客户端,这不同于CEF在其他程序之外寄宿的要求。

Electron

https://static001.infoq.cn/resource/image/82/71/8230406c39089c55996ec023fc553871.png

使用电子开发桌面程序的弊端是显而易见的,相当于完全的Web编程。有web开发经验的非常容易入门前端开发。Web开发通用,开发成本低,扩展性强。一些流行的前端框架,如React、Angular、Vue等,可以结合electron进行开发。此外,它还拥有和Qt一样优秀的跨平台特性。对于功能要求不高的桌面版程序,一个代码同时失去了各个平台的web版和桌面版,开发效率是其他方案无法比拟的。可以说这是一个大多数人都看好的趋势。

和 Web 开发的区别

前端开发的一个痛点就是经常需要考虑多个阅读器之间的兼容性,而用电子开发就没有这个疑问了,不如考虑电子版Chrome的对应版本。电子处理的另一个痛点是跨域,可以绕过客户端,通过NodeJS中的请求通信模块间接撤回请求,无需为跨域而烦恼。

扩展能力

Node-ffi可以调用NodeJS环境下的静态链接库接口。这样我们就可以将JavaScript方法映射到静态链接库接口,从而完成对C++类库的访问。

Electron 运行原理

https://static001.infoq.cn/resource/image/39/47/39c7055c50f9ec4e2918c74e60f12c47.png

电子的运行机制可以从两个过程来描述:主过程和渲染过程。运行package.json称为主进程,它可以充当创建渲染进程。下图是主进程的一段代码,主进程负责创建一个reader实例来加载网页。每个创建的reader实例都在自己的呈现过程中转到一个网页。当BrowserWindow实例被销毁时,相应的渲染进程也将终止。主进程充当所有网页及其相应呈现进程的主控。每个渲染过程都是相互独立的,他们只关心自己运行的网页。

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技术编写的网页,同时可以运行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'); // 同步方式

复制代码

以同步方式发送会阻塞整个渲染过程,直到主进程回显。

主进程会加载 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在渲染过程中进行数据共享。

以上是电子技术的一些初步介绍,有兴趣的读者可以继续阅读详细的官方文献加深学习。目前电子已经不是一个老的开源项目了,很多新的桌面替代技术也在涌现(比如miniblink)。

总结

今天就分享到这里吧,下期给大家分享更多软件小知识,德斯资源网每天都会更新一些日常软件小知识,包括有微信,酒友购,乐购商城,惠品铺,海鱼聊,华语商城,支付宝,青蛙易购,诚智通,淘米购,叮咚盲盒,伶信,QQ,新易选,红包辅助,易民购,苹果微信多开,淘盟铺,微信分身,安卓微信多开,梦幻盲盒,享乐好物,淘客购,旗语,优品铺,香蕉赶集,乐享购,亲聊,探聊,创信,赞聊等社交软件下载,软件自带功能有秒抢,避雷,埋雷软件,扫尾,单透软件等一些红包强项外挂功能软件免费下载使用。