[英]Communicate with the serial port from client web browser.
In my web application(sencha extjs 5) I have a user requirement to read/write data to the client PC serial port.在我的 Web 应用程序(sencha extjs 5)中,我有一个用户要求将数据读/写到客户端 PC 串行端口。
I am aware of the client browser can not access local machine hardware without installing some binaries on the local machine(Native app, Windows Service, etc..).我知道客户端浏览器无法访问本地机器硬件,除非在本地机器上安装一些二进制文件(本机应用程序、Windows 服务等)。
I have seen the same question is discussed few years back in stackoverflow forums.我看到几年前在 stackoverflow 论坛中讨论过同样的问题。 But I need to know what is the best way of doing this today with the available technologies?但是我需要知道当今使用可用技术进行此操作的最佳方法是什么?
Using Web Serial API.使用 Web 串行 API。 I am using this to ONLY read the data from my Weight Scale with RS232 Serial Interface我使用它仅从带有 RS232 串行接口的体重秤读取数据
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Web Serial</title>
</head>
<body>
<div class="serial-scale-div">
<button class="btn" id="connect-to-serial">Connect with Serial Device</button>
</div>
<button id="get-serial-messages">Get serial messages</button>
<div id="serial-messages-container">
<div class="message"></div>
</div>
<script>
"use strict";
class SerialScaleController {
constructor() {
this.encoder = new TextEncoder();
this.decoder = new TextDecoder();
}
async init() {
if ('serial' in navigator) {
try {
const port = await navigator.serial.requestPort();
await port.open({ baudRate: 9600 });
this.reader = port.readable.getReader();
let signals = await port.getSignals();
console.log(signals);
}
catch (err) {
console.error('There was an error opening the serial port:', err);
}
}
else {
console.error('Web serial doesn\'t seem to be enabled in your browser. Try enabling it by visiting:');
console.error('chrome://flags/#enable-experimental-web-platform-features');
console.error('opera://flags/#enable-experimental-web-platform-features');
console.error('edge://flags/#enable-experimental-web-platform-features');
}
}
async read() {
try {
const readerData = await this.reader.read();
console.log(readerData)
return this.decoder.decode(readerData.value);
}
catch (err) {
const errorMessage = `error reading data: ${err}`;
console.error(errorMessage);
return errorMessage;
}
}
}
const serialScaleController = new SerialScaleController();
const connect = document.getElementById('connect-to-serial');
const getSerialMessages = document.getElementById('get-serial-messages');
connect.addEventListener('pointerdown', () => {
serialScaleController.init();
});
getSerialMessages.addEventListener('pointerdown', async () => {
getSerialMessage();
});
async function getSerialMessage() {
document.querySelector("#serial-messages-container .message").innerText += await serialScaleController.read()
}
</script>
</body>
</html>
Checkout this demo and this code for a more descriptive example.查看此演示和此代码以获得更具描述性的示例。
You might need to turn on the Serial API feature on your browser.您可能需要在浏览器上打开串行 API 功能。 Following is the quote from References以下是参考文献的引用
As you can imagine, this is API is only supported by modern Chromium based desktop browsers right now (April 2020) but hopefully support will improve in the near future.可以想象,目前(2020 年 4 月)仅基于现代 Chromium 的桌面浏览器支持此 API,但希望在不久的将来支持会得到改善。 At this moment you need to enable your browser's Experimental Web Platform Features, just copy and paste the right URL:此时您需要启用浏览器的实验性 Web 平台功能,只需复制并粘贴正确的 URL:
chrome://flags/#enable-experimental-web-platform-features
opera://flags/#enable-experimental-web-platform-features
edge://flags/#enable-experimental-web-platform-features
chrome://flags/#enable-experimental-web-platform-features
opera://flags/#enable-experimental-web-platform-features
edge://flags/#enable-experimental-web-platform-features
References:参考:
https://dev.to/unjavascripter/the-amazing-powers-of-the-web-web-serial-api-3ilc https://dev.to/unjavascripter/the-amazing-powers-of-the-web-web-serial-api-3ilc
https://github.com/UnJavaScripter/web-serial-example https://github.com/UnJavaScripter/web-serial-example
Well, One way to do this is develop a chrome app.好吧,一种方法是开发一个 chrome 应用程序。 You can use chrome.serial API.您可以使用 chrome.serial API。
https://developer.chrome.com/apps/serial https://developer.chrome.com/apps/serial
Sample Code,示例代码,
In your manifest.json,在您的 manifest.json 中,
{
"name": "Serial Sample",
"description": "Read/Write from/to serial port.",
"version": "1.0",
"manifest_version": 2,
"permissions": ["serial"],
"app": {
"background": {
"scripts": ["background.js"]
}
}
}
In your background.js,在你的 background.js 中,
const DEVICE_PATH = 'COM1';
const serial = chrome.serial;
var dataRecieved="";
/* Interprets an ArrayBuffer as UTF-8 encoded string data. */
var ab2str = function(buf) {
var bufView = new Uint8Array(buf);
var encodedString = String.fromCharCode.apply(null, bufView);
return decodeURIComponent(escape(encodedString));
};
/* Converts a string to UTF-8 encoding in a Uint8Array; returns the array buffer. */
var str2ab = function(str) {
var encodedString = unescape(encodeURIComponent(str));
var bytes = new Uint8Array(encodedString.length);
for (var i = 0; i < encodedString.length; ++i) {
bytes[i] = encodedString.charCodeAt(i);
}
return bytes.buffer;
};
var SerialConnection = function() {
this.connectionId = -1;
this.lineBuffer = "";
this.boundOnReceive = this.onReceive.bind(this);
this.boundOnReceiveError = this.onReceiveError.bind(this);
this.onConnect = new chrome.Event();
this.onReadLine = new chrome.Event();
this.onError = new chrome.Event();
};
SerialConnection.prototype.onConnectComplete = function(connectionInfo) {
if (!connectionInfo) {
log("Connection failed.");
return;
}
this.connectionId = connectionInfo.connectionId;
chrome.serial.onReceive.addListener(this.boundOnReceive);
chrome.serial.onReceiveError.addListener(this.boundOnReceiveError);
this.onConnect.dispatch();
};
SerialConnection.prototype.onReceive = function(receiveInfo) {
if (receiveInfo.connectionId !== this.connectionId) {
return;
}
this.lineBuffer += ab2str(receiveInfo.data);
var index;
while ((index = this.lineBuffer.indexOf('\n')) >= 0) {
var line = this.lineBuffer.substr(0, index + 1);
this.onReadLine.dispatch(line);
this.lineBuffer = this.lineBuffer.substr(index + 1);
}
};
SerialConnection.prototype.onReceiveError = function(errorInfo) {
if (errorInfo.connectionId === this.connectionId) {
this.onError.dispatch(errorInfo.error);
}
};
SerialConnection.prototype.connect = function(path) {
serial.connect(path, this.onConnectComplete.bind(this))
};
SerialConnection.prototype.send = function(msg) {
if (this.connectionId < 0) {
throw 'Invalid connection';
}
serial.send(this.connectionId, str2ab(msg), function() {});
};
SerialConnection.prototype.disconnect = function() {
if (this.connectionId < 0) {
throw 'Invalid connection';
}
serial.disconnect(this.connectionId, function() {});
};
var connection = new SerialConnection();
connection.onConnect.addListener(function() {
//console.log('connected to: ' + DEVICE_PATH);
});
connection.onReadLine.addListener(function (line) {
//Serial port data recieve event.
dataRecieved = dataRecieved +line;
});
connection.connect(DEVICE_PATH);
Once you create the chrome app to communicate with the serial port the next thing is to allow your external web page to communicate with the chrome app using JavaScript.创建 chrome 应用程序以与串行端口通信后,接下来是允许您的外部网页使用 JavaScript 与 chrome 应用程序通信。
For this on your manifest.json file add,为此在您的 manifest.json 文件中添加,
"externally_connectable": {
"matches": ["*://*.example.com/*"]
}
This will allow external webpage on your example.com domain communicate with your chrome app.这将允许您 example.com 域上的外部网页与您的 chrome 应用程序通信。
In your webpage,在您的网页中,
// The ID of the extension we want to talk to.
var editorExtensionId = "nboladondmajlaalmcdupihoilpcketyl";
// Make a simple request:
chrome.runtime.sendMessage(editorExtensionId,
{ data: "data to pass to the chrome app" },
function (response)
{
alert(response);
});
In your chrome app,在您的 Chrome 应用程序中,
chrome.runtime.onMessageExternal.addListener(
function (request, sender, sendResponse) {
sendResponse("Send serial port data to the web page");
});
https://developer.chrome.com/apps/messaging https://developer.chrome.com/apps/messaging
I set up a website and a simple example for running a serial terminal in your browser.我建立了一个网站和一个在浏览器中运行串行终端的简单示例。 You should host it on a https server.您应该将其托管在 https 服务器上。
The serial terminal features are now available in chrome 88.串行终端功能现在在 chrome 88 中可用。
Live demo https://www.SerialTerminal.com Full source.现场演示https://www.SerialTerminal.com完整源代码。 https://github.com/mmiscool/serialTerminal.com/blob/main/index.html https://github.com/mmiscool/serialTerminal.com/blob/main/index.html
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.