aboutsummaryrefslogtreecommitdiffstats
path: root/web
diff options
context:
space:
mode:
Diffstat (limited to 'web')
-rw-r--r--web/src/js/app.jsx12
-rw-r--r--web/src/js/components/ProxyApp.jsx28
-rw-r--r--web/src/js/connection.js45
-rw-r--r--web/src/js/ducks/websocket.js101
4 files changed, 110 insertions, 76 deletions
diff --git a/web/src/js/app.jsx b/web/src/js/app.jsx
index 8fa52a00..643bb8b7 100644
--- a/web/src/js/app.jsx
+++ b/web/src/js/app.jsx
@@ -1,16 +1,15 @@
-import React from "react"
+import React from 'react'
import { render } from 'react-dom'
import { applyMiddleware, createStore } from 'redux'
import { Provider } from 'react-redux'
import createLogger from 'redux-logger'
import thunkMiddleware from 'redux-thunk'
-import { Route, Router as ReactRouter, hashHistory, Redirect } from "react-router"
+import { Route, Router as ReactRouter, hashHistory, Redirect } from 'react-router'
-import Connection from "./connection"
-import ProxyApp from "./components/ProxyApp"
+import ProxyApp from './components/ProxyApp'
import MainView from './components/MainView'
import rootReducer from './ducks/index'
-import { addLogEntry } from "./ducks/eventLog"
+import { addLogEntry } from './ducks/eventLog'
// logger must be last
const store = createStore(
@@ -18,14 +17,13 @@ const store = createStore(
applyMiddleware(thunkMiddleware, createLogger())
)
+// @todo move to ProxyApp
window.addEventListener('error', msg => {
store.dispatch(addLogEntry(msg))
})
// @todo remove this
document.addEventListener('DOMContentLoaded', () => {
- window.ws = new Connection("/updates", store.dispatch)
-
render(
<Provider store={store}>
<ReactRouter history={hashHistory}>
diff --git a/web/src/js/components/ProxyApp.jsx b/web/src/js/components/ProxyApp.jsx
index 81272268..2aedba7c 100644
--- a/web/src/js/components/ProxyApp.jsx
+++ b/web/src/js/components/ProxyApp.jsx
@@ -1,14 +1,15 @@
-import React, { Component, PropTypes } from "react"
-import ReactDOM from "react-dom"
-import _ from "lodash"
+import React, { Component, PropTypes } from 'react'
+import ReactDOM from 'react-dom'
+import _ from 'lodash'
import { connect } from 'react-redux'
-import { Splitter } from "./common.js"
-import Header from "./Header"
-import EventLog from "./EventLog"
-import Footer from "./Footer"
-import { SettingsStore } from "../store/store.js"
-import { Key } from "../utils.js"
+import { Splitter } from './common.js'
+import { connect as wsConnect } from '../ducks/websocket'
+import Header from './Header'
+import EventLog from './EventLog'
+import Footer from './Footer'
+import { SettingsStore } from '../store/store.js'
+import { Key } from '../utils.js'
class ProxyAppMain extends Component {
@@ -37,6 +38,10 @@ class ProxyAppMain extends Component {
this.onSettingsChange = this.onSettingsChange.bind(this)
}
+ componentWillMount() {
+ this.props.wsConnect()
+ }
+
/**
* @todo move to actions
*/
@@ -166,5 +171,8 @@ class ProxyAppMain extends Component {
export default connect(
state => ({
showEventLog: state.eventLog.visible
- })
+ }),
+ {
+ wsConnect,
+ }
)(ProxyAppMain)
diff --git a/web/src/js/connection.js b/web/src/js/connection.js
deleted file mode 100644
index 5961909e..00000000
--- a/web/src/js/connection.js
+++ /dev/null
@@ -1,45 +0,0 @@
-import {ConnectionActions} from "./actions.js";
-import {AppDispatcher} from "./dispatcher.js";
-import * as webSocketActions from "./ducks/websocket"
-import * as eventLogActions from "./ducks/eventLog"
-import * as flowActions from "./ducks/flows"
-
-export default function Connection(url, dispatch) {
- if (url[0] === "/") {
- url = location.origin.replace("http", "ws") + url;
- }
-
- var ws = new WebSocket(url);
- ws.onopen = function () {
- dispatch(webSocketActions.connected())
- dispatch(flowActions.fetchFlows())
- // workaround to make sure that our state is already available.
- .then(() => {
- console.log("flows are loaded now")
- ConnectionActions.open()
- })
- dispatch(eventLogActions.fetchLogEntries())
- };
- ws.onmessage = function (m) {
- var message = JSON.parse(m.data);
- AppDispatcher.dispatchServerAction(message);
- switch (message.type) {
- case eventLogActions.UPDATE_LOG:
- return dispatch(eventLogActions.updateLogEntries(message))
- case flowActions.UPDATE_FLOWS:
- return dispatch(flowActions.updateFlows(message))
- default:
- console.warn("unknown message", message)
- }
- };
- ws.onerror = function () {
- ConnectionActions.error();
- dispatch(eventLogActions.addLogEntry("WebSocket connection error."));
- };
- ws.onclose = function () {
- ConnectionActions.close();
- dispatch(eventLogActions.addLogEntry("WebSocket connection closed."));
- dispatch(webSocketActions.disconnected());
- };
- return ws;
-} \ No newline at end of file
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 })
+ }
}