我正在学习并使用rails构建emberjs应用程序。 在这个应用程序中,我希望推送数据而不是轮询到客户端应用程序。
For.e.g。以下代码段位于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应用程序?
答案 0 :(得分:15)
您必须实现了解如何处理WebSockets的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);
}
});
});
答案 1 :(得分: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;
}
}
});
答案 2 :(得分:1)
使用websockets,您正在观察套接字事件。触发事件时,您将处理该事件(如果适用),然后设置您的值。
查看您的代码,您会看到Socket.onmessage。如果邮件包含您要查找的内容,请调用刷新。