2012-05-10 2 views
9

Ich lerne und baue emberjs App mit Schienen. In dieser App möchte ich, dass die Daten an die Client-App gesendet und nicht gepollt werden.Wie kann man Websocket mit Emberjs integrieren?

z. der folgende Code-Schnipsel an 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(); 
    } 
}); 

Es Umfragen Twitter-API, aber meine Frage ist, wie eine EmberJS App zu machen, die eine WebSocket-Verbindung verwendet, um seinen Zustand zu aktualisieren?

Antwort

1

Mit Websockets, die Sie für Socket-Ereignisse beobachten. Wenn ein Ereignis ausgelöst wird, behandeln Sie dieses Ereignis (falls zutreffend) und legen dann Ihre Werte fest.

Betrachtet man den Code, würde man Socket.onmessage beobachten. Wenn die Nachricht enthält, wonach Sie suchen, rufen Sie Refresh auf.

+0

Danke, aber ich bin immer noch verwirrt. Ist Socket.onmessage in Ember implementiert? Oder etwas anderes muss ich wissen. Irgendein Code wäre eher hilfreich! – Autodidact

3

Ich spielte vor ein paar Tagen tatsächlich mit dem Code aus diesem Artikel. Behalten Sie die Griffleistenvorlage gleich und verwenden Sie den folgenden Code. Offensichtlich hängt das alles davon ab, was JSON durch den Socket passiert. Der folgende Code wurde mit ntwitter für Knoten getestet und getestet.

+0

Also, um das auszuführen, denke ich, dass ich die Nodejs installiert haben muss? Ist das eine Abhängigkeit für diese einfachen emberjs mit aktiviertem Web-Socket? – Autodidact

+0

Ja, dies ist clientseitiger Code für die Schnittstelle mit der socket.io-Bibliothek auf dem Knoten, aber ich nehme an, dass er dem Plugin sehr ähnlich zu einem anderen socket-betriebenen Backend ist. – Scotty

15

Sie müssen einen DS.Adapter implementieren, der mit WebSockets umgehen kann. Hier ist ein einfaches Beispiel:

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

danke für den Basisadapter. Aber ist es wirklich notwendig, alles nur für den Web-Socket aufzuschreiben? Ich meine, dass es nichts in Emberjs gibt? – Autodidact

+0

Soweit ich das beurteilen kann, hat Ember eine bultin REST-Implementierung, aber keine WebSockets für DS.Adapter (weshalb ich meine eigene rollte). – mike

+0

Hast du es ausgerollt oder irgendwo verpackt oder github? – Autodidact