BaaS_Driver_Android_App/services/paymentSocket.ts

137 lines
3.6 KiB
TypeScript

// services/socketService.ts
import { PAYMENT_SOCKET_BASE_URL, STORAGE_KEYS } from "@/constants/config";
import AsyncStorage from "@react-native-async-storage/async-storage";
import io, { Socket } from "socket.io-client";
class SocketService {
private socket: Socket | null = null;
private static instance: SocketService;
private constructor() {}
public static getInstance(): SocketService {
if (!SocketService.instance) {
SocketService.instance = new SocketService();
}
return SocketService.instance;
}
public async connect(): Promise<Socket> {
try {
const token = await AsyncStorage.getItem(STORAGE_KEYS.AUTH_TOKEN);
if (!token) {
throw new Error("No auth token found");
}
this.socket = io(PAYMENT_SOCKET_BASE_URL, {
transports: ["websocket"],
autoConnect: true,
reconnection: true,
reconnectionDelay: 1000,
reconnectionAttempts: 5,
timeout: 20000,
extraHeaders: {
Authorization: `Bearer ${token}`,
},
});
return new Promise((resolve, reject) => {
this.socket!.on("connect", () => {
console.log("Socket connected:", this.socket?.id);
resolve(this.socket!);
});
this.socket!.on("connect_error", (error) => {
console.error("Socket connection error:", error);
reject(error);
});
this.socket!.on("disconnect", (reason) => {
console.log("Socket disconnected:", reason);
});
});
} catch (error) {
console.error("Failed to connect socket:", error);
return Promise.reject(error);
}
}
public registerTransaction(transactionId: string): Promise<void> {
return new Promise((resolve, reject) => {
const socket = this.socket; // Save reference to socket here
if (!socket || !socket.connected) {
reject(new Error("Socket not connected"));
return;
}
const timeoutMs = 5000;
const timeoutId = setTimeout(() => {
socket.off("registration-ack", onRegistrationAck);
reject(new Error("Timeout: No registration-ack received"));
}, timeoutMs);
const onRegistrationAck = (data: any) => {
console.log("inside onRegisterAck");
if (data.transactionId === transactionId) {
clearTimeout(timeoutId);
// socket.off("registration-ack", onRegistrationAck);
if (data.success) {
resolve();
} else {
reject(new Error("Registration failed"));
}
}
};
socket.on("registration-ack", onRegistrationAck);
socket.on("register-transaction", this.onPaymentConfirm);
socket.onAny((eventName, ...args) => {
console.log(eventName, "eventname", JSON.stringify(args), "✅✅✅✅✅");
});
socket.emit("register-transaction", { transactionId });
});
}
private onPaymentConfirm(eventname: string, ...args: any[]): void {
console.log(eventname, "eventName", JSON.stringify(args));
}
public onPaymentConfirmation(callback: (data: any) => void): void {
if (!this.socket) {
console.error("Socket not connected");
return;
}
this.socket.on("register-transaction", callback);
}
public offPaymentConfirmation(): void {
if (this.socket) {
this.socket.off("payment-confirmation");
}
}
public disconnect(): void {
if (this.socket) {
this.socket.disconnect();
this.socket = null;
}
}
public isConnected(): boolean {
return this.socket?.connected || false;
}
public getSocket(): Socket | null {
return this.socket;
}
}
export default SocketService.getInstance();