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
HipsterSync
ing 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