2012-05-10 17 views
9

Sto imparando e costruendo l'app di emberjs con le guide. In questa app, voglio che i dati vengano trasferiti anziché inviati al client.Come integrare websocket con emberjs?

Per.e.g. il seguente frammento a 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(); 
    } 
}); 

E Sondaggi Twitter API, ma la mia domanda è come fare un app EmberJS che utilizza una connessione WebSocket per aggiornare il suo stato?

risposta

1

Con websockets che si stanno osservando per eventi socket. Quando un evento viene attivato, gestisci quell'evento (se appropriato) e quindi imposta i tuoi valori.

Guardando il codice si osserverebbe Socket.onmessage. Se il messaggio contiene ciò che stai cercando, chiama l'aggiornamento.

+0

Grazie, ma sono ancora confuso. Socket.onmessage è implementato in Ember? O qualcos'altro ho bisogno di sapere. Qualche codice sarebbe piuttosto utile! – Autodidact

3

In realtà stavo giocando con il codice di quell'articolo alcuni giorni fa. Mantenere il modello del manubrio lo stesso e utilizzare il seguente codice. Ovviamente, tutto dipende da cosa JSON stai passando attraverso il socket. Il seguente codice è stato provato e testato con ntwitter per il 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

Quindi, per far ciò, penso che devo aver installato il nodo? Sarà una dipendenza per quel semplice emberjs con la presa di rete abilitata? – Autodidact

+0

Sì, questo è il codice lato client per interfacciarsi con la libreria socket.io sul nodo, ma presumo che sarà molto simile al plug-in su un diverso backend basato su socket. – Scotty

15

si deve implementare un DS.Adapter che capisce come gestire WebSockets. Ecco un semplice esempio:

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

grazie per l'adattatore di base. Ma è davvero necessario scrivere tutto per la sola presa di rete? Intendo dire che non c'è nulla di simile in emberjs? – Autodidact

+0

Per quanto ne so, Ember ha un'implementazione bultin REST ma non una WebSockets per DS.Adapter (che è il motivo per cui ho fatto il mio). – mike

+0

Lo hai staccato o impacchettato da qualche parte o github? – Autodidact