我必须从头开始重新实现现有系统。
有一次,当用户导航到某个网页时,服务器必须从用户的串口读取数据。
目前,该网页有一个ActiveX控件;当页面加载时,ActiveX控件调用用户PC上的COM DLL,该DLL从串口读取数据。
该系统已有10年历史。有没有“更好”的方式可以实现这个?
例如,技术在过去十年中一直在发展。而这个解决方案似乎只适用于MS IE,它现在的市场份额约为26%(2013年,当我上次更新这个问题时。截至2107年2月,MS IE有3-4%而且Edge有由于Edge也是MS产品, 可能 支持Active X - 我没有尝试过.Otoh,因为它是从头开始的新产品,那里它不是一个很好的机会。
HTML 5是否提供了新的可能性?那些像Cordova这样的产品呢?
还有其他可能吗?
我可以添加一个Raspberry Pi来通过串口读取吗?并让浏览器应用程序通过RESTful服务与之通信?
[更新] @ EuroMicelli说:“我将假设您有充分的理由从网络浏览器而不是本机应用程序运行您的应用程序”。我不知道原来的项目计划时我不在身边(设计它的公司现在已经不存在了)。
也许他们不希望最终用户直接与数据库连接?也许“基于浏览器”当时是一个新的流行语?我个人对桌面应用程序没有任何问题(因为我发现它们更容易实现),但是我们应该考虑保留基于浏览器的? (此外,我可以自己处理桌面应用程序;它只是从COM端口读取浏览器,导致我提供奖金; - )
答案 0 :(得分:23)
有一点可以肯定,如果没有在本地计算机上安装一些特殊的二进制文件(并以适当的权限运行它),您将永远无法与本地计算机硬件进行通信。但是,这并不意味着您必须使用ActiveX组件并且仍然无法使用Internet Explorer。当然,您也可以为市场上的每个浏览器开发一个组件。
我建议采用另一种方法:
以下是它的样子:
答案 1 :(得分:10)
为了最大限度地减少客户端计算机上的外部库或插件要求,我会写一个 Java Applet 。
摘要 (包括实现此目标所需的大部分文档的链接) : < / p>
更多详情:
根据StatOwl,大约三分之二的计算机已经安装了所需的Java框架,因此您甚至可能不需要要求您的客户提供任何其他基础结构。如果你这样做,至少你要求一个(for the most part)维护良好的软件,人们知道并且不会过于怀疑。并且,大多数浏览器应该能够提示用户在缺少Java框架的情况下自动安装Java框架。
您可以在Java中使用几个不同的库来访问串行端口。 PureJavaComm似乎是少数几个不需要外部代码运行的人之一。具体来说,在Windows上,他们的WinAPI Java类使您可以直接访问COM端口,包括使用已安装的Windows库调用的所有设置。由于PureJavaComm是一个仅限Java的库,您可以将它与applet打包在一个.jar文件中,浏览器会自动将其下载,因此无需安装。
然后,您可以编写一个最小的Java Applet(可能只有大约50-100行),它定义了您需要的串行端口访问的公共方法,然后您可以直接从JavaScript直接调用:Invoking Applet Methods From JavaScript Code < / p>
您唯一需要确保的是sign your applet并且您将串行端口代码包装在doPrivileged(...)调用中,以便从JVM沙箱中获得所需的系统访问权限。为此,您可以获得已购买的SSL证书(如果您的服务使用https,您可能已拥有该证书)或生成您自己的证书。如果您生成自己的,则会提示用户,他们是否想要信任您的applet,但他们可以选择“始终信任”,因此它只是一次性复选框,然后单击确定。但除此之外,这应该是一个完全透明的解决方案,可以最大限度地减少对用户体验的影响。
备选方案1:
另一种选择是,简单地放弃网络界面,而是提供一个Java程序,用户可以使用JNLP (Java Web Start)直接从您的网站轻松运行(有或没有安装)。
备选方案2(仅限Windows):
我猜你也可以使用Microsoft Silverlight,这似乎也是fairly widely deployed:
Serial Communication with Silverlight 5 (COM port)
有些人可能认为它比Java Applet更“现代”,但它可能不那么跨平台。
从JavaScript调用Silverlight代码似乎也更复杂,但有可能:
答案 2 :(得分:7)
只需命名另一个(更像是#34; web-of-things&#34;)选项:外部硬件。
根据使用情况,您可以使用外部低成本设备,如arduino微控制器或raspberry-pi嵌入式PC。
在这些设备上构建简单的串行到Web服务桥接并不是很困难。你可以使用这样的一些项目,例如:https://code.google.com/p/serwebproxy/
在这种情况下,所有低级别的东西都由外部硬件处理,并通过类似界面的Web服务(通过get / post)提供给您。
进一步的优点是,运行应用程序的pc不需要串行端口(在某些系统上变得非常罕见)。
通过浏览器应用程序,您可以通过简单的ajax调用查询嵌入式设备上的Web服务。浏览器根本不需要任何插件,该解决方案可以跨平台工作,并且通用且独立于不久的将来浏览器技术的开发。
答案 3 :(得分:5)
可能不是。
我将假设您有充分的理由从Web浏览器而不是本机应用程序运行您的应用程序。我可以想到几个场景,我可以看到这是一个合理的商业决策。
即使在今天,随着所有现代技术的进步,Web浏览器仍然是花哨的交互式文档查看器,而不是通用的运行时环境。甚至最先进的功能,如websockets也被引入,以实现复杂的客户端 - 服务器通信,而不是因为有一天普遍感兴趣,有一天能够从浏览器做任何事情。
可能存在一些原生可能的特殊环境(Chrome操作系统?),但它不是一般解决方案。我不知道通过浏览器标签或脚本打开串行端口的现有标准或建议标准。这意味着您将需要某种类似ActiveX的相当低级别的插件技术。如果你只支持IE,那么ActiveX是一个非常好的解决方案,特别是如果它已经编写并且有效。
大多数寻求从浏览器进行串口访问的人可能正在从他们指定(构建/销售?)和控制的某些专有硬件进行数据采集,例如实验室设备,条形码扫描仪,科学仪器等。我认为在这一点上,指定所需的浏览器也是完全可以接受的。专业应用程序通常会这样做。
如果您仍想查看更广泛的浏览器支持,请尝试查看针对此问题的建议解决方案:Communicating with Serial Port using Adobe Flash。我没有使用过这个产品的经验,但是如果它有效,它应该能让大多数浏览器用你想做的单个代码库来完成你想做的事情。这就像你希望的那样好。
无论你最终做什么,它肯定会涉及某种形式的第三方插件。
答案 4 :(得分:5)
您可以使用网络USB - 但浏览器兼容性(目前)非常低 - Chrome 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。
答案 5 :(得分:2)
通过Node JS作为服务器使用serialport包是一种选择。这适用于Windows,显然也适用于Linux和OSX。请参阅https://github.com/node-serialport/node-serialport。
这是我用来通过USB向浏览器读取微位通信的解决方案。我必须使用:
重建windows(10)的驱动程序我已粘贴下面的一些代码供参考:
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')
}
})
})
*/
这种方法对我来说很有用 - 但要让它正常工作可能会非常耗时。在我看来,这不是一个明显或简单的解决方案。它需要相当多的技术知识 - 而且,我觉得,它更复杂,更棘手&#39;应该是。
特别是 - 在使用Node JS时,重建库并不是我期望做的事情。其中一个可能的影响是您需要为不同的平台重建串行端口二进制文件。