OK. What the heck. I got websockets in Dart working last night. Let's see if I can get Hipster MVC working over websockets.
First up, however, I am going to adopt the Backbone.js practice of syncing with 'create', 'update', 'read', and 'delete' instead of the HTTP verb equivalent:
static Map _methodMap = const {
'create': 'post',
'update': 'put',
'read': 'get'
};
// default sync behavior
static Future _defaultSync(_method, model) {
String method = _method.toLowerCase(),
verb = _methodMap.containsKey(method) ?
_methodMap[method] : method;
// ...
}I kinda got away with it when I was just messing about with localStorage, but even then it felt wrong to "post" new records to localStorage.With that TODO done, I shift to defining my websocketSync method. For now, I do it directly in the
main.dart entry point to my MVC app:#import('HipsterSync.dart');
main() {
HipsterSync.sync = wsSync;
var my_comics_collection = new Collections.Comics()
, comics_view = new Views.Comics( /* ... */ );
my_comics_collection.fetch();
new Views.AddComic( /* ... */ );
}
wsSync(method, model) {
final completer = new Completer();
print("[wsSync] $method");
return completer.future;
}It seems that, as-is, the return of a Future is needed (another TODO). With that in place, I can load the app and see my print statement / tracer bullet in the Dart console:In my backend, I enable websockets with the same node.js + WebSocket-Node setup from last night. Then I respond to a websocket message with a JSON representation of my sweet comic book collection:
connection.on('message', function(message) {
if (message.type === 'utf8') {
console.log('Received Message: ' + message.utf8Data);
connection.sendUTF(jsonComics());
}
});That will not work for create/update/delete operations, but I will worry about that later.Back in the
main.dart code, I establish a websocket connection and, once it is open, I initialized my app—including fetching the comic book collection:#import('HipsterSync.dart');
WebSocket ws;
main() {
HipsterSync.sync = wsSync;
ws = new WebSocket("ws://localhost:3000/");
// After open, initialize the app...
ws.
on.
open.
add((event) {
var my_comics_collection = new Collections.Comics()
, comics_view = new Views.Comics( /* ... */ );
my_comics_collection.fetch();
new Views.AddComic( /* ... */ );
});
}With that, I am ready to implement my wsSync method to sync data with the backend over websockets. That is actually fairly straight-forward. When the app syncs (the only sync it does on-load is fetching the collection), I send the server a websocket message. When the server responds, I complete the Future (aka callback) with the JSON parsed comic collection:wsSync(method, model) {
final completer = new Completer();
ws.send(method);
// Handle messages from the server, completing the completer
ws.
on.
message.
add((event) {
print("The data in the event is: " + event.data);
completer.complete(JSON.parse(event.data));
});
return completer.future;
}And just like that, I am HipsterSyncing my MVC collection over websockets:That was almost too easy.
I still need to get creating / deleting working over websockets, so I may pick that up tomorrow. Then again, I am beginning to feel the strains of the impending Dart for Hipsters deadline so I may move on to other topics.
Day #325


No comments:
Post a Comment