Created
February 26, 2016 13:48
-
-
Save roman01la/0c327a8a8f3c03435d0f to your computer and use it in GitHub Desktop.
Redux WebSockets recipe
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const MODULE_NAME = 'base-app/events/' | |
export const CONNECT_WS = MODULE_NAME.concat('CONNECT_WS') | |
export const DISCONNECT_WS = MODULE_NAME.concat('DISCONNECT_WS') | |
export const SUBSCRIBE_WS = MODULE_NAME.concat('SUBSCRIBE_WS') | |
export const UNSUBSCRIBE_WS = MODULE_NAME.concat('UNSUBSCRIBE_WS') | |
export const EMIT_WS = MODULE_NAME.concat('EMIT_WS') | |
export const NEW_EVENT = MODULE_NAME.concat('NEW_EVENT') | |
export const ADD_EVENT = MODULE_NAME.concat('ADD_EVENT') | |
export function connect(socketID) { | |
return (dispatch) => { | |
return dispatch({ | |
type: CONNECT_WS, | |
socketID | |
}) | |
} | |
} | |
export function disconnect(socketID) { | |
return (dispatch) => { | |
return dispatch({ | |
type: DISCONNECT_WS, | |
socketID | |
}) | |
} | |
} | |
export function subscribe(socketID, event) { | |
return (dispatch) => { | |
return dispatch({ | |
type: SUBSCRIBE_WS, | |
socketID, | |
event | |
}) | |
} | |
} | |
export function unsubscribe(socketID, event) { | |
return (dispatch) => { | |
return dispatch({ | |
type: UNSUBSCRIBE_WS, | |
socketID, | |
event | |
}) | |
} | |
} | |
export function emit(socketID, data) { | |
return (dispatch) => { | |
return dispatch({ | |
type: EMIT_WS, | |
socketID, | |
data | |
}) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { PropTypes, Component } from 'react' | |
import { connect as connectState } from 'react-redux' | |
import { bindActionCreators } from 'redux' | |
import { connect, disconnect, subscribe, unsubscribe } from '../modules/events' | |
import { NEW_EVENT } from '../modules/events' | |
const devTools = __DEV__ ? React.createFactory(require('../containers/dev-tools').default) : () => null | |
class Events extends Component { | |
render() { | |
return ( | |
<div> | |
<button onClick={() => this.props.connect('events')}>Connect to events socket</button> | |
<button onClick={() => this.props.disconnect('events')}>Disconnect from events socket</button> | |
<button onClick={() => this.props.subscribe('events', NEW_EVENT)}>Subscribe to a new events</button> | |
<button onClick={() => this.props.unsubscribe('events', NEW_EVENT)}>Unsubscribe from a new events</button> | |
<ul> | |
{this.props.events.map(({ message }) => <li key={message}>{message}</li>)} | |
</ul> | |
{devTools()} | |
</div> | |
) | |
} | |
} | |
function mapStateToProps(state) { | |
return { | |
events: state.events | |
} | |
} | |
function mapDispatchToProps(dispatch) { | |
return bindActionCreators({ connect, disconnect, subscribe, unsubscribe }, dispatch) | |
} | |
Events.propTypes = { | |
events: PropTypes.array.isRequired, | |
connect: PropTypes.func.isRequired, | |
disconnect: PropTypes.func.isRequired, | |
subscribe: PropTypes.func.isRequired, | |
unsubscribe: PropTypes.func.isRequired | |
} | |
export default connectState(mapStateToProps, mapDispatchToProps)(Events) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import io from 'socket.io-client' | |
import { CONNECT_WS, DISCONNECT_WS, SUBSCRIBE_WS, UNSUBSCRIBE_WS, EMIT_WS } from '../modules/events' | |
let config = {} | |
const sockets = {} | |
function connect(url, socketID) { | |
sockets[socketID] = { | |
connection: io(url) | |
} | |
} | |
function disconnect(socketID) { | |
sockets[socketID].connection.disconnect() | |
sockets[socketID] = undefined | |
} | |
function subscribe(socketID, event, dispatch) { | |
const listener = (data) => dispatch({ type: event, data }) | |
sockets[socketID].listener = listener | |
sockets[socketID].connection.on(event, listener) | |
} | |
function unsubscribe(socketID, event) { | |
sockets[socketID].connection.removeListener(event, sockets[socketID].listener) | |
} | |
function emit(socketID, data) { | |
sockets[socketID].emit(data) | |
} | |
// usage: applyMiddleware(thunk, api, createWSMiddleware({ events: 'http://localhost:3000' })) | |
export default function createWSMiddleware(wsConfig) { | |
config = wsConfig | |
return store => next => action => { | |
const { type, socketID, event, data } = action | |
if (type === CONNECT_WS) { | |
connect(config[socketID], socketID) | |
} | |
if (type === DISCONNECT_WS) { | |
disconnect(socketID) | |
} | |
if (type === SUBSCRIBE_WS) { | |
subscribe(socketID, event, store.dispatch) | |
} | |
if (type === UNSUBSCRIBE_WS) { | |
unsubscribe(socketID, event) | |
} | |
if (type === EMIT_WS) { | |
emit(socketID, data) | |
} | |
return next(action) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as actions from './actions' | |
export * from './actions' | |
const initialState = [] | |
export default function reducer(state = initialState, action = {}) { | |
switch (action.type) { | |
case actions.NEW_EVENT: | |
return state.concat(action.data) | |
default: | |
return state | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment