vigetlabs / microcosm

Flux with actions at center stage. Write optimistic updates, cancel requests, and track changes with ease.
http://code.viget.com/microcosm/
MIT License
487 stars 22 forks source link

Add example use with websockets to Docs #196

Open tommymarshall opened 7 years ago

tommymarshall commented 7 years ago

Curious where best to listen for websocket events.

djmccormick commented 7 years ago

We push an action onto the repo when a message arrives and it works well.

nhunzaker commented 7 years ago

@greypants you're the resident web sockets + microcosm expert. Would you be willing to take this on? Happy to ghost write.

greypants commented 7 years ago

Sure. I believe I've got a week to spend on open source coming up in the next month or so. I can put together some examples.

The basic pattern is this:

Receiving Messages

Socket messages being received have an action key that map to microcosm actions.

{ 
  "action": "addItem", 
  "data": { 
    "id": 1, 
    "label": "foo" 
  }
}

Then I'd build a little ActionSocket class that looked something like this:

import * as CoolActions from '../actions/cool-actions'

class ActionSocket {
  constructor(repo) {
    this.repo = repo
    this.socket = new WebSocket('ws://foo.dev')
    this.socket.addEventListener('message', this.onMessage)
  }

  onMessage({ action, data }) {
    if(CoolActions[action]) {
      this.repo.push(CoolActions[action], data)
    } else {
      console.debug(`"${action}" not found CoolActions`, data)
    }
  }
}

Sending Messages

For sending messages, I set up an effect, passing it my websocket instance, and registering actions that send messages with the action payload.

export default class SocketEffect {
  setup(repo, socket) {
    this.socket = socket
  }

  register() {
    return {
      [CoolActions.sendAddItem] : this.sendAddItem
    }
  }

  sendAddItem(data) {
    this.socket.send({ action: 'addItem', data })
  }
}