2
\$\begingroup\$

I want to arrange async server-client communication with websockets and vanilla flux architecture. There is an excellent article about "Async Server-Side Communication with the Flux Architecture". I gonna implement it analogue with SockJS and ES6 promises:

TodoActionCreator.js

import { dispatchAsync } from '../AppDispatcher';
import ActionTypes from '../constants/ActionTypes';
import TodoService from '../services/TodoService'

export function addTodo(text) {
  var that = this;
  TodoService.addTodo({text: text}).then(function(todo) {
    that.dispatch(ActionTypes.ADD_TODO, todo);
  });
}

TodoService.js

import WebSocketWrapper from '../communication/WebSocketWrapper';

export function addTodo(todo) {
    //maybe do something with todos before send them to the server
    return WebSocketWrapper.send(todo);
}

WebSocketWrapper.js

/**
 * Due fact that SockJS provide raw websocket API and do not implement pub/sub, we need to do wrapper, which will corellate request/response
 */
import SockJS from 'sockjs-client';
import selectn from 'selectn';

var responseDeffers = {},
    requestId = 1;

var webSocketWrapper = {

    join: function(url) {
        this.ws = new SockJS(url);
        this.ws.onopen = this.onOpen;
        this.ws.onmessage = this.onMessage;
        this.ws.onclose = this.onClose;
        this.ws.onerror = this.onError;
    },

    onMessage: function(message) {
        let requestId = selectn('message.data.request_id');
        if (!requestId) return;
        //resolve or reject the promise which is kept in ActionCreator
        if (message.data.result === 'Ok') resolveRequest(requestId, message);
        else rejectRequest(requestId, message.error);
    },

    /**
     * Return Promise, which will be resolved/rejected on server response with the same requestId
     */
    send: function(request) {
        return new Promise(function(resolve, reject) {
            //npm run build
            // cache resolve/reject function to be able to invoke themn on server response
            responseDeffers[requestId++] = {
                resovle,
                reject
            };
            //send message via websockets
            if (this.ws.readyState == this.ws.OPEN) {
                this.ws.send(JSON.stringify(request));
            } else {
                reject('Websocket connection is closed');
            }
        });
    },

    resolveRequest: function(requestId, message) {
        let response = JSON.parse(message.data);
        responseDeffers[request_id].resolve(response);
        delete responseDeffers[request_id];
    },

    rejectRequest: function(requestId, message) {
        responseDeffers[requestId].reject(message);
    },

    onOpen: function() {},

    oClose: function() {},

    onError: function(e) {}
}

webSocketWrapper.join('http://localhost:3000/sjs');

export default webSocketWrapper;
\$\endgroup\$
3
  • \$\begingroup\$ So I was about to write a very detailed review on this code until I noticed that the code doesn't look valid. Would you mind going over your code first. \$\endgroup\$ Commented Sep 10, 2015 at 13:03
  • \$\begingroup\$ @JosephtheDreamer yeah, sure. Give me an hour pls. I was in hurry, so haven't chance to ran it first. Actually the question is about approach, but I definitely want to make it valid \$\endgroup\$ Commented Sep 10, 2015 at 13:15
  • \$\begingroup\$ @JosephtheDreamer updated \$\endgroup\$ Commented Sep 10, 2015 at 18:39

0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.