Last active
October 22, 2018 15:20
-
-
Save OtavioBraga/e244ac0fae3fa1d22ab8eec7e27de627 to your computer and use it in GitHub Desktop.
This file contains hidden or 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 { takeLatest, call, put, race, take } from 'redux-saga/effects' | |
import { eventChannel } from 'redux-saga' | |
import { | |
WS_NEW_EVENT, | |
USER_LOGOUT, | |
WS_CONNECT_FAIL, | |
WS_CONNECT | |
} from '../actions/types' | |
export function * handelWsConnection () { | |
try { | |
// Iniciamos a conexão com o socket | |
const websocket = new WebSocket('wss://echo.websocket.org') | |
// Criamos o channel | |
const eventChannel = yield call(getWsChannel, websocket) | |
// Iniciamos uma corrida que só irá terminar | |
// Quando houver um dispatch da ação USER_LOGOUT | |
const { cancel } = yield race({ | |
task: call(watchMessages, eventChannel), | |
cancel: take(USER_LOGOUT) | |
}) | |
// Se a ação cancel vencer a corrida podemos | |
// chamar o método close do channel. | |
// Ele irá executar o websocket.close() | |
// visto anteriormente. | |
if (cancel) { | |
eventChannel.close() | |
} | |
} catch (error) { | |
yield put({ type: WS_CONNECT_FAIL }) | |
} | |
} | |
function getWsChannel(websocket) { | |
// Devemos retornar o channel pois é | |
// nele que iremos buscar os eventos emitidos | |
return eventChannel(emitter => { | |
websocket.onmessage = event => { | |
emit(event.data) | |
} | |
// O channel tem um método close | |
// que executa esta função ao ser chamado | |
return () => { | |
websocket.close() | |
} | |
}) | |
} | |
export function * watchMessages (eventChannel) { | |
// Executamos indefinidamente | |
while (true) { | |
// Usamos o effect take para ler os eventos do channel | |
const event = yield take(eventChannel) | |
// Enviamos uma ação para nossa store do redux | |
yield put({ type: WS_NEW_EVENT, payload: JSON.parse(event) }) | |
} | |
} | |
// Criamos um watch para fazer a conexão com o ws. | |
// Esse watch será executado quando houver um disptach da ação de tipo WS_CONNECT | |
export default [ | |
takeLatest(WS_CONNECT, handelWsConnection) | |
] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment