2012-05-10 21 views
9

私はレールを使ってemberjsアプリを学びビルドしています。 このアプリでは、クライアントアプリケーションにポーリングするのではなく、データをプッシュする必要があります。websocketとemberjsの統合方法は?

たとえば、 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(); 
    } 
}); 

それをポーリングのTwitterのAPIで次のスニペットが、私の質問は、その状態を更新するためのWebSocket接続を使用EmberJSアプリを作成する方法ですか?

答えて

1

ウェブソケットでは、ソケットイベントを監視しています。イベントがトリガーされると、そのイベントを処理して(適切な場合)、値を設定します。

あなたのコードを見ると、あなたはSocket.onmessageを観察するでしょう。メッセージに探しているものが含まれている場合は、更新を呼び出します。

+0

ありがとう、しかし私はまだ混乱しています。 Socket.onmessageはEmberに実装されていますか?それとも何か他のことを知る必要があります。いくつかのコードはむしろ参考になるでしょう! – Autodidact

3

私は数日前にその記事のコードで実際に遊んでいました。ハンドルバーテンプレートを同じにして、次のコードを使用します。明らかに、これはすべてあなたがソケットを通過しているJSONに依存します。次のコードはノードのntwitterで試してテストされています。

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

これを実行するには、nodejsをインストールしなければならないと思いますか? Webソケットを有効にした単純なemberjsの依存関係ですか? – Autodidact

+0

これはノード上のsocket.ioライブラリとインターフェイスするためのクライアントサイドコードですが、別のソケット電源バックエンドへのプラグインと非常によく似ていると想定しています。 – Scotty

15

WebSocketの処理方法を理解しているDS.Adapterを実装する必要があります。ここに簡単な例があります:

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

基本アダプターに感謝します。しかし、本当にWebソケットだけのためにすべてを書き留める必要はありますか?私はemberjsに何もないことを意味しますか? – Autodidact

+0

Emberにはbultin RESTの実装がありますが、DS.Adapter用のWebSocketはありません(これが私自身のものです)。 – mike

+0

あなたはそれをロールアウトしたのか、どこかに詰め込んだことがありますか? – Autodidact

関連する問題