Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Building Real-time Vue App

joe_re
May 23, 2018

Building Real-time Vue App

How to manage Socket.IO events in Vuex.

Vue.js Tokyo v-meetup #7 LT

joe_re

May 23, 2018
Tweet

More Decks by joe_re

Other Decks in Technology

Transcript

  1. Building Real­time
    Vue App
    2018/05/23 Vue.js Tokyo v­meetup #7 LT
    @joe_re

    View Slide

  2. Who am I?
    twitter: @joe_re
    github: @joe­re
    ClassDo Inc CTO
    community: Nishinippori.rb, GraphQL Tokyo Organizer

    View Slide

  3. What do you select for real­time
    communications?
    Polling
    Comet(Long polling)
    Server Sent Event
    Websocket

    View Slide

  4. Socket.IO
    Socket.IO enables real­time bidirectional event­based
    communication.
    It works on every platform, browser or device, focusing
    equally on reliability and speed.

    View Slide

  5. DEMO

    View Slide

  6. Rooms and Namespaces

    View Slide

  7. Rooms/Namespaces Good
    Points
    Enabling specific clients to send events is very easy.
    (All room numbers or only specific members or ...)
    If one of features causes a fatal error, it doesn't affect other
    features.
    Codebase become structured and easy to read

    View Slide

  8. Where do we manage Socket
    communications on Vue Apps?

    View Slide

  9. Socket.IO with Vuex

    View Slide

  10. vuex­socketio­plugin
    https://github.com/joe­re/vuex­socketio­plugin
    Inspired by Vue­Socket.io
    https://github.com/MetinSeylan/Vue­Socket.io
    Integrate Socket.IO events to vuex actions and mutations
    Support multi connections
    Map Socket.IO namespaces to Vuex module namespaces

    View Slide

  11. Map Socket.IO namespaces to
    Vuex module namespaces

    View Slide

  12. Map Socket.IO namespaces to
    Vuex module namespaces

    View Slide

  13. Map Socket.IO namespaces to
    Vuex module namespaces

    View Slide

  14. Socket.IO Events Mapping

    View Slide

  15. Socket.IO Events Mapping

    View Slide

  16. Socket.IO Events Mapping

    View Slide

  17. We can completely handle all websocket
    communications via the Vuex Store

    View Slide

  18. but it may lose readability with product
    growth..
    const sketchpad = {
    namespaced: true,
    state: { connect: false, ... },
    mutations: {
    SOCKET_CONNECT (state) { ... },
    SOCKET_RECEIVE_SHAPE (state, payload) { ... },
    ADD_SHAPE (state, payload) { ... },
    DELETE_SHAPE (state, payload) { ... },
    OTHER_MUTATION(state, payload) { ... },
    ...
    },
    actions: {
    socket_RECEIVE_SHAPE (state, payload) { ... },
    socket_CREATE_SHAPE (state, payload) { ... },
    socket_ARCHIVE_SHAPE (state, payload) { ... },
    fetchSketch (state, payload) { ... },
    fetchAllList (state, payload) { ... },
    ...
    }
    }
    combining events triggered by socket.IO and view.
    it makes very complex and difficult to read.

    View Slide

  19. We can set any number of nested modules
    const store = new Vuex.Store({
    modules: {
    account: {
    namespaced: true,
    state: { ... },
    actions: { ... },
    mutations: { ... },
    // nested modules
    modules: {
    myPage: {
    state: { ... },
    actions: { ... },
    mutations: { ... },
    },
    // nested modules
    posts: {
    namespaced: true,
    state: { ... },
    actions: { ... },
    mutations: { ... },
    }
    }
    }
    }
    })

    View Slide

  20. adding a prefix of action and mutation as
    child module name.
    const store = new Vuex.Store({
    modules: { videochat, sketchpads, ... }
    plugins: [
    createSocketioPlugin([ ... ]),
    { actionPrefix: 'socket/', mutationPrefix: 'socket/' }),
    ]
    })

    View Slide

  21. separate Socket.IO Events and other
    ones.
    const socket = {
    namespaced: true,
    state: { ... },
    mutations: {
    CONNECT (state) { ... },
    RECEIVE_SHAPE (state, payload) { ... },
    },
    actions: {
    RECEIVE_SHAPE (state, payload) { ... },
    CREATE_SHAPE (state, payload) { ... },
    ARCHIVE_SHAPE (state, payload) { ... },
    }
    }
    const sketchpad = {
    namespaced: true,
    modules: socket,
    state: { ... },
    mutations: {
    ADD_SHAPE (state, payload) { ... },
    DELETE_SHAPE (state, payload) { ... },
    OTHER_MUTATION(state, payload) { ... }
    },
    actions: {
    fetchSketch (state, payload) { ... },
    fetchAllList (state, payload) { ... }
    }
    }

    View Slide

  22. It's very readable
    but it may feel a bit strange..
    To update view we modify the state in the 'parent'.
    Child(socket) modules are mostly state­less.
    Thus children needs to modify the parent's state.
    It looks like anti­pattern.
    (but currently we have no problem, it's very limited
    situation...)

    View Slide

  23. How do you deal with real­time
    communications?
    Let's talk after this.

    View Slide

  24. Thank you for your attention!

    View Slide