redux-saga-sc
This package provides ready to use sagas to connect SocketCluster clients. It can be used to let your server dispatch redux actions on the client and vice verca. Or to sync a shared redux state across multiple nodes or clients.
Examples
- redux-saga-sc-demo - A demo chat app showing redux-saga-sc in action
- epic - React example project, that takes you from fun development to high quality production
Documentation
Sending actions between remote redux stores
You'll notice that this guide does not use the terms "server" and "client". Why? You could use this server to server, client to client, it doesn't matter. Instead you have a "sender" and a "receiver".
The "sender" can emit
something, the "receiver" listens for the emit
and may decide to emit
something back in response.
The "sender" can also request
something from the "receiver" requiring a response of either successType
or failureType
.
socketEmit
action creator
Sending notifications with You can use socketEmit
to dispatch simple actions that does not require a response. If there's a network problem, like if the device switch between a 3G to 4G connection, it'll automatically retry sending the emit
until it gets a delivery notification back from the receiver.
To use it, wrap your action that you want dispatched on the remote redux store like this:
./actions/chat.js
const sendMessage =
Next step is to setup the watcher that will take actions created by socketEmit
and send it over the websocket for us.
./sagas/index.js
const socket = socketCluster { ... // your other sagas }
And the last step is to add the watchRemote
worker to the receiver, in this example the receiver is a SocketCluster workerController:
./web/worker.js
const run = { const app = workerhttpServer workerscServer}
./web/store.js
{ const sagaMiddleware = const store = sagaMiddleware return store}
./web/sagas/index.js
{ ... // your other sagas }
You can setup this on both sides of the websocket if you need the ability to pass actions back and forth. Actions will dispatch like any other action. Meaning you can use
in the sagas of your receiver to act on it. And you can also use RECEIVE_MESSAGE
in your reducers.
The actions you dispatch wrapped in socketEmit
only dispatch on the receiver, not the local redux store.
It will automatically retry if the server does not respond.
By default emits will be done on the "dispatch" event on SocketCluster. You can change this by passing a second argument to socketEmit and use whatever event you want.
Just be sure to set the watchRemote
saga on the receiver to the same event, as that too use 'dispatch' as the default event.
socketRequest
Requesting data with While socketEmit
is useful for notifications and other stuff that you don't need to know the result, only that it was delivered, there's socketRequest
that is suitable for more advanced situations.
When you do a socketRequest
you have to pass both a successType
and failureType
that the receiver must emit back in a given timeframe.
Here's an example:
./actions/auth.js
const signInWithEmailAndPassword =
To dispatch socket requests, setup watchRequests
the same way you did watchEmits
.
You setup the receiver just like you do in the socketEmit
example, using watchRemote
.
There are two important differences though. First of all, unlike socketEmit
, the action you pass in socketRequest
will also dispatch locally. This is to allow for stuff like creating progress spinners and similar.
The other difference is that you need to setup your own watcher that will act on the AUTHENTICATE_REQUESTED
in this example, and return either AUTHENTICATE_SUCCESS
or AUTHENTICATE_FAILURE
.
Here's what it should look like:
./web/sagas/auth.js
{ while true // eslint-disable-line no-constant-condition const payload: successType failureType credentials = try const authToken = catcherr }
Advanced
A little more info on lower level stuff if you need to do more than what the provided watchers and action creators provides out of the box.
createEventChannel
factory to connect to socket events
Using the On the client:
const socket = socketCluster { const chan = while true const action = }
On the server:
socket
createChannelSubscription
factory to connect to socket channels
Using the One of the coolest features of SocketCluster are channels. Especially when you use channels on the Exchange as it allows you to distribute actions both vertically (multiple worker processes) and horizontally (multiple servers).
Since publishing to a channel is very straightforward there's no utility in redux-saga-sc
for that, the example below shows you how it's done (exchange
in these examples are assumed to be scWorker.exchange
passed to the store from your workerController, that's how it's done in redux-saga-sc-demo):
{ while true // eslint-disable-line no-constant-condition const message = }
And here's how createChannelSubscription is implemented to dispatch actions from the channel:
{ const chan = while true // eslint-disable-line no-constant-condition const action = }