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

Commit 5f3a434

Browse files
feat: websocket reconnection draft logic without auth
1 parent c25449a commit 5f3a434

File tree

5 files changed

+84
-7
lines changed

5 files changed

+84
-7
lines changed

src/configs/websocket/index.ts

Lines changed: 78 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,25 @@ 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';
1112

1213
export type TDerivApi = {
1314
send: (...requestData: unknown[]) => Promise<unknown>;
1415
subscribe: (...requestData: unknown[]) => Observable<object>;
1516
authorize: (requestData: AuthorizeRequest) => Promise<AuthorizeResponse>;
1617
};
1718

19+
let attempts = 10;
20+
const RECONNECT_INTERVAL = attempts * 1000;
1821
const PING_INTERVAL = 12000;
22+
const is_connected_before = false;
23+
// const { updateAuthorize } = useAuthContext();
1924

2025
export class ApiManager {
2126
private socket: WebSocket;
2227
private derivApi: TDerivApi;
2328
private pingInterval: NodeJS.Timer;
29+
private reconnectInterval: NodeJS.Timer;
2430

2531
public static instance: ApiManager;
2632
public static getInstance() {
@@ -31,6 +37,7 @@ export class ApiManager {
3137
}
3238

3339
public init() {
40+
console.log('init called');
3441
if (!this.socket) {
3542
const { serverUrl, appId } = getServerConfig();
3643
this.socket = new WebSocket(`wss://${serverUrl}/websockets/v3?app_id=${appId}`);
@@ -62,19 +69,30 @@ export class ApiManager {
6269
if (this.pingInterval) {
6370
clearInterval(this.pingInterval);
6471
}
72+
if (this.reconnectInterval) {
73+
clearInterval(this.reconnectInterval);
74+
}
6575
this.socket.addEventListener('open', () => {
6676
this.pingInterval = setInterval(() => {
6777
this.socket.send(JSON.stringify({ ping: 1 }));
6878
}, PING_INTERVAL);
79+
// if(is_connected_before) updateAuthorize();
6980
});
7081

71-
this.socket.addEventListener('close', () => {
72-
clearInterval(this.pingInterval);
73-
});
74-
75-
this.socket.addEventListener('error', () => {
82+
this.socket.onclose = () => {
83+
// if (!is_connected_before) {
84+
// is_connected_before = true;
85+
// }
7686
clearInterval(this.pingInterval);
77-
});
87+
this.socket = null;
88+
if (attempts > 0) {
89+
this.reconnectInterval = setTimeout(this.init.bind(this), RECONNECT_INTERVAL);
90+
attempts -= 1;
91+
} else {
92+
window.alert('server down!!!');
93+
clearInterval(this.reconnectInterval);
94+
}
95+
};
7896
}
7997

8098
public reset(appId: string, url: string, registerKeepAlive = false) {
@@ -85,6 +103,60 @@ export class ApiManager {
85103
}
86104
}
87105

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+
88160
set connection(newConnection: WebSocket) {
89161
this.socket = newConnection;
90162
}

src/contexts/auth/auth.context.tsx

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

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

src/contexts/auth/auth.provider.tsx

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

1818
if (getIsBrowser()) {
1919
apiManager.init();
20+
console.log('auth provider');
2021
}
2122

2223
const AuthProvider = ({ children }: TAuthProviderProps) => {
@@ -103,6 +104,7 @@ const AuthProvider = ({ children }: TAuthProviderProps) => {
103104
updateCurrentLoginAccount,
104105
userAccounts,
105106
user,
107+
updateAuthorize,
106108
};
107109
}, [
108110
currentLoginAccount,
@@ -114,6 +116,7 @@ const AuthProvider = ({ children }: TAuthProviderProps) => {
114116
updateLoginAccounts,
115117
userAccounts,
116118
user,
119+
updateAuthorize,
117120
]);
118121

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

src/contexts/playground/playground.provider.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ type TPlaygroundProviderProps = {
1111

1212
if (getIsBrowser()) {
1313
apiManager.init();
14+
console.log('PlaygroundProvider');
1415
}
1516

1617
const PlaygroundProvider = <T extends TSocketEndpointNames>({

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)