我不得不重新从头开始实现现有系统。
在一个点上,当用户导航到特定网页的服务器必须读取用户的串口数据。
目前,该网页有一个ActiveX控件; 当页面加载ActiveX控件的调用到用户PC上的COM DLL从串口读取数据。
该系统为10岁。 有没有“更好”的方式,我可以实现这一点?
举例来说,技术在过去十年继续前进。 而这种解决办法似乎只有在微软IE浏览器,目前拥有约26%的市场份额(它有,在2013年,当我上次更新了这个问题。工作作为2107年2月的,微软IE浏览器拥有3-4%和边缘有1-2%为边缘也是MS的产品,它可以支持Active X的-我还没有尝试过OTOH,因为它是新的从地上爬起来,有一个很好的机会,事实并非如此)。
难道HTML 5提供任何新的可能性? 怎么样的产品,如科尔多瓦 ?
是否有任何其他的可能性?
我可以添加一个树莓派做了串口和阅读并让浏览器的应用程序与通过RESTful服务沟通?
[更新] @ EuroMicelli说:“我要去假设你有一个很好的理由来运行从Web浏览器您的应用程序,而不是本机应用程序”。 我不知道,因为我不在身边时,原项目计划(并把它设计公司现在已经不存在)。
也许他们不想让最终用户直接与数据库交互? 也许,“基于浏览器”是一个新名词回来呢? 我个人有一个桌面应用程序没有问题(因为我觉得他们更容易实现),但也许我们基于应该考虑剩余的浏览器? (此外,我可以处理桌面应用自己;它是从COM端口仅基于浏览器的阅读,导致我提供奖金;-)
Answer 1:
仅举另一个(更像是“网络的-东西”)选项:外部硬件。
根据不同的使用情况,您可以使用一个外部低成本的设备,如嵌入式PC一个Arduino微控制器或覆盆子-PI。
这不是很困难时,这些类型的设备来构建一个简单的串行到网络服务的桥梁。 你可以使用一些项目,像这样如: https://code.google.com/p/serwebproxy/
在这种情况下所有低层次的东西是由外部硬件来处理,并通过类似的界面web服务(通过GET / POST),提供给你。
另一个优点是,个人电脑,在那里你运行应用程序,并不需要一个串行端口(其变得相当罕见的在某些系统上)。
从您的浏览器应用程序,你可以用一个简单的Ajax调用查询嵌入式设备上的网络服务。 该浏览器将不需要任何插件可言,该解决方案能跨plattform是从浏览器的技术,在不久的将来开发通用的,独立的。
Answer 2:
可以肯定一件事,你将永远无法无需安装一些特殊的二进制文件与本地计算机硬件进行通信(并以适当的权限运行的话)在本地计算机上。 然而,这并不意味着你需要需要使用ActiveX组件,并保持停留在Internet Explorer。 当然,你也可以开发一个组件在市场的每一个浏览器。
我建议另一种方法:
- 写一个Windows服务(我假设你的机器运行的是Windows),具有必要的权限配置。 你将不得不反正安装在机器上的东西。 该服务可以在任何语言来实现。
- 添加HTTP(S)服务器功能吧。 你可以在这里使用了大量的技术,从WCF到的WebAPI。
- 发明通过HTTP自己的通信协议。 你可以使用JSON,AJAX的WebSockets,SignalR等。
- 编写JavaScript文件,该文件将与市场上大多数的浏览器兼容 - 所以你只需要编写,一旦 - 这将成为你的串行COM API。 你可以支持Javascript和Ajax功能(所有浏览器的XmlHttpRequest ),只有一个代码库。
下面是它会是什么样子:
Answer 3:
为了尽量减少客户机上的外部库或插件的需求,我会写一个Java小程序 。
摘要 (包括链接到大多数文件,你需要做到这一点):
- 确保您的客户端已经安装了Java( 大多数人已经 ,如果没有,浏览器可以安装)(这是唯一的安装,你可能需要从你的一些客户的要求对这种做法)
- 挑选一个不需要任何外部安装一个Java串行端口库,像PureJavaComm
- 写一个非常简单的Java小程序 ,它提供的公共方法做串口读取
- 登录您的小程序 ,以便它被授予必要的系统访问权限
- 包括小程序在你的网页,并简单地直接从JavaScript调用的公共方法
更多细节:
据StatOwl ,所有机器的约三分之二所需的Java框架已经安装了,所以你可能甚至需要向客户提供任何额外的基础设施。 如果你这样做,至少你问一个( 大部分 )保持良好的软件,人们知道并不会太怀疑。 而且,大多数浏览器应该有提示用户自动安装Java框架,如果它缺少的能力。
还有,你可以在Java中使用它来访问串口几个不同的库。 PureJavaComm似乎是为数不多的,虽然,不需要外部代码运行。 具体而言,在Windows上,他们WinAPI的 Java类为您提供了COM端口,包括他们所有的设置只使用到已经安装了Windows库调用的直接访问。 由于PureJavaComm是一个纯Java的库,你可以在一个.jar文件小程序,该浏览器自动下载打包,因此没有安装。
然后,你可以写一个最小的Java小程序(可能只有约50-100线总),它定义的公共方法做你需要的串行端口访问,你可以很容易从JavaScript直接调用: 调用Applet的方法从JavaScript代码
你需要确保的唯一的事情是,你签上你的小应用程序和你包在你的串行端口代码doPrivileged的(...)调用,以便将被授予由JVM沙箱中所需的系统访问。 对于这一点,你可以得到一个购买SSL证书(你可能已经有您的服务使用HTTPS),或生成自己的保持。 如果你生成你自己的,用户将被提示,是否要信任你的小程序,但他们可以选择“始终信任”,所以它只是一个一次性的复选框 - 和OK键单击。 但除此之外,这应该是一个完全透明的解决方案,最大限度地减少对用户体验的影响。
选择1:
另一种选择是,简单干脆直接使用你的网站沟Web的界面,而是提供了一个Java程序,用户可以轻松地运行(有或没有安装它) JNLP(Java Web Start的) 。
方案2(很有可能仅适用于Windows):
我猜你也可以使用微软的Silverlight ,这也似乎相当广泛部署 :
使用Silverlight 5(COM端口)的串行通信
有些人可能会认为它比Java小程序的“现代”,但它可能是跨平台的少。
它也似乎更多地参与了一下,从JavaScript调用您的Silverlight代码,但它是可能的:
制作的Silverlight编写脚本由JavaScript
Answer 4:
可能不是。
我会假设你有一个很好的理由来运行从Web浏览器您的应用程序,而不是本机应用程序。 我能想到的几个场景在那里我可以看到,作为一个合理的业务决策。
即使在今天,拥有各种现代化的进步,Web浏览器仍然是看中了交互式文档浏览器,而不是普遍的运行环境。 即使是最前沿的功能,比如WebSockets的引入,使复杂的客户端 - 服务器通信,而不是因为一些普遍的兴趣有朝一日能够从浏览器中做的一切。
可能有一些特殊的环境,这是本机可能(做Chrome操作系统?),但它不会是一个通用的解决方案。 没有现存或建议的标准,我知道通过浏览器标签或脚本来打开串行端口。 这意味着你将需要一些相当低级别的插件技术如ActiveX的。 ActiveX是一个很好的解决方案,如果你是好与IE仅支持,特别是如果它已经书面和它的作品。
大多数人希望从浏览器串行端口的访问可能正在做数据采集一些专有的硬件,他们指定(建造/出售?)和控制,如实验室设备,条码扫描仪,科学仪器等,我觉得在这一点上它也完全可以接受的指定所需的浏览器为好。 专门的应用程序通常这样做。
如果你还是想看看更广泛的浏览器支持,尝试寻找在这个问题提出的解决方案: 使用的Adobe Flash串行端口交换 。 我没有对该产品的经验,但如果它的工作原理它应该使大多数浏览器做你想要一个单一的代码库做什么,那就是如你可以希望。
无论你最终做起来,它肯定会涉及某种形式的第三方插件。
Answer 5:
你可以使用网络USB - 但浏览器的兼容性是(目前)非常低 - 铬61似乎是它。
这种方法的主要好处是,将USB设备插入到浏览器的机器。 显然,这适用于Android版Chrome 64和(未测试)。
该API是在https://wicg.github.io/webusb/ 。
对于一个教程,请参阅https://developers.google.com/web/updates/2016/03/access-usb-devices-on-the-web 。
Answer 6:
通过使用节点JS通过一个串口包作为服务器是一个选项。 这适用于Windows,显然在Linux和OSX为好。 见https://github.com/node-serialport/node-serialport 。
这是我用来读取通过USB接口微型位通讯科到浏览器的解决方案。 我没有要重建与Windows(10)驱动程序:
- NPM安装--global - 生产Windows的构建工具
- NPM的serialport安装--build-从源
我已经粘贴下面一些参考我的代码:
const serialport = require('serialport')
// list serial ports:
const find_microbit = (error, success) => {
serialport.list((err, ports) => {
if (err) {
error(err)
} else {
let comName = null
ports.forEach((port) => {
if ((port.vendorId == '0D28') && (port.productId == '0204')) {
comName = port.comName
}
})
if (comName != null) {
success(comName)
} else {
error('Could not find micro:bit.')
}
}
})
}
exports.get_serial = (error, success) => {
find_microbit(error, (comName) => {
let serial = new serialport(comName, {baudRate: 115200, parser: serialport.parsers.readline('\n')}, (err) => {
if (err) {
error(err)
} else {
success(serial)
}
})
})
}
/* e.g.
get_serial((err)=>{console.log("Error:" + err)},
(serial)=>{
serial.on('data', (data) => {
let ubit = JSON.parse(data)
if (ubit.button == 'a') {
console.log('Button A Pressed')
}
if (ubit.button == 'b') {
console.log('Button B Pressed')
}
if (ubit.ir) {
console.log('Visitor detected')
}
})
})
*/
这种方法适用 - 我 - 但它可以是时间得到它的工作耗时。 这不,在我看来,一个明显的,或者简单的解决方案。 它需要技术诀窍相当数量的 - 而且,我觉得,更复杂和“棘手”比它应该是。
特别是 - 重新构建库,这并不是我所期望的使用节点JS什么时候做。 一种可能的影响是,你将需要重建串口二进制文件不同的平台。
文章来源: How can a web page read from the user's serial port - in the year 2017?