9

私はレールでemberjsアプリを学び、構築しています。このアプリでは、データをクライアント アプリにポーリングするのではなく、プッシュする必要があります。

たとえば、次のスニペットはhttp://awardownedfjords.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 アプリを作成する方法です。

4

3 に答える 3

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);
        }

    });
});
于 2012-05-11T18:59:32.123 に答える
3

私は実際、数日前にその記事のコードをいじっていました。ハンドル バーのテンプレートはそのままにして、次のコードを使用します。明らかに、これはすべて、ソケットを介して渡す JSON によって異なります。次のコードは、ntwitter for node で試行およびテストされています。

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;
        }
    }

});
于 2012-05-11T16:50:35.243 に答える
1

WebSocket を使用すると、ソケット イベントを監視できます。イベントがトリガーされると、そのイベントを処理し (適切な場合)、値を設定します。

コードを見ると、Socket.onmessage が表示されます。メッセージに探しているものが含まれている場合は、refresh を呼び出します。

于 2012-05-10T17:11:52.543 に答える