背景
在项目实施的过程中, 经常需要调用一些本地程序 (DLL,EXE 或 OCX), 常用的方法就是将本地程序封装成 OCX 插件, 在本地电脑安装注册, 然后使用 JavaScript 进行调用, 然而这种方案主要存在几个问题:
本地程序质量参差不齐, 频繁的无响应或者崩溃导致浏览器卡死或崩溃, 极大的降低了用户的体验
高版本的 Chrome 和 Firefox 已经不再支持插件, 为保证插件的调用只能固定浏览器版本
丧失了 BS 技术产品集中部署, 随处运行, 工程实施以及产品更新更加方便的优势
对于不同的本地程序, 均需要封装为 OCX 插件, 对于 Java 程序员来说略显为难, 更不用说封装过程中容易出现的内存泄露问题
问题分析
为解决浏览器调用本地程序过程耦合过于紧密的问题, 需要提供一个解决方案替代之前调用插件的方式, 改进要求大致有三点:
本地程序无论是无响应或者卡死崩溃, 不能影响浏览器的正常运行
不能使用高版本浏览器已经弃用的 OCX 插件
不需要对本地程序做二次封装注册, 能够做到拿来就用最好
综合起来看, 第一点是迫切需要改善的, 用户直接使用的对象是我们系统, 因为一个操作点导致用户浏览器频繁的崩溃, 然后重新登录, 很容易引起用户的反感, 而且这是个扯皮的事情, 涉及到其他厂商, 想找到问题也比较复杂.
技术思考
为了降低耦合度, 考虑是在客户端电脑安装一个中间层程序, 浏览器通过中间层程序调用本地程序. 客户端电脑的中间层程序作为 http 服务运行, 浏览器通过 http 请求的方式调用中间层程序, 中间层程序根据 http 请求参数来确定需要调用的本地程序, 动态调用后返回结果给浏览器.
浏览器和本地程序之间增加一个 http 的中间层, 有以下优点:
全版本浏览器支持, 不用考虑浏览器差异
http 可以设置同步请求或者异步请求, 可以根据场景来设置不同的请求类型
http 可以设置超时时间, 如果本地程序迟迟没有返回, 超过时间可以认为此次调用失败
浏览器和厂商插件程序彻底解耦, 只需要保证中间层程序的可用性, 就完全抛开外部程序的制约, 恢复了 BS 程序应有的优势
存在问题
中间层程序运行模式
1, 中间层程序在客户端电脑作为 Windows services 服务运行, 这样的话可以利用 Windows 的功能设置开机自启动, 错误重启等, 方便管理, 能够保证中间层程序的高可用. 然而之后发现在调用有界面的插件时存在 session0 隔离的问题, 虽然有办法能够绕过 session0 的隔离, 但是有些 Windows 的环境变量会出现问题.
2, 中间层程序作为开机自启动的后台程序运行, 开机启动的后台程序不存在 session0 隔离的问题, 但是无法使用 Windows 服务的开机自启动, 错误重启等, 中间层程序的可用性需要自己来保证.
中间层程序的可用性保障
1, 中间层程序设置为开机自启动
2, 客户端电脑增加一个守护进程程序, 对中间层程序进行心跳检测, 定时检查中间层程序有没有开启
3, 浏览器调用中间层程序失败, 触发守护进程启动中间层程序
总结
通过以上方案主要是实现了本地程序和浏览器解耦, 可以实现一个统一的技术方案兼容多种情况的需求, 而且能够充分利用中间层进行 Windows API 的调用, 实现本地文件的安全可控读写及上传下载.
然而这种方案还是存在缺陷, 因为此方案的目标是浏览器和本地程序的解耦, 对于需要嵌入浏览器并且需要进行界面操作的本地程序就无法友好的实现, 通过中间层只能调起程序, 而无法嵌入浏览器.
虽然本文中的这种方案, 可以实现浏览器和本地程序的动态调用, 但是如果可能的话, 尽量不要使用, 将数据的交互方式更改为 http,webservice 等技术方案更为妥当, 毕竟随着技术的发展, 类似插件的本地程序都将会被淘汰掉, 云服务模式才是未来.
本文思路的实现方案: WebRunLocal 中间层程序 https://github.com/wrxiang/WebRunLocal
来源: http://www.bubuko.com/infodetail-3810749.html