From 16a28eca258e07d45c7e2a8ee95368d4eb077d4d Mon Sep 17 00:00:00 2001 From: Jason Date: Wed, 15 Jun 2016 01:18:10 +0800 Subject: [web] websocket --- web/src/js/ducks/websocket.js | 101 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 87 insertions(+), 14 deletions(-) (limited to 'web/src/js/ducks/websocket.js') diff --git a/web/src/js/ducks/websocket.js b/web/src/js/ducks/websocket.js index ebb39cf8..268c9e65 100644 --- a/web/src/js/ducks/websocket.js +++ b/web/src/js/ducks/websocket.js @@ -1,30 +1,103 @@ +import { ConnectionActions } from '../actions.js' +import { AppDispatcher } from '../dispatcher.js' +import * as eventLogActions from './eventLog' +import * as flowActions from './flows' + +const CONNECT = 'WEBSOCKET_CONNECT' const CONNECTED = 'WEBSOCKET_CONNECTED' +const DISCONNECT = 'WEBSOCKET_DISCONNECT' const DISCONNECTED = 'WEBSOCKET_DISCONNECTED' +const ERROR = 'WEBSOCKET_ERROR' +const MESSAGE = 'WEBSOCKET_MESSAGE' +/* we may want to have an error message attribute here at some point */ +const defaultState = { connected: false, socket: null } -const defaultState = { - connected: false, - /* we may want to have an error message attribute here at some point */ -} export default function reducer(state = defaultState, action) { switch (action.type) { + + case CONNECT: + return { ...state, socket: action.socket } + case CONNECTED: - return { - connected: true - } + return { ...state, connected: true } + + case DISCONNECT: + return { ...state, connected: false } + case DISCONNECTED: - return { - connected: false - } + return { ...state, socket: null } + default: return state } } +export function connect() { + return dispatch => { + const socket = new WebSocket(location.origin.replace('http', 'ws') + '/updates') + + // @todo remove this + window.ws = socket + + socket.addEventListener('open', () => dispatch(onConnect())) + socket.addEventListener('close', () => dispatch(onDisconnect())) + socket.addEventListener('message', msg => dispatch(onMessage(msg))) + socket.addEventListener('error', error => dispatch(onError(error))) + + dispatch({ type: CONNECT, socket }) + + return socket + } +} + +export function disconnect() { + return { type: DISCONNECT } +} + +export function onConnect() { + // workaround to make sure that our state is already available. + return dispatch => { + dispatch({ type: CONNECTED }) + dispatch(flowActions.fetchFlows()).then(() => ConnectionActions.open()) + } +} + +export function onDisconnect() { + return dispatch => { + ConnectionActions.close() + dispatch(eventLogActions.addLogEntry('WebSocket connection closed.')) + dispatch({ type: DISCONNECTED }) + } +} + +export function onMessage(msg) { + return dispatch => { + const data = JSON.parse(msg.data) + + AppDispatcher.dispatchServerAction(data) -export function connected() { - return {type: CONNECTED} + switch (data.type) { + + case eventLogActions.UPDATE_LOG: + return dispatch(eventLogActions.updateLogEntries(data)) + + case flowActions.UPDATE_FLOWS: + return dispatch(flowActions.updateFlows(data)) + + default: + console.warn('unknown message', data) + } + + dispatch({ type: MESSAGE, msg }) + } } -export function disconnected() { - return {type: DISCONNECTED} + +export function onError(error) { + // @todo let event log subscribe WebSocketActions.ERROR + return dispatch => { + ConnectionActions.error() + dispatch(eventLogActions.addLogEntry('WebSocket connection error.')) + dispatch({ type: ERROR, error }) + } } -- cgit v1.2.3