Handling socket connections in a flux application

582 views Asked by At

Situation:

I am building a web service using Reactjs and Flummox that will connect to a simple socket server using Socket.io. It will need to keep track of multiple connections per user on their dashboard and am wondering about the best way of doing this. Each user can have multiple tokens, each of which will be associated with a socket connection. I have 2 approaches to this and would like to know which method is more fluxy or if there is another better way that is more fluxy.

My first solution

Creating a class that I import into my react view that handles the socket connections and updates my store when the socket responds. The class might look something like this:

import Flux from '../flux'
import io from 'socket.io-client'

export default class Socket {

    constructor() {

        this.socket = null;
        this.token = null
    }

    connect = (token) => {
        this.token = token;
        this.socket = io('http//192.168.0.144:3000');
        this.listen()
    };

    listen = () => {
        this.socket.on('connect', this.socket.emit('auth', this.token));
        this.socket.on('state', this.stateChanged)
    };

    stateChanged(state) {

        Flux.getActions('sockets').updateState(state, this.token);
    }
}

and from my react view:

import React from 'react'
import Flux from '../flux'
import Socket from './SocketClass'

let _ = React.createFactory;
let div = _('div');
let h1 = _('h1');

export default
class Dashboard extends React.Component {

    constructor() {

        super();

        this.state = {
            tokens: []
        }
    }

    componentWillMount() {

        Flux.getStore('users').on('change', this._storeUpdated);
        Flux.getActions('users').update();
    }

    render() {

        let connections = Flux.getStore('sockets').getStates().forEach(state => {
            h1({},
                state
            )
        });

        return div({},
            connections
        )
    }

    _storeUpdated = () => {

        let tokens = [];
        Flux.getStore('users').getTokens().forEach((token, index) => {
            tokens.push({
                token: token,
                socket: new Socket()
            });
            tokens[index].socket.connect(token)
        });
        this.setState(tokens)
    };
}

Note: This code is just to get the idea across and has not been tested.

My second solution

My second approach would be to do something similar, but instead instantiating a new class for each socket, I could handle the sockets in a single flux store. Something like this:

import { Store } from 'flummox'
import io from 'socket.io-client'

export default
class Socket extends Store {

    constructor(flux) {


        super();

        this.state = {
            sockets: []
        }
    }

    connect(token) {

        let sockets = this.state.sockets;
        sockets.push({
            token: token,
            socket: io('http://192.168.0.144:3000'),
            state: null
        });
        this.state.sockets.forEach((socket, index) => {
            if (socket.token == token) {
                socket.on('connect', socket.socket.emit('auth', socket.token));
                socket.on('state', state => {
                    let sockets = this.state.sockets;
                    sockets[index].state = state;
                    this.setState({sockets: sockets})
                })
            }
        })
    }

    getStates() {
        return this.state.sockets
    }
}
1

There are 1 answers

0
Kinnza On BEST ANSWER

Its pretty open, but all the implementations and guidelines i saw (and use) leave the store simple (just holds data and doing nothing much), and the action does the login to access the server and such. Again, i would implement in the action, but will logically split it into a different class that the action will use.