Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import { all, takeEvery, take, call, put, select } from 'redux-saga/effects';
- import { eventChannel, delay } from 'redux-saga';
- import { getToken } from './selectors';
- import { ERROR } from '../constants/genericTypes';
- import { WEBSOCKET_ONERROR, // ERRORS
- WEBSOCKET_ERROR_PARSING,
- UNKNOWN_TYPE_OF_INCOMING_ACTION } from '../constants/errors';
- import { NEW_TOKEN, // INCOMING ACTIONS
- CURRENT_TOKEN_IS_OK,
- USERINFO_RECEIVED,
- UNAUTHORIZED,
- LOG } from '../constants/actionTypes';
- import { WEBSOCKET_ONOPEN,
- TOKEN_REQUESTED, // UPCOMING ACTIONS
- SIGN_OUT,
- USERINFO_REQUESTED,
- } from '../constants/actionTypes';
- const createWebSocketConnection = () => new WebSocket(wsURL('/websocket/'))
- export default function* websocketSagas() {
- const socket: any = yield call(createWebSocketConnection)
- yield all([
- watchIncoming(socket),
- watchUpcoming(socket)
- ])
- }
- function incomingWebsocketChannel(socket: any) {
- return eventChannel( emitter => {
- socket.onopen = () => {
- return emitter({ type: WEBSOCKET_ONOPEN })
- }
- socket.onerror = (error: any) => {
- return emitter({ type: ERROR, error: WEBSOCKET_ONERROR, meta: error })
- }
- socket.onmessage = (frame: any) => {
- let action = null
- try {
- action = JSON.parse(frame.data)
- } catch(frame) {
- return emitter({ type: ERROR, error: WEBSOCKET_ERROR_PARSING, meta: frame.data })
- }
- if(action) {
- switch (action.type) {
- case "pong":
- return emitter(action)
- case NEW_TOKEN:
- return emitter(action)
- case CURRENT_TOKEN_IS_OK:
- return emitter(action)
- case USERINFO_RECEIVED:
- return emitter(action)
- case UNAUTHORIZED:
- return emitter(action)
- case LOG:
- return emitter(action)
- default:
- return emitter({ type: ERROR, error: UNKNOWN_TYPE_OF_INCOMING_ACTION, meta: action })
- }
- }
- }
- // unsubscribe function
- return () => {
- console.log('Socket off')
- }
- })
- }
- function* watchIncoming(socket: any) {
- const channel = yield call(incomingWebsocketChannel, socket)
- while (true) {
- const action = yield take(channel)
- yield put(action)
- }
- }
- function* watchUpcoming(socket: any) {
- yield takeEvery(WEBSOCKET_ONOPEN, open, socket)
- yield takeEvery("pong", pong, socket)
- yield takeEvery("ping", send, socket)
- yield takeEvery(TOKEN_REQUESTED, send, socket)
- yield takeEvery(USERINFO_REQUESTED, send, socket)
- yield takeEvery(SIGN_OUT, send, socket)
- }
- function* open(socket: any) {
- yield put({ type: TOKEN_REQUESTED })
- yield delay(1000)
- yield put({ type: "ping" })
- }
- function* pong(socket: any) {
- yield delay(15000)
- yield socket.send(JSON.stringify({ type: "ping" }))
- }
- function* send(socket: any, action: any) {
- action.token = yield select(getToken)
- if(!action.server_meta)
- yield socket.send(JSON.stringify(action))
- }
- const wsURL = (path: any) => { // Thx stackoverflow.com for this fun.
- var protocol = (window.location.protocol === 'https:') ? 'wss://' : 'ws://'
- var url = protocol + window.location.host
- if(window.location.hostname === 'localhost') {
- url += '/' + window.location.pathname.split('/')[1]
- }
- return url + path
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement