Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Websockets redux-logic and SSR #177

Open
therealgilles opened this issue Jan 3, 2021 · 0 comments
Open

Websockets redux-logic and SSR #177

therealgilles opened this issue Jan 3, 2021 · 0 comments

Comments

@therealgilles
Copy link

Wondering what's the right way to handle a websockets listener implemented through redux-logic with SSR. I've been using window.location to configure the listener. Should I use process.env variables to configure them when rendering on the server, or should I do something else with the listener (maybe bypass it entirely)?

Any advice welcome. Redux logic listener code is below.

websocket/logic.js:

import { createLogic } from 'redux-logic'
import { timer } from 'rxjs'
import {
  filter,
  tap,
  map,
  takeUntil,
  retryWhen,
  switchMap,
} from 'rxjs/operators'
import { webSocket } from 'rxjs/webSocket'
import debug from 'debug'
import store from '../store'
import {
  msgReceived,
  WS_CONNECT,
  WS_DISCONNECT,
  WS_MSG_ERROR,
  WS_MSG_SEND,
  WS_MSG_LISTEN,
  WS_MSG_STOP_LISTENING,
} from './actions'

debug.enable('websocket/logic:*')
const log = debug('websocket/logic:log')
// const info = debug('websocket/logic:info')
const error = debug('websocket/logic:error')

const wsType = window.location.protocol === 'http:' ? 'ws' : 'wss'
const port = window.location.port ? `:${window.location.port}` : ''
const WS_SERVER = `${wsType}://${window.location.hostname}${port}/ws`
log(`ws server = ${WS_SERVER}`)

const wsListenLogic = createLogic({
  type: WS_MSG_LISTEN,
  cancelType: WS_MSG_STOP_LISTENING,
  latest: true, // take latest only
  warnTimeout: 0, // long running logic

  processOptions: {
    failType: WS_MSG_ERROR,
  },

  process({ action$, cancelled$ }) {
    const wsSubject$ = webSocket({
      url: WS_SERVER,
      openObserver: {
        next: () => store.dispatch({ type: WS_CONNECT }),
      },
      closeObserver: {
        next: () => store.dispatch({ type: WS_DISCONNECT }),
      },
    })

    // send message on WS_MSG_SEND action
    action$
      .pipe(
        filter(action => action.type === WS_MSG_SEND),
        tap(action => wsSubject$.next(action.payload)),
        takeUntil(cancelled$)
      )
      .subscribe()

    // dispatch msgReceived with payload from server
    // on any incoming messages
    // returning obs subscribes to it
    return wsSubject$.pipe(
      map(msg => msgReceived(msg)),
      retryWhen(errors =>
        errors.pipe(
          tap(err => error(err)),
          switchMap(err => timer(1000))
        )
      )
    )
  },
})

export default [wsListenLogic]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant