Skip to content

Commit

Permalink
change(Restaurant app): connect to centrifugo based on the app state …
Browse files Browse the repository at this point in the history
…(active, background etc.)
  • Loading branch information
vladimir-8 committed Nov 21, 2024
1 parent 5f371d3 commit c8770bb
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 80 deletions.
9 changes: 1 addition & 8 deletions src/navigation/restaurant/Dashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ import {
} from '../../redux/Restaurant/selectors';
import PushNotification from '../../notifications';
import OrdersToPrintQueue from './components/OrdersToPrintQueue';
import { connect as connectCentrifugo } from '../../redux/middlewares/CentrifugoMiddleware/actions';
import BasicSafeAreaView from '../../components/BasicSafeAreaView'
import BasicSafeAreaView from '../../components/BasicSafeAreaView';

const RNSound = NativeModules.RNSound;

Expand Down Expand Up @@ -65,12 +64,6 @@ export default function DashboardPage({ navigation, route }) {
};
}, []);

useEffect(() => {
if (!isCentrifugoConnected) {
dispatch(connectCentrifugo());
}
}, [dispatch, isCentrifugoConnected]);

useEffect(() => {
if (route.params?.loadOrders ?? true) {
dispatch(
Expand Down
10 changes: 3 additions & 7 deletions src/redux/App/reducers.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,7 @@
import { AppState } from 'react-native';
import Config from 'react-native-config';

import {
CENTRIFUGO_MESSAGE,
CONNECTED,
DISCONNECTED,
} from '../middlewares/CentrifugoMiddleware';
import { connected, disconnected } from '../middlewares/CentrifugoMiddleware';

import {
ACCEPT_PRIVACY_POLICY,
Expand Down Expand Up @@ -172,13 +168,13 @@ export default (state = initialState, action = {}) => {
loading: action.payload,
};

case CONNECTED:
case connected.type:
return {
...state,
isCentrifugoConnected: true,
};

case DISCONNECTED:
case disconnected.type:
return {
...state,
isCentrifugoConnected: false,
Expand Down
13 changes: 5 additions & 8 deletions src/redux/middlewares/CentrifugoMiddleware/actions.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
import { createAction } from 'redux-actions';

import { createAction } from '@reduxjs/toolkit';
import { updateTask } from '../../Dispatch/actions';

export const CONNECT = '@centrifugo/CONNECT';
export const CENTRIFUGO_MESSAGE = '@centrifugo/MESSAGE';
export const CONNECTED = '@centrifugo/CONNECTED';
export const DISCONNECTED = '@centrifugo/DISCONNECTED';

export const connect = createAction(CONNECT);
export const connect = createAction('@centrifugo/CONNECT');
export const disconnect = createAction('@centrifugo/DISCONNECT');

export const connected = createAction(CONNECTED);
export const disconnected = createAction(DISCONNECTED);
export const connected = createAction('@centrifugo/CONNECTED');
export const disconnected = createAction('@centrifugo/DISCONNECTED');

export const _message = createAction(CENTRIFUGO_MESSAGE);

Expand Down
169 changes: 112 additions & 57 deletions src/redux/middlewares/CentrifugoMiddleware/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@ import parseUrl from 'url-parse';

import {
CENTRIFUGO_MESSAGE,
CONNECT,
CONNECTED,
DISCONNECTED,
connect,
connected,
disconnect,
disconnected,
message,
} from './actions';
Expand All @@ -16,81 +15,137 @@ import {
selectHttpClient,
selectHttpClientHasCredentials,
selectIsAuthenticated,
selectLoggedInUser,
selectUser,
} from '../../App/selectors';
import { LOGOUT_SUCCESS } from '../../App/actions';
import { LOGOUT_SUCCESS, appStateChanged } from '../../App/actions';

const isCentrifugoAction = ({ type }) => [CONNECT].some(x => x === type);
function shouldManageConnectionBasedOnAppState(getState, action) {
const state = getState();

export default ({ getState, dispatch }) => {
let centrifuge = null;
const user = selectLoggedInUser(state);

if (!user) {
return false;
}

// For now this method is used only for restaurant users
return user.hasRole('ROLE_RESTAURANT');
}

function shouldConnectBasedOnAppState(getState, action) {
if (!shouldManageConnectionBasedOnAppState(getState, action)) {
return false;
}

if (action.type !== appStateChanged.type) {
return false;
}

return action.payload === 'active';
}

function shouldDisconnectBasedOnAppState(getState, action) {
if (!shouldManageConnectionBasedOnAppState(getState, action)) {
return false;
}

if (action.type !== appStateChanged.type) {
return false;
}

return action.payload !== 'active';
}

let centrifuge = null;
let subscription = null;

export default ({ getState, dispatch }) => {
return next => action => {
if (action.type === LOGOUT_SUCCESS) {
const result = next(action);
dispatch(disconnect());
return next(action);
}

if (
action.type === connect.type ||
shouldConnectBasedOnAppState(getState, action)
) {
const state = getState();

if (
!selectIsAuthenticated(state) ||
!selectHttpClientHasCredentials(state)
) {
return next(action);
}

if (centrifuge && centrifuge.isConnected()) {
centrifuge.disconnect();
centrifuge = null;
return next(action);
}

return result;
}
const httpClient = selectHttpClient(state);
const baseURL = selectBaseURL(state);
const user = selectUser(state);

httpClient.get('/api/centrifugo/token').then(tokenResponse => {
const url = parseUrl(baseURL);
const protocol = url.protocol === 'https:' ? 'wss' : 'ws';

centrifuge = new Centrifuge(
`${protocol}://${url.hostname}/centrifugo/connection/websocket`,
{
debug: __DEV__,
onRefresh: function (ctx, cb) {
httpClient
.post('/api/centrifugo/token/refresh')
.then(refreshResponse => {
// @see https://github.com/centrifugal/centrifuge-js#refreshendpoint
// Data must be like {"status": 200, "data": {"token": "JWT"}} - see
// type definitions in dist folder. Note that setting status to 200 is
// required at moment. Any other status will result in refresh process
// failure so client will eventually be disconnected by server.
cb({ status: 200, data: { token: refreshResponse.token } });
});
},
},
);

centrifuge.setToken(tokenResponse.token);

centrifuge.on('connect', context => dispatch(connected(context)));
centrifuge.on('disconnect', context => dispatch(disconnected(context)));

subscription = centrifuge.subscribe(
`${tokenResponse.namespace}_events#${user.username}`,
msg => dispatch(message(msg.data.event)),
);

centrifuge.connect();
});

if (!isCentrifugoAction(action)) {
return next(action);
}

const state = getState();

if (
!selectIsAuthenticated(state) ||
!selectHttpClientHasCredentials(state)
action.type === disconnect.type ||
shouldDisconnectBasedOnAppState(getState, action)
) {
if (subscription) {
subscription.unsubscribe();
subscription.removeAllListeners();
subscription = null;
}

if (centrifuge && centrifuge.isConnected()) {
centrifuge.disconnect();
centrifuge = null;
}
return next(action);
}

const httpClient = selectHttpClient(state);
const baseURL = selectBaseURL(state);
const user = selectUser(state);

httpClient.get('/api/centrifugo/token').then(tokenResponse => {
const url = parseUrl(baseURL);
const protocol = url.protocol === 'https:' ? 'wss' : 'ws';

centrifuge = new Centrifuge(
`${protocol}://${url.hostname}/centrifugo/connection/websocket`,
{
debug: __DEV__,
onRefresh: function (ctx, cb) {
httpClient
.post('/api/centrifugo/token/refresh')
.then(refreshResponse => {
// @see https://github.com/centrifugal/centrifuge-js#refreshendpoint
// Data must be like {"status": 200, "data": {"token": "JWT"}} - see
// type definitions in dist folder. Note that setting status to 200 is
// required at moment. Any other status will result in refresh process
// failure so client will eventually be disconnected by server.
cb({ status: 200, data: { token: refreshResponse.token } });
});
},
},
);
centrifuge.setToken(tokenResponse.token);

centrifuge.on('connect', context => dispatch(connected(context)));
centrifuge.on('disconnect', context => dispatch(disconnected(context)));

centrifuge.subscribe(
`${tokenResponse.namespace}_events#${user.username}`,
msg => dispatch(message(msg.data.event)),
);

centrifuge.connect();
});

return next(action);
};
};

export { CENTRIFUGO_MESSAGE, CONNECTED, DISCONNECTED, connected, disconnected };
export { CENTRIFUGO_MESSAGE, connected, disconnected };

0 comments on commit c8770bb

Please sign in to comment.