2012-05-10 21 views
9

Estoy aprendiendo y construyendo la aplicación emberjs con rieles. En esta aplicación, deseo que los datos se envíen en lugar de sondear a la aplicación cliente.¿Cómo integrar websocket con emberjs?

For.e.g. el siguiente fragmento en http://awardwinningfjords.com/2011/12/27/emberjs-collections.html

// Setup a global namespace for our code. 
Twitter = Em.Application.create({ 

    // When everything is loaded. 
    ready: function() { 

    // Start polling Twitter 
    setInterval(function() { 
     Twitter.searchResults.refresh(); 
    }, 2000); 

    // The default search is empty, let's find some cats. 
    Twitter.searchResults.set("query", "cats"); 

    // Call the superclass's `ready` method. 
    this._super(); 
    } 
}); 

Se API encuestas gorjeo, pero mi pregunta es cómo hacer que una aplicación EmberJS que utiliza una conexión WebSocket para actualizar su estado?

Respuesta

1

Con websockets está observando eventos de socket. Cuando se desencadena un evento, usted maneja ese evento (si corresponde) y luego establece sus valores.

En cuanto a su código, usted podría observar Socket.onmessage. Si el mensaje contiene lo que estás buscando, llama a refresh.

+0

Gracias, pero todavía estoy confundido. ¿Socket.onmessage se implementa en Ember? O algo más necesito saber. ¡Algún código sería bastante útil! – Autodidact

3

En realidad estaba jugando con el código de ese artículo hace unos días. Mantenga la plantilla de la barra del mango igual, y use el siguiente código. Obviamente, todo esto depende de qué JSON estés pasando por el socket. El siguiente código se prueba y prueba con ntwitter para el nodo.

Twitter = Em.Application.create({ 
    ready: function() { 
     var socket = io.connect(); 
     socket.on('message', function(json) { 
      Twitter.searchResults.addTweet(Twitter.Tweet.create(JSON.parse(json))); 
     }); 

     this._super(); 
    } 
}); 

//Model 
Twitter.Tweet = Em.Object.extend(); 

//Collection 
Twitter.searchResults = Em.ArrayController.create({ 
    content: [], 
    _idCache: {}, 

    addTweet: function(tweet) { 
     var id = tweet.get("id"); 
     if (typeof this._idCache[id] === "undefined") { 
      this.pushObject(tweet); 
      this._idCache[id] = tweet.id; 
     } 
    } 

}); 
+0

Entonces, para ejecutar eso, ¿creo que debo tener el nodejs instalado? ¿Será eso una dependencia para ese simple emberjs con socket web habilitado? – Autodidact

+0

Sí, este es el código del lado del cliente para la interfaz con la biblioteca socket.io en el nodo, pero supongo que será muy similar al complemento a un servidor de alimentación con socket diferente. – Scotty

15

Tiene que implementar un Adaptador DS que comprenda cómo manejar WebSockets. Aquí hay un ejemplo simple:

var SOCKET  = 'ws://localhost:9090/some-websocket'; 

var ID   = 'uuid'; 

var FIND  = 'find'; 
var FIND_MANY = 'findMany'; 
var FIND_QUERY = 'findQuery'; 
var FIND_ALL = 'findAll'; 

/** 
* Implementation of WebSocket for DS.Store 
*/ 
App.Store = DS.Store.extend({ 

    revision: 4, 

    adapter: DS.Adapter.create({ 

     socket: undefined, 

     requests: undefined, 

     send: function(action, type, data, result) { 
      /* Specific to your web socket server side implementation */ 
      var request = { 
       "uuid": generateUuid(), 
       "action": action, 
       "type": type.toString().substr(1), 
       "data": data 
      }; 
      this.socket.send(JSON.stringify(request)); 
      /* So I have access to the original request upon a response from the server */ 
      this.get('requests')[request.uuid] = request; 
      return request; 
     }, 

     find: function (store, type, id) { 
      this.send(FIND, type, id); 
     }, 

     findMany: function (store, type, ids, query) { 
      this.send(FIND_MANY, type, ids); 
     }, 

     findQuery: function (store, type, query, modelArray) { 
      this.send(FIND_QUERY, type, query, modelArray).modelArray = modelArray; 
     }, 

     findAll: function (store, type) { 
      this.send(FIND_ALL, type); 
     }, 

     /* Also implement: 
     * createRecord & createRecords 
     * updateRecord & updateRecords 
     * deleteRecord & deleteRecords 
     * commit & rollback 
     */ 

     init: function() { 

      var context = this; 

      this.set('requests', {}); 

      var ws = new WebSocket(SOCKET); 

      ws.onopen = function() { 

      }; 

      ws.onmessage = function(event) { 
       var response = JSON.parse(event.data); 
       var request = context.get('requests')[response.uuid]; 

       switch (request.action) { 
        case FIND: 
         App.store.load(type, response.data[0]); 
         break; 
        case FIND_MANY: 
         App.store.loadMany(type, response.data); 
         break; 
        case FIND_QUERY: 
         request.modelArray.load(response.data); 
         break; 
        case FIND_ALL: 
         App.store.loadMany(type, response.data); 
         break; 
        default: 
         throw('Unknown Request: ' + request.action); 
       } 

       /* Cleanup */ 
       context.get('requests')[response.uuid] = undefined; 
      }; 

      ws.onclose = function() { 

      }; 

      this.set('socket', ws); 
     } 

    }); 
}); 
+0

gracias por el adaptador básico. Pero, ¿es realmente necesario anotar todo solo por el socket web? Quiero decir que no hay nada que esté en emberjs? – Autodidact

+0

Por lo que puedo decir, Ember tiene una implementación de REST bultin pero no una de WebSockets para DS.Adapter (que es la razón por la que rodé la mía). – mike

+0

¿Lo ha extendido o empaquetado en algún lugar o github? – Autodidact