Skip to content
This repository has been archived by the owner on May 13, 2024. It is now read-only.

Utkarsha/dera 453/websocket connection closed due to timeout #281

23 changes: 22 additions & 1 deletion src/configs/websocket/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,17 @@ export type TDerivApi = {
authorize: (requestData: AuthorizeRequest) => Promise<AuthorizeResponse>;
};

let attempts = 10;
const RECONNECT_INTERVAL = attempts * 10000;
matin-deriv marked this conversation as resolved.
Show resolved Hide resolved
const PING_INTERVAL = 12000;

export class ApiManager {
private socket: WebSocket;
private derivApi: TDerivApi;
private pingInterval: NodeJS.Timer;
private reconnectInterval: NodeJS.Timer;
private is_websocket_connected: (connection_value) => boolean;
private is_websocket_authorized: (connection_value) => boolean;

public static instance: ApiManager;
public static getInstance() {
Expand Down Expand Up @@ -51,7 +56,9 @@ export class ApiManager {
return this.derivApi.subscribe(request) as Observable<TSocketResponse<T>>;
}

public authorize(token: string) {
public authorize(token: string, setIsConnected, setIsAuthorized) {
this.is_websocket_connected = setIsConnected;
this.is_websocket_authorized = setIsAuthorized;
return this.derivApi.authorize({ authorize: token });
}
public logout() {
Expand All @@ -62,14 +69,28 @@ export class ApiManager {
if (this.pingInterval) {
clearInterval(this.pingInterval);
}
if (this.reconnectInterval) {
clearInterval(this.reconnectInterval);
}
this.socket.addEventListener('open', () => {
this.is_websocket_connected?.(true);
this.pingInterval = setInterval(() => {
this.socket.send(JSON.stringify({ ping: 1 }));
}, PING_INTERVAL);
});

this.socket.addEventListener('close', () => {
this.is_websocket_connected?.(false);
this.is_websocket_authorized?.(false);
clearInterval(this.pingInterval);
this.socket = null;
if (attempts > 0) {
this.reconnectInterval = setTimeout(this.init.bind(this), RECONNECT_INTERVAL);
attempts -= 1;
} else {
window.alert('server down!!!');
matin-deriv marked this conversation as resolved.
Show resolved Hide resolved
clearInterval(this.reconnectInterval);
}
});

this.socket.addEventListener('error', () => {
Expand Down
11 changes: 8 additions & 3 deletions src/contexts/auth/auth.provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const AuthProvider = ({ children }: TAuthProviderProps) => {
const [is_logged_in, setIsLoggedIn] = useState(false);
const [is_authorized, setIsAuthorized] = useState(false);
const [is_switching_account, setisSwitchingAccount] = useState(false);
const [is_connected, setIsConnected] = useState(true);

const [loginAccounts, setLoginAccounts] = useSessionStorage<IUserLoginAccount[]>(
LOGIN_ACCOUNTS_SESSION_STORAGE_KEY,
Expand All @@ -45,7 +46,11 @@ const AuthProvider = ({ children }: TAuthProviderProps) => {

const updateAuthorize = useCallback(async () => {
if (currentLoginAccount.token) {
const { authorize } = await apiManager.authorize(currentLoginAccount.token);
const { authorize } = await apiManager.authorize(
currentLoginAccount.token,
setIsConnected,
setIsAuthorized,
);
setIsAuthorized(true);
setisSwitchingAccount(false);
const { account_list, ...user } = authorize;
Expand All @@ -55,10 +60,10 @@ const AuthProvider = ({ children }: TAuthProviderProps) => {
}, [currentLoginAccount.token, setUser, setUserAccounts]);

useEffect(() => {
if (!is_authorized) {
if (!is_authorized && is_connected) {
updateAuthorize();
}
}, [is_authorized, updateAuthorize]);
}, [is_authorized, is_connected, updateAuthorize]);

const updateLoginAccounts = useCallback(
(loginAccounts: IUserLoginAccount[]) => {
Expand Down
6 changes: 0 additions & 6 deletions src/contexts/playground/playground.provider.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import React, { ReactNode, useEffect, useMemo, useState } from 'react';
import apiManager from '@site/src/configs/websocket';
import { getIsBrowser } from '@site/src/utils';
import { PlaygroundContext } from './playground.context';
import { TSocketResponseData } from '@site/src/configs/websocket/types';
import { TSocketEndpointNames } from '@site/src/configs/websocket/types';
Expand All @@ -9,10 +7,6 @@ type TPlaygroundProviderProps = {
children: ReactNode;
};

if (getIsBrowser()) {
apiManager.init();
}

const PlaygroundProvider = <T extends TSocketEndpointNames>({
children,
}: TPlaygroundProviderProps) => {
Expand Down
Loading