How I Made Friends React and the HP LJ M127 Scanner
Friendship of three friends React, Delphi, HP LJ M127
Today I will tell you the story of the friendship of three friends, or if, in a simple way, like me, I got the idea to make the web with hardware.
I’ll probably start with the fact that it all started with writing a software application in delphi to scan documents and save their blob data in the MSSQL SERVER 20212 database, below I will give a screenshot of this application, but as the title of my article says today, we will talk about another application
In general, the idea came from the fact that I wanted to make an application that could be run on any computer, but then the first problem appeared, reactjs, like all web frameworks, does not work with hardware with drivers, and then my experience of working with high-level Delphi programming language
React app
I present to your attention the login login page
My authorization is essentially built on two functions, one function is to check whether this user has previously authorized, and the second function already authorizes the user
ReallyAut=()=>
{
axios.get(Conf.API_URL+'user/really_aut/'+localStorage.getItem('hash'))
.then(res => {
const data= res.data;
let autentificate = data.autentificate;
this.setState({autentificate : autentificate.success});
this.props.aut(data.data.hash,data.success,data.data.username);
this.props.autentificate(autentificate);
})
}
This function is just involved in checking whether the user is authorized, I call this function in the react lifecycle in ComponentDidMount (this function is executed after adding an object to the DOM tree) and of course I use hash values to work with authorizations
Autorize = (event) => {
event.preventDefault();
let passwd = this.passwdRef.current.value;
let login = this.loginRef.current.value;
Toast.loading('Ожидание ответа....');
axios.get(Conf.API_URL+'user/autorize/'+login+'/'+passwd)
.then(res => {
const data = res.data;
Toast.hide();
if(data.success){
this.props.aut(data.token,data.success,data.name);
localStorage.setItem('hash',data.token);
localStorage.setItem('userName',data.token);
} else
{
NotificationManager.error('Неверный логин или пароль, повторите ввод','Ошибка авторизации',3000);
}
}).catch(err => {
if (err.response) {
// client received an error response (5xx, 4xx)
} else if (err.request) {
// client never received a response, or request never left
} else {
// anything else
}
NotificationManager.error('Нет доступа....','Ошибка',3000);
console.log(err);
Toast.hide();
});
}
Well, we got to the second function that authorizes us on the server and gives us a token
The main form looks like this, and as you can see from the screenshot, it allows us to select a customer and an executor in a quick set, but the main functionality is different, namely, in scanning and saving a document, side functions are deleting, moving, adding scanned documents
In general, an already completed form with scanned documents, as you can see in the screenshot, can be moved and deleted.
How scanning is performed in general, everything is simple here, in the DELPHI program that sits in the tray all the power is contained, namely, this is the connection with the HP LJ M127 scanner, the application attaches a listener to the port, now let’s move on to the Delphi application
Delphi Application
Let’s describe the main objects, one of which is an object that stores information about scanned images, here the main trick is to store the image in encrypted form as a string so that it can be conveniently transmitted and stored
type
TScanImage = class(Tobject)
public
Image: TBitmap;
thumbnail: TJPEGImage;
StreamBitmap: TMemoryStream;
base64_image: String;
sended: Byte;
heigh: Integer;
width: Integer;
date_scan: TDateTime;
constructor Create(zimg: TBitmap; zh, zw: Integer; zds: TDateTime);
end;
The second object is needed to inform our web application about the current tasks that our application is performing, there are only a few events
No event
Scanning a Document
Rotate picture
Convert to PDF
Saving to the server
type
TEvents = class(Tobject)
public
procedure SetEvent(EventCode: Byte; EventStatus: Byte;
EventData: TJSONArray);
procedure SetEventName(EventName: String; EventCode: Byte);
procedure SetStatusEvent(EventStatus: Byte);
procedure SetEventData(EventData: TJSONArray);
function GetEvent: TJSONObject;
private
constructor Create();
protected
event_name: String;
event_code: Byte;
event_status: Byte;
event_date: Int64;
event_data: TJSONArray;
event_message: String;
end;
That is, the very principle of friendship lies in the link that our application in Delphi executes, it happens like this
1. A web application on React through http requests (via axios) gives a command to scan a document, a Delphi application listens on a port and receives a command, starts executing and records what is happening at the moment in the application on delphi
2. The web application, after a certain interval, requests the status of the task that is being performed or has already been completed
3. When the application in Delphi has finished scanning the document (It can be an automatic feeder and manual scanning), it writes the objects that it scanned to the event status and, when requested from the web application, gives them
Back to the ReactJS web application
This screenshot shows documents that have already been scanned and can be viewed, deleted
View a document with the ability to download it
Deleting a Document