Handle connection loss gracefully
This commit is contained in:
parent
54030bb341
commit
a1aa140848
|
@ -1,5 +1,10 @@
|
|||
export const SOCKET_CONNECTED = "SOCKET_CONNECTED";
|
||||
export const SOCKET_DISCONNECTED = "SOCKET_DISCONNECTED";
|
||||
export const SOCKET_STATE = {
|
||||
CONNECTED: "SOCKET_CONNECTED",
|
||||
CONNECTING: "SOCKET_CONNECTING",
|
||||
DISCONNECTED: "SOCKET_DISCONNECTED"
|
||||
};
|
||||
|
||||
export const socket_connected = () => ({ type: SOCKET_CONNECTED });
|
||||
export const socket_disconnected = () => ({ type: SOCKET_DISCONNECTED });
|
||||
export const SOCKET_UPDATE = "SOCKET_UPDATE";
|
||||
|
||||
export const socket_update = (state, reason=null) =>
|
||||
({ type: SOCKET_UPDATE, state, reason });
|
||||
|
|
10
src/index.js
10
src/index.js
|
@ -6,21 +6,25 @@ import { ConnectedRouter } from 'react-router-redux';
|
|||
import 'preact/devtools';
|
||||
import './polyfills';
|
||||
|
||||
import store, { history } from './store';
|
||||
import store, { create, history } from './store';
|
||||
import scss from '../scss/main.scss';
|
||||
import { ws_init } from './socket';
|
||||
import { filter_subscribe } from './actions/filter_subscribe';
|
||||
import { socket_connected, socket_disconnected } from './actions/socket';
|
||||
import { socket_update, SOCKET_STATE } from './actions/socket';
|
||||
|
||||
import Nav from './ui/navigation';
|
||||
import Main from './ui/main';
|
||||
import Connection from './ui/connection';
|
||||
|
||||
export function initialize(uri) {
|
||||
store.dispatch(socket_update(SOCKET_STATE.CONNECTING));
|
||||
ws_init(uri, () => {
|
||||
store.dispatch(socket_connected());
|
||||
store.dispatch(socket_update(SOCKET_STATE.CONNECTED));
|
||||
store.dispatch(filter_subscribe());
|
||||
store.dispatch(filter_subscribe('server'));
|
||||
}, () => {
|
||||
store.dispatch(socket_update(SOCKET_STATE.DISCONNECTED,
|
||||
"You were disconnected."));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { UPDATE_RESOURCES, RESOURCES_REMOVED } from '../actions/resources';
|
||||
import { SOCKET_STATE, SOCKET_UPDATE } from '../actions/socket';
|
||||
|
||||
export default function resourceReducer(type) {
|
||||
return (state = {}, action) => {
|
||||
|
@ -17,6 +18,9 @@ export default function resourceReducer(type) {
|
|||
return Object.values(state)
|
||||
.filter(r => action.ids.indexOf(r.id) === -1)
|
||||
.reduce((s, r) => ({ ...s, [r.id]: r }), {});
|
||||
case SOCKET_UPDATE:
|
||||
const _state = action.state;
|
||||
return _state === SOCKET_STATE.CONNECTING ? {} : state;
|
||||
}
|
||||
return state;
|
||||
};
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
import { SOCKET_CONNECTED, SOCKET_DISCONNECTED } from '../actions/socket';
|
||||
import { SOCKET_STATE, SOCKET_UPDATE } from '../actions/socket';
|
||||
|
||||
export default function socket(state = { connected: false }, action) {
|
||||
export default function socket(_state = {
|
||||
state: SOCKET_STATE.DISCONNECTED,
|
||||
reason: null
|
||||
}, action) {
|
||||
const { state, reason } = action;
|
||||
switch (action.type) {
|
||||
case SOCKET_CONNECTED:
|
||||
return { ...state, connected: true };
|
||||
case SOCKET_DISCONNECTED:
|
||||
return { ...state, connected: false };
|
||||
case SOCKET_UPDATE:
|
||||
return { ..._state, state, reason };
|
||||
default:
|
||||
return state;
|
||||
return _state;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,9 +35,9 @@ function ws_recv(e) {
|
|||
handler && handler(msg);
|
||||
}
|
||||
|
||||
export function ws_init(uri, cb) {
|
||||
export function ws_init(uri, open, close) {
|
||||
ws = new WebSocket(uri);
|
||||
ws.addEventListener("open", cb);
|
||||
ws.addEventListener("open", open);
|
||||
ws.addEventListener("message", ws_recv);
|
||||
ws.addEventListener("close", () => console.log("ws closed"));
|
||||
ws.addEventListener("close", close);
|
||||
}
|
||||
|
|
14
src/store.js
14
src/store.js
|
@ -13,10 +13,16 @@ export const history = createHistory();
|
|||
const _compose =
|
||||
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
|
||||
|| compose;
|
||||
const store = createStore(
|
||||
reducer,
|
||||
_compose(applyMiddleware(thunk, routerMiddleware(history))),
|
||||
);
|
||||
|
||||
let store;
|
||||
|
||||
export const create = () => {
|
||||
store = createStore(
|
||||
reducer,
|
||||
_compose(applyMiddleware(thunk, routerMiddleware(history))),
|
||||
);
|
||||
};
|
||||
create();
|
||||
|
||||
if (module.hot) {
|
||||
// Enable webpack hot module replacement for reducers
|
||||
|
|
|
@ -1,14 +1,17 @@
|
|||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import {
|
||||
Alert,
|
||||
Card,
|
||||
CardHeader,
|
||||
CardBlock,
|
||||
FormGroup,
|
||||
Progress,
|
||||
Label,
|
||||
Input
|
||||
} from 'reactstrap';
|
||||
import { initialize } from '..';
|
||||
import { SOCKET_STATE } from '../actions/socket';
|
||||
|
||||
class ConnectionOverlay extends Component {
|
||||
constructor() {
|
||||
|
@ -25,15 +28,29 @@ class ConnectionOverlay extends Component {
|
|||
|
||||
render() {
|
||||
const { socket } = this.props;
|
||||
if (socket.connected) {
|
||||
if (socket.state === SOCKET_STATE.CONNECTED) {
|
||||
return null;
|
||||
}
|
||||
if (socket.state === SOCKET_STATE.CONNECTING) {
|
||||
return (
|
||||
<div className="connection-overlay">
|
||||
<Card>
|
||||
<CardHeader>Connect to synapse</CardHeader>
|
||||
<CardBlock>
|
||||
<p className="text-center">Connecting...</p>
|
||||
<Progress value={100} animated />
|
||||
</CardBlock>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
const { uri, autoconnect } = this.state;
|
||||
return (
|
||||
<div className="connection-overlay">
|
||||
<Card>
|
||||
<CardHeader>Connect to synapse</CardHeader>
|
||||
<CardBlock>
|
||||
{socket.reason && <Alert color="info">{socket.reason}</Alert>}
|
||||
<FormGroup>
|
||||
<Label for="socket-uri">Server URI</Label>
|
||||
<Input
|
||||
|
@ -56,7 +73,7 @@ class ConnectionOverlay extends Component {
|
|||
<button
|
||||
className="btn btn-primary"
|
||||
onClick={() => initialize(this.state.uri)}
|
||||
>Connect</button>
|
||||
>{socket.reason ? "Reconnect" : "Connect"}</button>
|
||||
</CardBlock>
|
||||
</Card>
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue
Block a user