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

Commit 3f436aa

Browse files
fix: websocket reconnection issue and authorization on reconnect
1 parent 8185b13 commit 3f436aa

File tree

5 files changed

+17
-78
lines changed

5 files changed

+17
-78
lines changed

src/configs/websocket/index.ts

Lines changed: 8 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import {
88
} from './types';
99
import { Observable } from 'rxjs';
1010
import { getIsBrowser, getServerConfig } from '@site/src/utils';
11-
import useAuthContext from '@site/src/hooks/useAuthContext';
1211

1312
export type TDerivApi = {
1413
send: (...requestData: unknown[]) => Promise<unknown>;
@@ -19,14 +18,14 @@ export type TDerivApi = {
1918
let attempts = 10;
2019
const RECONNECT_INTERVAL = attempts * 1000;
2120
const PING_INTERVAL = 12000;
22-
const is_connected_before = false;
23-
// const { updateAuthorize } = useAuthContext();
2421

2522
export class ApiManager {
2623
private socket: WebSocket;
2724
private derivApi: TDerivApi;
2825
private pingInterval: NodeJS.Timer;
2926
private reconnectInterval: NodeJS.Timer;
27+
private websocket_connected: (connection_value) => boolean;
28+
private websocket_authorize: (connection_value) => boolean;
3029

3130
public static instance: ApiManager;
3231
public static getInstance() {
@@ -37,7 +36,6 @@ export class ApiManager {
3736
}
3837

3938
public init() {
40-
console.log('init called');
4139
if (!this.socket) {
4240
const { serverUrl, appId } = getServerConfig();
4341
this.socket = new WebSocket(`wss://${serverUrl}/websockets/v3?app_id=${appId}`);
@@ -58,7 +56,9 @@ export class ApiManager {
5856
return this.derivApi.subscribe(request) as Observable<TSocketResponse<T>>;
5957
}
6058

61-
public authorize(token: string) {
59+
public authorize(token: string, setIsConnected, setIsAuthorized) {
60+
this.websocket_connected = setIsConnected;
61+
this.websocket_authorize = setIsAuthorized;
6262
return this.derivApi.authorize({ authorize: token });
6363
}
6464
public logout() {
@@ -73,16 +73,15 @@ export class ApiManager {
7373
clearInterval(this.reconnectInterval);
7474
}
7575
this.socket.addEventListener('open', () => {
76+
this.websocket_connected(true);
7677
this.pingInterval = setInterval(() => {
7778
this.socket.send(JSON.stringify({ ping: 1 }));
7879
}, PING_INTERVAL);
79-
// if(is_connected_before) updateAuthorize();
8080
});
8181

8282
this.socket.onclose = () => {
83-
// if (!is_connected_before) {
84-
// is_connected_before = true;
85-
// }
83+
this.websocket_connected(false);
84+
this.websocket_authorize(false);
8685
clearInterval(this.pingInterval);
8786
this.socket = null;
8887
if (attempts > 0) {
@@ -103,60 +102,6 @@ export class ApiManager {
103102
}
104103
}
105104

106-
// connection is made and all of a sudden server is down, two things happen -> we send ping to server repeatedly and check fo response -> if response received for that no. of attempts meaning server got up if not meaning server down show msg
107-
// fe side, we send pings to keep ws alive, but when server goes down ping gives no response which causes ws to close
108-
// In this case, we need to check the cause of closure
109-
// To check if reason is server down, we need to make new ws, send pings if no response recieved ws may close on its own so we send again for x amount times
110-
// once all attempts get exhausted, we conclude that server is down and show message
111-
// but if in one of the attempts, server send back a request - we try to reconnect (how to reconnect?)
112-
// handles reconnection if server goes down
113-
// 1. triggers on connection closed -> 1. reattempt to connect first check if server is up -> ping 4-5 times, 2. if server down for long time show msg, 3. if server back up re-establish websocket connection
114-
115-
// trigger this function when socket is closed -> to check if server is down
116-
public checkServerStatus() {
117-
console.log('checkServerStatus');
118-
119-
// open new socket
120-
this.createNewWebsocket();
121-
122-
// if WS is open, ping server for sometime, arbitary tries
123-
if (this.socket.readyState == WebSocket.OPEN) {
124-
console.log('ws is open');
125-
126-
while (attempts < 10) {
127-
console.log('inside while');
128-
129-
this.reconnectInterval = setInterval(() => {
130-
this.socket.send(JSON.stringify({ ping: 1 }));
131-
attempts += 1;
132-
}, 12000);
133-
134-
// listen for pongs
135-
this.socket.addEventListener('pong', () => {
136-
console.log('server is up');
137-
clearInterval(this.reconnectInterval);
138-
// break -> attempts = 4
139-
attempts = 4;
140-
});
141-
}
142-
}
143-
144-
if (attempts < 3) {
145-
attempts = 0;
146-
console.log('attempts < 3');
147-
window.alert('server is down');
148-
} else {
149-
console.log('attempts > 3');
150-
this.init();
151-
}
152-
}
153-
154-
public createNewWebsocket() {
155-
const { serverUrl, appId } = getServerConfig();
156-
this.socket = new WebSocket(`wss://${serverUrl}/websockets/v3?app_id=${appId}`);
157-
this.derivApi = new DerivAPIBasic({ connection: this.socket });
158-
}
159-
160105
set connection(newConnection: WebSocket) {
161106
this.socket = newConnection;
162107
}

src/contexts/auth/auth.context.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ export interface IAuthContext {
1919
updateCurrentLoginAccount: (userAccount: IUserLoginAccount) => void;
2020
userAccounts: IUserAccounts;
2121
user: IUser;
22-
updateAuthorize;
2322
}
2423

2524
export const AuthContext = React.createContext<IAuthContext | null>(null);

src/contexts/auth/auth.provider.tsx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@ type TAuthProviderProps = {
1717

1818
if (getIsBrowser()) {
1919
apiManager.init();
20-
console.log('auth provider');
2120
}
2221

2322
const AuthProvider = ({ children }: TAuthProviderProps) => {
2423
const [is_logged_in, setIsLoggedIn] = useState(false);
2524
const [is_authorized, setIsAuthorized] = useState(false);
2625
const [is_switching_account, setisSwitchingAccount] = useState(false);
26+
const [is_connected, setIsConnected] = useState(true);
2727

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

4747
const updateAuthorize = useCallback(async () => {
4848
if (currentLoginAccount.token) {
49-
const { authorize } = await apiManager.authorize(currentLoginAccount.token);
49+
const { authorize } = await apiManager.authorize(
50+
currentLoginAccount.token,
51+
setIsConnected,
52+
setIsAuthorized,
53+
);
5054
setIsAuthorized(true);
5155
setisSwitchingAccount(false);
5256
const { account_list, ...user } = authorize;
@@ -56,10 +60,10 @@ const AuthProvider = ({ children }: TAuthProviderProps) => {
5660
}, [currentLoginAccount.token, setUser, setUserAccounts]);
5761

5862
useEffect(() => {
59-
if (!is_authorized) {
63+
if (!is_authorized && is_connected) {
6064
updateAuthorize();
6165
}
62-
}, [is_authorized, updateAuthorize]);
66+
}, [is_authorized, is_connected]);
6367

6468
const updateLoginAccounts = useCallback(
6569
(loginAccounts: IUserLoginAccount[]) => {
@@ -104,7 +108,6 @@ const AuthProvider = ({ children }: TAuthProviderProps) => {
104108
updateCurrentLoginAccount,
105109
userAccounts,
106110
user,
107-
updateAuthorize,
108111
};
109112
}, [
110113
currentLoginAccount,
@@ -116,7 +119,6 @@ const AuthProvider = ({ children }: TAuthProviderProps) => {
116119
updateLoginAccounts,
117120
userAccounts,
118121
user,
119-
updateAuthorize,
120122
]);
121123

122124
return <AuthContext.Provider value={context_object}>{children}</AuthContext.Provider>;

src/contexts/playground/playground.provider.tsx

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
import React, { ReactNode, useEffect, useMemo, useState } from 'react';
2-
import apiManager from '@site/src/configs/websocket';
3-
import { getIsBrowser } from '@site/src/utils';
42
import { PlaygroundContext } from './playground.context';
53
import { TSocketResponseData } from '@site/src/configs/websocket/types';
64
import { TSocketEndpointNames } from '@site/src/configs/websocket/types';
@@ -9,11 +7,6 @@ type TPlaygroundProviderProps = {
97
children: ReactNode;
108
};
119

12-
if (getIsBrowser()) {
13-
apiManager.init();
14-
console.log('PlaygroundProvider');
15-
}
16-
1710
const PlaygroundProvider = <T extends TSocketEndpointNames>({
1811
children,
1912
}: TPlaygroundProviderProps) => {

src/features/Apiexplorer/RequestResponseRenderer/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ function RequestResponseRenderer<T extends TSocketEndpointNames>({
5959
<div className={styles.btnWrapper}>
6060
<Button
6161
color='primary'
62-
// disabled={disableSendRequest(auth) || reqData === ''}
62+
disabled={disableSendRequest(auth) || reqData === ''}
6363
onClick={handleClick}
6464
>
6565
Send Request

0 commit comments

Comments
 (0)