Skip to content

Instantly share code, notes, and snippets.

@sardaukar sardaukar/connection.js Secret
Created Nov 24, 2017

Embed
What would you like to do?
Websocket Reduxjs middleware
// src/actions/connection.js
import {
CONNECTION_OPENING,
CONNECTION_SUBSCRIBING,
CONNECTION_READY,
} from './constants';
export function opening() {
return {
type: CONNECTION_OPENING,
}
}
export function subscribing() {
return {
type: CONNECTION_SUBSCRIBING,
};
}
export function ready() {
return {
type: CONNECTION_READY,
};
}
// src/middlewares/websocket.js
import * as connectionActions from '../actions/connection';
let socket;
const onOpen = (ws, store, code) => evt => {
console.log("WS OPEN");
}
const onClose = (ws, store) => evt => {
console.log("WS CLOSE");
}
const onMessage = (ws, store) => evt => {
let msg = JSON.parse(evt.data);
if (msg.type === "ping") {
return;
}
console.log("FROM RAILS: ", msg);
const connectionState = store.getState().connection.state;
const gameCode = store.getState().game.code;
if (connectionState === 'OPENING') {
if (msg.type === 'welcome') {
store.dispatch(connectionActions.subscribing());
const msg = {
command: 'subscribe',
identifier: JSON.stringify({
channel: 'GameChannel',
}),
};
socket.send(JSON.stringify(msg));
} else {
console.error('WS ERRORED!');
}
} else if (connectionState === 'SUBSCRIBING') {
if (msg.type === 'confirm_subscription') {
store.dispatch(connectionActions.ready());
const msg = {
command: 'message',
identifier: JSON.stringify({
channel: 'GameChannel',
}),
data: JSON.stringify({
action: 'join',
code: gameCode,
}),
};
socket.send(JSON.stringify(msg));
} else {
console.error('WS ERRORED!');
}
} else {
store.dispatch(msg.message);
}
}
export default store => next => action => {
const match = /^WS_(.+)$/.exec(action.type);
if (!match) {
return next(action);
}
const wsAction = { ...action, type: match[1] };
if (wsAction.type === 'CONNECT') {
if (socket) {
socket.close();
}
const { code } = wsAction.payload;
socket = new WebSocket(process.env.REACT_APP_WS_URL);
socket.onmessage = onMessage(socket, store);
socket.onclose = onClose(socket, store);
socket.onopen = onOpen(socket, store, code);
store.dispatch(connectionActions.opening());
} else if (wsAction.type === 'SUBSCRIBE') {
const msg = {
command: 'subscribe',
identifier: JSON.stringify({
channel: 'GameChannel',
}),
};
socket.send(JSON.stringify(msg));
store.dispatch(connectionActions.subscribing())
} else {
const msg = {
command: 'message',
identifier: JSON.stringify({
channel: 'GameChannel',
}),
data: JSON.stringify({
...action,
action: wsAction.type.toLowerCase(),
}),
};
socket.send(JSON.stringify(msg));
next(action);
}
};
@satish-zol

This comment has been minimized.

Copy link

commented Jul 3, 2019

how to use the websocket.js in store creation?
ex.

import api from "../middleware/websocket";

export default function configureStore(preloadedState) {
    const middlewares = [loggerMiddleware, thunkMiddleware, api];
    const middlewareEnhancer = applyMiddleware(...middlewares);

    const enhancers = [middlewareEnhancer];
    const composedEnhancers = composeWithDevTools(...enhancers);
    const store = createStore(rootReducer, preloadedState, composedEnhancers);

    return store;
}
@sardaukar

This comment has been minimized.

Copy link
Owner Author

commented Jul 3, 2019

It's been a while, but I think something like that might work.

@satish-zol

This comment has been minimized.

Copy link

commented Jul 6, 2019

Thanks @sardaukar for reply. I'm bit confuse on this line
const connectionState = store.getState().connection.state;
how to set the connection object?

@sardaukar

This comment has been minimized.

@satish-zol

This comment has been minimized.

Copy link

commented Jul 6, 2019

awesome..
thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.