Another dead-simple middleware which allows you to connect Redux and Socket.io.
It uses meta
property of your action object to recognize whether send it to backend, or not.
- Whenever you want to send an event from Client to your Backend through socket.io,
use
store.dispatch
with regularaction
withmeta
object (see example actionCreator.js) - Whenever you want to send and handle an event from your Backend to
Client - emit it on backend with socket.io in a form of regular
action
and it will be handled by forwarding it tostore.dispatch()
- your reducers should take care of the rest.
Important side note - action object send thorough Socket.io must be standard javascript object literal. It can't be a function (so unfortunately thunk drops out).
npm install --save redux-socket.io-middleware
store.js
import socketIO from 'socket.io-client';
import socketIoMiddleware from 'redux-socket.io-middleware'
const reducers = (...);
const io = socketIO.connect(`http://localhost:3030`);
const store = createStore(
reducers,
applyMiddleware(
socketIoMiddleware(io)
)
);
actionCreator.js
function addUserRequest(user){
return {
type: "ADD_USER_REQUEST",
meta: {remote: true},
user
}
}
function addUserRequestSuccess() {
return {
type: "ADD_USER_REQUEST_SUCCESS",
}
}
function addUserRequestFailure() {
return {
type: "ADD_USER_REQUEST_FAILURE",
}
}
And then you dispatch this type of action like any other:
yourReactComponentContainer.js
const mapDispatchToProps = function (dispatch) {
return {
addUserRequest: (user) => dispatch(actionCreator.addUserRequest(user)),
}
}
If we share actionCreator.js between client and server we can youse it like below. Otherwise, just create action by hand.
userController.js
io.on('connection', function (socket) {
socket.on("action", function (action) {
switch (action.type) {
case "ADD_USER_REQUEST":
return userService.save(action.user).then(
(user) => io.emit('action', actionCreator.addUserRequestSuccess()),
(err) => io.emit('action', actionCreator.addUserRequestFailure())
);
}
})
});
You can configure the name of channel which will be used for sending websocket messages.
Default value is action
. To change it, simply add second parameter when registering middleware:
import socketIoMiddleware from './redux-socket.io-middleware'
const store = createStore(
reducers,
applyMiddleware(
socketIoMiddleware(io, "myRandomChannel")
)
);
and then on your backend side, listen on that string:
io.on('connection', function (socket) {
socket.on("myRandomChannel", function (action) {
/// ...
})
});
Yeah, I know that this readme is much longer than a code itself :)