feat(scanner): tcp scanner connection based on env var no more db stuff
This commit is contained in:
187
lstV2/server/globalUtils/scannerConnect.ts
Normal file
187
lstV2/server/globalUtils/scannerConnect.ts
Normal file
@@ -0,0 +1,187 @@
|
||||
/**
|
||||
* Using this to make a scanner connection to the server.
|
||||
*/
|
||||
|
||||
import net from "net";
|
||||
|
||||
interface QueuedCommand {
|
||||
command: string;
|
||||
resolve: (value: string) => void;
|
||||
reject: (reason?: any) => void;
|
||||
timeout: NodeJS.Timeout;
|
||||
}
|
||||
|
||||
const STX = "\x02";
|
||||
const ETX = "\x03";
|
||||
|
||||
// const prodIP = process.env.SERVER_IP as string;
|
||||
// const prodPort = parseInt(process.env.SCANNER_PORT || "50000", 10);
|
||||
// const scannerID = `${process.env.SCANNER_ID}@`;
|
||||
//const scannerCommand = "AlplaPRODcmd00000042#000028547"; // top of the picksheet
|
||||
|
||||
export class ScannerClient {
|
||||
private socket = new net.Socket();
|
||||
private connected = false;
|
||||
|
||||
private queue: QueuedCommand[] = [];
|
||||
private processing = false;
|
||||
|
||||
private incomingBuffer = "";
|
||||
|
||||
constructor(
|
||||
private host: string,
|
||||
private port: number,
|
||||
private scannerId: string,
|
||||
) {
|
||||
this.initialize();
|
||||
}
|
||||
|
||||
private initialize() {
|
||||
this.socket.connect(this.port, this.host, () => {
|
||||
console.info("Connected to scanner");
|
||||
this.connected = true;
|
||||
});
|
||||
|
||||
this.socket.on("data", (data) => this.handleData(data));
|
||||
|
||||
this.socket.on("close", () => {
|
||||
console.log("Scanner connection closed");
|
||||
this.connected = false;
|
||||
});
|
||||
|
||||
this.socket.on("error", (err) => {
|
||||
console.error("Scanner error:", err);
|
||||
});
|
||||
}
|
||||
|
||||
// ✅ Public method you use
|
||||
public scan(command: string): Promise<string> {
|
||||
if (!this.connected) {
|
||||
return Promise.reject("Scanner not connected");
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const timeout = setTimeout(() => {
|
||||
this.processing = false;
|
||||
reject("Scanner timeout");
|
||||
this.processQueue();
|
||||
}, 5000); // 5s safety timeout
|
||||
|
||||
this.queue.push({
|
||||
command,
|
||||
resolve,
|
||||
reject,
|
||||
timeout,
|
||||
});
|
||||
|
||||
this.processQueue();
|
||||
});
|
||||
}
|
||||
|
||||
// ✅ Ensures strict FIFO processing
|
||||
private processQueue() {
|
||||
if (this.processing) return;
|
||||
if (this.queue.length === 0) return;
|
||||
|
||||
this.processing = true;
|
||||
|
||||
const current = this.queue[0];
|
||||
const message = Buffer.from(
|
||||
`${STX}${this.scannerId}${current.command}${ETX}`,
|
||||
"ascii",
|
||||
);
|
||||
|
||||
this.socket.write(message);
|
||||
}
|
||||
|
||||
// ✅ Handles full STX/ETX framed responses
|
||||
private handleData(data: Buffer) {
|
||||
console.log(
|
||||
"ASCII:",
|
||||
data
|
||||
.toString("ascii")
|
||||
.replace(/\x00/g, "") // remove null bytes
|
||||
.replace(/\x1B\[[0-9;?]*[A-Za-z]/g, "") // remove ANSI escape codes
|
||||
.trim(),
|
||||
);
|
||||
|
||||
const current = this.queue.shift();
|
||||
if (current) {
|
||||
clearTimeout(current.timeout);
|
||||
current.resolve(data.toString("ascii"));
|
||||
}
|
||||
|
||||
this.processing = false;
|
||||
this.processQueue();
|
||||
}
|
||||
}
|
||||
|
||||
export const scanner = new ScannerClient(
|
||||
process.env.SERVER_IP!,
|
||||
parseInt(process.env.SCANNER_PORT!, 10),
|
||||
`${process.env.SCANNER_ID}@`,
|
||||
);
|
||||
|
||||
// export const connectToScanner = () => {
|
||||
// if (!process.env.SERVER_IP || !process.env.SCANNER_PORT) {
|
||||
// return {
|
||||
// success: false,
|
||||
// message: "Missing ServerIP or ServerPort",
|
||||
// };
|
||||
// }
|
||||
|
||||
// scanner.connect(prodPort, prodIP, () => {
|
||||
// console.log("Connected to scanner");
|
||||
// connected = true;
|
||||
// });
|
||||
// };
|
||||
|
||||
// export const scan = async (command: string) => {
|
||||
// if (!connected) {
|
||||
// return {
|
||||
// success: false,
|
||||
// message: "Scanner is not connected, please contact admin",
|
||||
// };
|
||||
// }
|
||||
// if (inScanCommand) {
|
||||
// bufferCommands.push({ timeStamp: new Date(Date.now()), command: command });
|
||||
// }
|
||||
|
||||
// // we are going to set to scanning
|
||||
// inScanCommand = true;
|
||||
|
||||
// const message = Buffer.from(`${STX}${scannerID}${command}${ETX}`, "ascii");
|
||||
// scanner.write(message);
|
||||
// await new Promise((resolve) => setTimeout(resolve, 750));
|
||||
|
||||
// inScanCommand = false;
|
||||
|
||||
// if (bufferCommands.length > 0) {
|
||||
// await scan(bufferCommands[0].command);
|
||||
// bufferCommands.shift();
|
||||
// }
|
||||
|
||||
// return {
|
||||
// success: true,
|
||||
// message: "Scan completed",
|
||||
// };
|
||||
// };
|
||||
|
||||
// scanner.on("data", async (data) => {
|
||||
// console.log(
|
||||
// "Response:",
|
||||
// data
|
||||
// .toString("ascii")
|
||||
// .replace(/\x00/g, "") // remove null bytes
|
||||
// .replace(/\x1B\[[0-9;?]*[A-Za-z]/g, "") // remove ANSI escape codes
|
||||
// .trim(),
|
||||
// );
|
||||
// });
|
||||
|
||||
// scanner.on("close", () => {
|
||||
// console.log("Connection closed");
|
||||
// });
|
||||
|
||||
// scanner.on("error", (err) => {
|
||||
// console.error("Scanner error:", err);
|
||||
// });
|
||||
Reference in New Issue
Block a user