Prodress Connection fertig implementiert
This commit is contained in:
parent
7e892e8c42
commit
b1f264424c
@ -1,8 +1,6 @@
|
||||
import {app, BrowserWindow} from 'electron';
|
||||
import {Socket} from 'net';
|
||||
import path from 'path';
|
||||
import {R2RequestErweiterungsdaten, R2RequestKopfdaten, Request, RequestLeser} from '@prodress/pdr2com';
|
||||
import {ProdressRequest} from './pdr2com/wrapper.js';
|
||||
import {ProdressConnection} from './pdr2com/connection.js';
|
||||
|
||||
const APPLICATION_PATH = path.join(app.getAppPath(), '/dist-svelte/index.html');
|
||||
|
||||
@ -14,23 +12,39 @@ app.on('ready', async () => {
|
||||
mainWindow.loadFile(APPLICATION_PATH);
|
||||
}
|
||||
|
||||
try {
|
||||
const socket = new Socket();
|
||||
socket.connect(4788, 'localhost');
|
||||
|
||||
const test = new ProdressRequest('db', 'handler', 'aktion', {});
|
||||
test.schreibeText('HalloWelt 2355435');
|
||||
socket.on('connect', () => {
|
||||
console.log('verbunden');
|
||||
test.sende(socket);
|
||||
});
|
||||
const r2reader = new RequestLeser();
|
||||
socket.on('data', (data: Buffer) => {
|
||||
r2reader.verarbeiteDaten(data);
|
||||
});
|
||||
const r2request = await r2reader.leseRequest();
|
||||
console.log(r2request.nächsterText());
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
const req = new ProdressConnection(
|
||||
{
|
||||
port: 4788,
|
||||
host: 'localhost',
|
||||
database: 'test',
|
||||
handler: 'Shopify',
|
||||
action: 'artikelSync',
|
||||
},
|
||||
[['string', 'HalloWelt']],
|
||||
[
|
||||
['line1', 'string'],
|
||||
['line2', 'string'],
|
||||
],
|
||||
);
|
||||
const res = await req.handleRequest();
|
||||
console.log(res);
|
||||
// try {
|
||||
// const socket = new Socket();
|
||||
// socket.connect(4788, 'localhost');
|
||||
//
|
||||
// const test = new ProdressRequest('db', 'handler', 'aktion');
|
||||
// test.schreibeText('HalloWelt 2355435');
|
||||
// socket.on('connect', () => {
|
||||
// console.log('verbunden');
|
||||
// test.sende(socket);
|
||||
// });
|
||||
// const r2reader = new RequestLeser();
|
||||
// socket.on('data', (data: Buffer) => {
|
||||
// r2reader.verarbeiteDaten(data);
|
||||
// });
|
||||
// const r2request = await r2reader.leseRequest();
|
||||
// console.log(r2request.nächsterText());
|
||||
// } catch (error) {
|
||||
// console.error(error);
|
||||
// }
|
||||
});
|
||||
|
||||
139
src/electron/pdr2com/connection.ts
Normal file
139
src/electron/pdr2com/connection.ts
Normal file
@ -0,0 +1,139 @@
|
||||
import {RequestLeser as ProdressListener, type R2AnfrageBlaupause} from '@prodress/pdr2com';
|
||||
import {type ResponseTupel, type ResponseObject, ProdressRequest, type RequestTupel} from './wrapper.js';
|
||||
import {Socket} from 'node:net';
|
||||
|
||||
export interface ProdressHeader {
|
||||
port?: number;
|
||||
host?: string;
|
||||
database: string;
|
||||
handler: string;
|
||||
action: string;
|
||||
}
|
||||
|
||||
// @todo move to nyi utils file
|
||||
function stringifyError(error: Error): string {
|
||||
const {message, stack} = error;
|
||||
|
||||
return JSON.stringify(
|
||||
{
|
||||
message,
|
||||
stack,
|
||||
},
|
||||
null,
|
||||
2,
|
||||
);
|
||||
}
|
||||
|
||||
export class ProdressConnection {
|
||||
public static readonly TIMEOUT = 30_000;
|
||||
|
||||
private port: number;
|
||||
private host: string;
|
||||
private socket: Socket;
|
||||
private request: ProdressRequest;
|
||||
private listener: ProdressListener;
|
||||
private requestTupelList: RequestTupel[];
|
||||
private responseTupelList: ResponseTupel[];
|
||||
|
||||
public constructor(header: ProdressHeader, requestTupelList: RequestTupel[], responseTupelList: ResponseTupel[]) {
|
||||
this.port = header.port ?? 4788;
|
||||
this.host = header.host ?? 'localhost';
|
||||
this.socket = new Socket();
|
||||
this.request = new ProdressRequest(header.database, header.handler, header.action);
|
||||
this.listener = new ProdressListener();
|
||||
this.requestTupelList = requestTupelList;
|
||||
this.responseTupelList = responseTupelList;
|
||||
}
|
||||
|
||||
public async handleRequest(): Promise<string> {
|
||||
let response: string = '';
|
||||
const responseAsPromise = new Promise<string>((resolve) => {
|
||||
this.socket.once('finished', () => {
|
||||
if (!this.socket.destroyed) {
|
||||
this.socket.destroy();
|
||||
}
|
||||
resolve(response);
|
||||
});
|
||||
});
|
||||
|
||||
this.socket.setTimeout(ProdressConnection.TIMEOUT);
|
||||
this.socket.connect(this.port, this.host);
|
||||
|
||||
this.socket.once('connect', () => {
|
||||
try {
|
||||
this.request.writeEntries(this.requestTupelList);
|
||||
this.request.sende(this.socket);
|
||||
} catch (error) {
|
||||
response = stringifyError(error as Error);
|
||||
this.finished();
|
||||
}
|
||||
});
|
||||
|
||||
// @todo Rework Error Message
|
||||
this.socket.on('timeout', () => {
|
||||
const timeoutError = new Error('timeout');
|
||||
response = stringifyError(timeoutError);
|
||||
this.finished();
|
||||
});
|
||||
|
||||
this.socket.on('error', (error: Error) => {
|
||||
response = stringifyError(error);
|
||||
this.finished();
|
||||
});
|
||||
|
||||
this.socket.on('data', (data: Buffer) => {
|
||||
this.listener.verarbeiteDaten(data);
|
||||
this.socket.emit('dataRecieved');
|
||||
});
|
||||
|
||||
this.socket.once('dataRecieved', async () => {
|
||||
try {
|
||||
const incomingResponse = await this.listener.leseRequest();
|
||||
const responseObject = this.readResponse(incomingResponse);
|
||||
response = JSON.stringify(responseObject, null, 2);
|
||||
this.finished();
|
||||
} catch (error) {
|
||||
response = stringifyError(error as Error);
|
||||
this.finished();
|
||||
}
|
||||
});
|
||||
return responseAsPromise;
|
||||
}
|
||||
|
||||
private finished(): void {
|
||||
this.socket.emit('finished');
|
||||
}
|
||||
|
||||
/**
|
||||
* reads the Reponse based on the provided responseTupelList and creates a ResponseObject
|
||||
* @param responseInstance The Listener Instance of the active TCP Socket
|
||||
* @returns ResponseObject
|
||||
*/
|
||||
private readResponse(responseInstance: R2AnfrageBlaupause): ResponseObject {
|
||||
const response: ResponseObject = {};
|
||||
|
||||
for (const tupel of this.responseTupelList) {
|
||||
const [key, type] = tupel;
|
||||
switch (type) {
|
||||
case 'string':
|
||||
response[key] = responseInstance.nächsterText();
|
||||
break;
|
||||
case 'integer':
|
||||
response[key] = responseInstance.nächsteGanzzahl();
|
||||
break;
|
||||
case 'float':
|
||||
response[key] = responseInstance.nächsteDezimalzahl();
|
||||
break;
|
||||
case 'date':
|
||||
response[key] = responseInstance.nächstesDatum();
|
||||
break;
|
||||
case 'date_time':
|
||||
//@todo missing method in lib
|
||||
response[key] = responseInstance.nächstesDatum();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
}
|
||||
@ -8,32 +8,18 @@ export interface DataTypeConversion {
|
||||
date_time: () => Date | null;
|
||||
}
|
||||
|
||||
export interface ReponseSchema {
|
||||
readonly [key: string]: keyof DataTypeConversion;
|
||||
export interface ResponseObject {
|
||||
[key: string]: ReturnType<DataTypeConversion[keyof DataTypeConversion]>;
|
||||
}
|
||||
|
||||
export type ResponseTupel = [string, keyof DataTypeConversion];
|
||||
|
||||
export type RequestTupel = {
|
||||
[K in keyof DataTypeConversion]: [K, NonNullable<ReturnType<DataTypeConversion[K]>>];
|
||||
}[keyof DataTypeConversion];
|
||||
|
||||
export class ProdressRequest extends Request {
|
||||
/**
|
||||
* Mapping of a datatype to the correspondig read method
|
||||
*/
|
||||
public readonly responseSchemaConversion: DataTypeConversion = {
|
||||
string: this.nächsterText,
|
||||
integer: this.nächsteGanzzahl,
|
||||
float: this.nächsteDezimalzahl,
|
||||
date: this.nächstesDatum,
|
||||
date_time: this.nächstesDatumMitZeit,
|
||||
} as const;
|
||||
|
||||
/**
|
||||
* Definition of the Reponse
|
||||
*/
|
||||
public readonly responseSchema: ReponseSchema;
|
||||
|
||||
public constructor(db: string, handler: string, action: string, responseSchema: ReponseSchema) {
|
||||
public constructor(db: string, handler: string, action: string) {
|
||||
super(
|
||||
{
|
||||
interneProtokollVersion: 1,
|
||||
@ -55,6 +41,40 @@ export class ProdressRequest extends Request {
|
||||
maximalePaketgröße: 0,
|
||||
},
|
||||
);
|
||||
this.responseSchema = responseSchema;
|
||||
}
|
||||
|
||||
/**
|
||||
* writes entries based on the provided requestTupelList into the request
|
||||
* @param requestTupelList
|
||||
*/
|
||||
public writeEntries(requestTupelList: RequestTupel[]): void {
|
||||
for (const tupel of requestTupelList) {
|
||||
this.writeEntry(tupel);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* writes an entry based on the provided requestTupel into the request
|
||||
* @param requestTupel
|
||||
*/
|
||||
public writeEntry(requestTupel: RequestTupel): void {
|
||||
const [type, value] = requestTupel;
|
||||
switch (type) {
|
||||
case 'string':
|
||||
this.schreibeText(value);
|
||||
break;
|
||||
case 'integer':
|
||||
this.schreibeGanzzahl(value);
|
||||
break;
|
||||
case 'float':
|
||||
this.schreibeDezimalzahl(value);
|
||||
break;
|
||||
case 'date':
|
||||
this.schreibeDatum(value);
|
||||
break;
|
||||
case 'date_time':
|
||||
this.schreibeDatumMitZeit(value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,16 +1,12 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
// require strict types (null-save)
|
||||
"strict": true,
|
||||
// tell TypeScript to generate ESM Syntax
|
||||
"target": "ESNext",
|
||||
// tell TypeScript to require ESM Syntax as input (including .js file imports)
|
||||
"module": "NodeNext",
|
||||
// define where to put generated JS
|
||||
"moduleResolution": "NodeNext",
|
||||
"esModuleInterop": true,
|
||||
"outDir": "../../dist-electron",
|
||||
// ignore errors from dependencies
|
||||
"skipLibCheck": true,
|
||||
// add global types
|
||||
"skipLibCheck": true
|
||||
//"types": ["../../types"]
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user