Evenimente
Evenimente
EventSubscriber înfășoară WebSocket-ul de evenimente e-bon (wss://api.e-bon.ro/ws) cu listeneri tipați și reconectare automată. Este înlocuitorul recomandat al pollingului pe client.commands.get(id) îndată ce integrarea ta are mai mult de o mână de dispozitive.
Pornire rapidă
Cea mai simplă cale este să lași EBonClient să-ți construiască subscriber-ul, reutilizând aceleași credențiale:
import { EBonClient } from '@e-bon/sdk';
const client = new EBonClient({
baseUrl: 'https://api.e-bon.ro',
apiKey: process.env.EBON_API_KEY!,
});
const events = client.events.subscribe();
events.on('receipt.created', (data) => {
console.log(`bon fiscal ${data.receiptId} pe dispozitivul ${data.deviceId} = ${data.total}`);
});
events.on('command.failed', (data) => {
// data.fiscalError este o instanță reală FiscalError — o poți arunca direct.
console.error(data.fiscalError);
});
// Mai târziu, la oprire:
events.close();
Construiește direct un EventSubscriber
EventSubscriber este de asemenea exportat separat și poate fi construit direct atunci când nu ai un EBonClient la îndemână (de exemplu într-un worker care doar ascultă):
import { EventSubscriber } from '@e-bon/sdk';
const events = new EventSubscriber('https://api.e-bon.ro', {
apiKey: 'ebon_live_...',
});
Semnătura:
new EventSubscriber(baseUrl: string, auth: { apiKey?: string; token?: string })
baseUrl— același URL de bază pe care îl dai luiEBonClient. Subscriber-ul rescrie protocolul înws/wssși adaugă/ws.auth.token— token de acces JWT. Trimis ca?token=...în URL-ul WebSocket. Are prioritate față deauth.apiKeycând sunt setate amândouă.auth.apiKey— cheie API. Trimisă ca?apiKey=...când nu este oferit niciuntoken.
Subscriber-ul se conectează imediat la construcție; nu trebuie să apelezi tu o metodă connect().
Ascultă cu on, off, once
Toate cele trei metode sunt tipate prin uniunea EventName derivată din EventMap, deci payload-ul listener-ului este inferat pentru tine:
events.on('device.status', (data) => {
// data este DeviceStatusEvent { deviceId, status, timestamp }
});
const handler = (data: ReceiptCreatedEvent) => { /* … */ };
events.on('receipt.created', handler);
events.off('receipt.created', handler); // elimină un listener anume
events.once('command.completed', (data) => {
// se declanșează exact o dată și se dezînregistrează singur
});
Erorile aruncate dintr-un listener sunt înghițite — un throw într-un listener nu va opri ceilalți listeneri să ruleze și nu va distruge bucla WebSocket.
Închide subscriber-ul
Apelează events.close() când ai terminat. Marchează subscriber-ul ca închis, anulează orice timer de reconectare în așteptare și închide socket-ul subiacent. După close(), subscriber-ul este permanent închis — construiește unul nou dacă vrei să o iei de la capăt.
Reconectează automat cu backoff exponențial
Când socket-ul cade, subscriber-ul se reconectează automat. Programul este fix:
| Constantă | Valoare | Înțeles |
|---|---|---|
DEFAULT_RECONNECT_DELAY | 1000 ms | Prima reîncercare are loc la 1 secundă după deconectare. |
RECONNECT_BACKOFF_FACTOR | 2 | Fiecare reîncercare următoare dublează întârzierea. |
MAX_RECONNECT_DELAY | 30000 ms | Plafon — întârzierea nu trece niciodată de 30 de secunde. |
Așadar, intervalele dintre încercările de reconectare merg 1s → 2s → 4s → 8s → 16s → 30s → 30s → … până când socket-ul revine, moment în care întârzierea se resetează la 1 secundă pentru următoarea deconectare. Evenimentul connected se declanșează de fiecare dată când socket-ul se redeschide; disconnected se declanșează de fiecare dată când cade.
events.on('connected', () => console.log('evenimente: live'));
events.on('disconnected', () => console.warn('evenimente: căzut — se reconectează'));
events.on('error', (err) => console.error('evenimente: eroare socket', err));
WebSocket-ul nativ al runtime-ului. Mesajele incorecte primite de la server sunt ignorate în tăcere (socket-ul rămâne deschis). Dacă runtime-ul tău nu pune la dispoziție WebSocket global, instalează un polyfill înainte de a importa @e-bon/sdk.Răsfoiește catalogul de evenimente
Mulțimea completă a evenimentelor pe care te poți abona este interfața EventMap re-exportată din @e-bon/sdk. Cheile de mai jos sunt exact șirurile pe care le pasezi lui on / off / once; coloana de payload este forma tipată a celui de-al doilea argument.
| Șir eveniment | Tip payload | Se declanșează când |
|---|---|---|
device.status | DeviceStatusEvent | Statusul de conexiune al unui dispozitiv se schimbă (online / offline / busy). |
device.claimed | DeviceClaimedEvent | Un controler (instanță a aplicației mobile E-BON) revendică un dispozitiv. |
receipt.created | ReceiptCreatedEvent | Un bon fiscal este stocat pe platformă. |
command.completed | CommandCompletedEvent | O comandă fiscală se termină cu succes la imprimantă. |
command.failed | CommandFailedEvent | O comandă fiscală eșuează. Payload-ul include un fiscalError precalculat. |
app.connected | AppConnectedEvent | O instanță a aplicației mobile E-BON își deschide WebSocket-ul către server. |
app.disconnected | AppDisconnectedEvent | O instanță a aplicației mobile E-BON se deconectează. |
connected | undefined | Socket-ul de evenimente tocmai s-a (re)deschis — doar ciclu de viață local. |
disconnected | undefined | Socket-ul de evenimente tocmai a căzut — doar ciclu de viață local. |
error | Error | Socket-ul de evenimente a emis o eroare — doar ciclu de viață local. |
Tipurile de payload exportate sunt: DeviceStatusEvent, DeviceClaimedEvent, ReceiptCreatedEvent, CommandCompletedEvent, CommandFailedEvent, CommandTimeoutEvent, AppConnectedEvent și AppDisconnectedEvent. Toate pot fi importate ca tipuri din @e-bon/sdk. CommandTimeoutEvent este forma folosită de pipeline-ul de timeout din server; pe fir, evenimentul este livrat ca command.failed cu errorCode: ErrorCode.TimeoutCommand, deci îl tratezi prin același listener.
Exemplu — reacționează la receipt.created
Un worker minim care oglindește fiecare bon fiscal într-un jurnal de audit local:
import { EBonClient, type ReceiptCreatedEvent } from '@e-bon/sdk';
const client = new EBonClient({
baseUrl: 'https://api.e-bon.ro',
apiKey: process.env.EBON_API_KEY!,
});
const events = client.events.subscribe();
events.on('connected', () => console.log('evenimente: live'));
events.on('disconnected', () => console.warn('evenimente: se reconectează…'));
events.on('receipt.created', async (event: ReceiptCreatedEvent) => {
// Aducem bonul fiscal complet acum că îi știm id-ul.
const receipt = await client.receipts.get(event.receiptId);
await auditLog.append({
receiptId: receipt.id,
deviceId: event.deviceId,
total: event.total,
timestamp: event.timestamp,
});
});
process.on('SIGTERM', () => events.close());
Unde mergi mai departe
- Erori — forma
FiscalErroratașată payload-urilorcommand.failed. - API › Webhook-uri — apeluri HTTP de ieșire dacă nu poți menține un WebSocket cu durată lungă de viață.
- Prezentare generală SDK — înapoi la suprafața clientului.
Pornire rapidă
Un parcurs pas cu pas — instalează @e-bon/sdk, obține o cheie API, instanțiază EBonClient, listează aparatele, emite un bon și tratează erorile fiscale.
Erori
Clasele de excepție FiscalError și EBonApiError, enumerarea ErrorCode și mulțimea RETRYABLE_ERRORS re-exportate din @e-bon/sdk și un model recomandat de reîncercare.