dux-socket
v1.0.3
Published
Flexible Socket.IO middleware for Redux applications
Downloads
2
Readme
dux-socket
_,,...,_
.’¯ ’-_
.¯ -
/ \
-----., @ ;
=====| \ |
| } ; _
=====| / / ,~¯ ‘.
-----~’ , / \
~_ ,’~’ \
_,-‘ \
,’ \
,¯ _,..,_ ,~’, ,
‘ ¯ `¯¯ ;
‘ | , ;
‘ ; ._.- /
‘ \ ,`/
‘ ‘, - ‘.’
‘. ‘-.,,.-‘.~
¯~.,_ _,.-~’¯
`’’’’’’’’’¯¯¯
Flexible WebSocket middleware for Redux applications. Maps inbound WebSocket events to Redux actions. Exposes action creators for dispatching actions that should be emitted as socket messages. Works with Socket.IO, as well as native WebSocket implementations!
Installation
npm install dux-socket
Usage
Socket.IO
In your project, define a mapDispatchToSocket
function, which will receive store.dispatch
as its argument, and return an object which maps socket events to arbitrary Redux actions:
const mapDispatchToSocket = (dispatch) => ({
'eventName': (eventData) => dispatch({type: 'SOME_ACTION', data: eventData}),
// using action creators
'otherEvent': (eventData) => dispatch(someAction(eventData)),
});
This works exactly like the mapDispatchToProps
function you are used to from React-Redux's connect
API. The functions defined in this map will be invoked with the socket event payload as the argument.
When creating your store & applying middleware, add socketMiddleware
in the usual way, supplying the mapDispatchToSocket
function defined above, & an initialized Socket
object:
import {createStore, applyMiddleware} from 'redux';
import io from 'socket.io-client'
import {socketMiddleware} from 'dux-socket';
const socket = io('http://socket-url');
const store = createStore(
appReducer,
applyMiddleware(
/* ... other middlewares here ... */
socketMiddleware(mapDispatchToSocket, socket)
)
);
Emitting socket events
Simply dispatch
using the emit(eventName, data)
action creator supplied by dux-socket
in order to emit a socket event:
import {emit} from 'dux-socket';
dispatch(emit('someAction', {foo: bar}))
Native WebSockets
Since native WebSocket implementations don't have a concept of named events, your mapDispatchToSocket
function, and the way you send data work a bit differently. Simply supply functions for the native WebSocket event handlers onopen
, onmessage
, and onerror
where relevant to your application, and map them to Redux actions however you see fit:
import {socketMiddleware} from 'dux-socket';
import {createStore, applyMiddleware} from 'redux';
let socket = new WebSocket('ws://localhost:4242');
const mapDispatchToSocket = (dispatch) => ({
'onmessage': (event) => dispatch({ type: 'CHAT_MESSAGE', message: event.data }),
'onerror': (event) => dispatch({ type: 'ERROR', msg: 'Connection error!' })
});
const store = createStore(
appReducer,
applyMiddleware(socketMiddleware(mapDispatchToSocket, socket))
);
Sending text data
Use the send(data)
action creator to send data over a native WebSocket connection.
import {send} from 'dux-socket';
dispatch(send('some data!'))
Asynchronous socket initialization
You may want to include some asynchronously-resolved data (ie. route parameters) in your initial connection with the WebSocket server. To do this, simply don't supply a WebSocket object when applying the socketMiddleware
:
const store = createStore(
appReducer,
applyMiddleware(socketMiddleware(mapDispatchToSocket))
);
And dispatch an initSocket
event when you are ready to initialize the socket! Supply this action creator with either a Socket.IO object or a native WebSocket object.
import io from 'socket.io-client'
import {initSocket} from 'dux-socket';
import store from '../store';
class SomeComponent extends Component {
componentDidMount() {
let socket = io('http://socket-url', { foo: 'bar' });
store.dispatch(initSocket(socket));
}
}
Motivation
Flexibility! The main goals for a flexible Redux/WebSocket middleware are:
- Event-agnostic: You should be able to integrate an existing Redux application with an existing WebSocket server without re-writing your server-initiated events or your client-side reducers.
- Asynchronous: You should be able to (optionally) initialize your web socket connection asynchronously. This is useful if you want to include some resolved data in your handshake with the web socket server, (ie. router parameters)
- Native WebSocket support: You should be able to (optionally) use a native WebSocket implementation, in case you don't want to use Socket.IO
Other middleware libraries emit a single Redux action for all Socket events. This leads to tightly coupled reducers & nested branching over the event types within your reducer cases. dux-socket solves this problem by invoking client-defined actions according to the map provided:
Contributing
We welcome Your interest in the American Express Open Source Community on Github. Any Contributor to any Open Source Project managed by the American Express Open Source Community must accept and sign an Agreement indicating agreement to the terms below. Except for the rights granted in this Agreement to American Express and to recipients of software distributed by American Express, You reserve all right, title, and interest, if any, in and to Your Contributions. Please fill out the Agreement.
License
Any contributions made under this project will be governed by the Apache License 2.0.
Code of Conduct
This project adheres to the American Express Community Guidelines. By participating, you are expected to honor these guidelines.