浏览器调用本地程序的一些想法

背景

在项目实施的过程中,经常需要调用一些本地程序(DLL,EXE或OCX),常用的方法就是将本地程序封装成OCX插件,在本地电脑安装注册,然后使用JavaScript进行调用,然而这种方案主要存在几个问题:

  1. 本地程序质量参差不齐,频繁的无响应或者崩溃导致浏览器卡死或崩溃,极大的降低了用户的体验
  2. 高版本的Chrome和FireFox已经不再支持插件,为保证插件的调用只能固定浏览器版本
  3. 丧失了BS技术产品集中部署,随处运行,工程实施以及产品更新更加方便的优势
  4. 对于不同的本地程序,均需要封装为OCX插件,对于Java程序员来说略显为难,更不用说封装过程中容易出现的内存泄露问题

问题分析

为解决浏览器调用本地程序过程耦合过于紧密的问题,需要提供一个解决方案替代之前调用插件的方式,改进要求大致有三点:

  1. 本地程序无论是无响应或者卡死崩溃,不能影响浏览器的正常运行
  2. 不能使用高版本浏览器已经弃用的OCX插件
  3. 不需要对本地程序做二次封装注册,能够做到拿来就用最好

综合起来看,第一点是迫切需要改善的,用户直接使用的对象是我们系统,因为一个操作点导致用户浏览器频繁的崩溃,然后重新登录,很容易引起用户的反感,而且这是个扯皮的事情,涉及到其他厂商,想找到问题也比较复杂。

技术思考

任何软件工程遇到的问题都可以通过增加一个中间层来解决,考虑是在客户端电脑安装一个中间层程序,浏览器通过中间层程序调用本地程序。

浏览器和中间层程序的交互可以使用socket、http、webservice或者websoket等通讯协议,这样不局限于浏览器调用,我们的后端服务也可以调用客户端电脑上的本地程序。

对于通讯协议的选择,首先是要简单高效,最好是浏览器端和后端服务都能进行使用,这样的话http和websoket就是剩下的最佳选择,二者之间如何选择见仁见智,

http的优点可以设置同步或者异步请求以及设置请求的超时时间,针对于不同的使用场景设置不同的请求类型,有时会更灵活一些,而缺点就是http是无状态的通讯协议,很难做到双向交互,而且如果系统是部署在互联网环境中后端获取不到客户端ip无法调用,只能在前端浏览器调用。

websocket是全双工的异步通讯协议,双向交互很简单就可以实现,而且不需要通过ip的形式进行通讯,但是缺点是异步回调,这种方式在业务代码中会更复杂一些,甚至会破坏已有的代码结构。

小孩子才做选择题,成年人当然是全都要!开发客户端中间层程序其实有很多选择,无论是Java、C#、Node或者Python等流行的语言,创建一个http或者websocket服务简直不要太简单,

客户端电脑的中间层程序作为http或者websocket服务运行,浏览器通过http或websocket请求的方式调用中间层程序,中间层程序根据请求参数来确定需要调用的本地程序,动态调用后返回结果给浏览器。

遇到的问题

中间层程序运行模式

1、中间层程序在客户端电脑作为Windows services服务运行,这样的话可以利用windows的功能设置开机自启动,错误重启等,方便管理,能够保证中间层程序的高可用。然而之后发现在调用有界面的插件时存在session0隔离的问题,虽然有办法能够绕过session0的隔离,但是有些windows的环境变量会出现问题。
2、中间层程序作为开机自启动的后台程序运行,开机启动的后台程序不存在session0隔离的问题,但是无法使用windows服务的开机自启动,错误重启等,中间层程序的可用性需要自己来保证。
3. 需要设置防火墙允许程序或者端口通过,否则后端无法访问客户端程序,如果只是前端调用无所谓

中间层程序的可用性保障

1、中间层程序设置为开机自启动
2、客户端电脑增加一个守护进程程序,对中间层程序进行心跳检测,定时检查中间层程序有没有开启
3、浏览器调用中间层程序失败,触发守护进程启动中间层程序

总结

通过以上方案主要是实现了本地程序和浏览器解耦,可以实现一个统一的技术方案兼容多种情况的需求,而且能够充分利用中间层进行windows API的调用,实现本地文件的安全可控读写及上传下载。

然而这种方案还是存在缺陷,因为此方案的目标是浏览器和本地程序的解耦,对于需要嵌入浏览器并且需要进行界面操作的本地程序就无法友好的实现,通过中间层只能调起程序,而无法嵌入浏览器,比如某些程序提供的视频播放功能会无法嵌入浏览器导致用户体验度降低,对于这种场景可以让插件悬浮在浏览器的某个位置,前端监听浏览器的缩放、关闭、刷新、下拉等事件并将事件触发给客户端中间层,让悬浮的插件做出相应的动作,可以给用户组件是嵌入在浏览器的操作体验。

虽然本文中的这种方案,可以实现浏览器和本地程序的动态调用,但是如果可能的话,尽量不要使用,将数据的交互方式更改为http、webservice等技术方案更为妥当,毕竟随着技术的发展,类似插件的本地程序都将会被淘汰掉,云服务模式才是未来。

本文思路的实现方案:WebRunLocal中间层程序

posted @ 2021-08-17 12:26  ~鲨鱼辣椒~  阅读(1236)  评论(0)    收藏  举报