Created
March 9, 2018 15:45
-
-
Save ChristiaanScheermeijer/617ba5f4e97683674a65e6d9723218da to your computer and use it in GitHub Desktop.
Redux Saga with WebSocket
This file contains 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 { eventChannel, END } from 'redux-saga'; | |
import { call, put, take, fork, cancel, cancelled } from 'redux-saga/effects'; | |
import * as LiveDataActions from '../../redux/LiveData/LiveData.actions'; | |
import * as LiveDataTypes from '../../redux/LiveData/LiveData.types'; | |
// Use this to actually throw exceptions, allows for easier debugging. | |
const dispatch = put.resolve; | |
function createWebSocketConnection() { | |
return new Promise((resolve, reject) => { | |
const socket = new WebSocket("ws://localhost:1555"); | |
socket.onopen = function () { | |
resolve(socket); | |
}; | |
socket.onerror = function (evt) { | |
reject(evt); | |
} | |
}); | |
} | |
function createSocketChannel(socket) { | |
return eventChannel(emit => { | |
socket.onmessage = (event) => { | |
emit(event.data) | |
}; | |
socket.onclose = () => { | |
emit(END); | |
}; | |
const unsubscribe = () => { | |
socket.onmessage = null; | |
}; | |
return unsubscribe; | |
}); | |
} | |
function* listenForSocketMessages() { | |
let socket; | |
let socketChannel; | |
try { | |
socket = yield call(createWebSocketConnection); | |
socketChannel = yield call(createSocketChannel, socket); | |
// tell the application that we have a connection | |
yield dispatch(LiveDataActions.connectionSuccess()); | |
while (true) { | |
// wait for a message from the channel | |
const payload = yield take(socketChannel); | |
// a message has been received, dispatch an action with the message payload | |
yield dispatch(LiveDataActions.incomingEvent(payload)); | |
} | |
} catch (error) { | |
yield dispatch(LiveDataActions.connectionError('Error while connecting to the WebSocket')); | |
} finally { | |
if (yield cancelled()) { | |
// close the channel | |
socketChannel.close(); | |
// close the WebSocket connection | |
socket.close(); | |
} else { | |
yield dispatch(LiveDataActions.connectionError('WebSocket disconnected')); | |
} | |
} | |
} | |
export function* connect() { | |
// starts the task in the background | |
const socketTask = yield fork(listenForSocketMessages); | |
// when DISCONNECT action is dispatched, we cancel the socket task | |
yield take(LiveDataTypes.DISCONNECT); | |
yield cancel(socketTask); | |
yield dispatch(LiveDataActions.disconnectSuccess()); | |
} |
How would I implement socket.send
method?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
You should consider the reconnection case.