Wednesday, December 12, 2012

Dart Client and Server Websockets

‹prev | My Chain | next›

Up tonight I will swap out the data synchronization layer in my Dart Comics sample Dart application for one based on websockets. I already did this once, so I start by copying the old implementation into my new client-side implementation.

Said implementation swaps the synchronization layer, then opens a websocket for use in that sync layer. Once the websocket is open, the MVC application starts as usual:
WebSocket ws;

main() {
  HipsterSync.sync = wsSync;
  ws = new WebSocket("ws://localhost:8000/");

  // After open, initialize the app...
  ws.
    on.
    open.
    add((event) {
      // Perform the usual app initialization
    });
}
The old code all looks good, but to know for sure I need a websocket on the server side. In the original implementation, I created a server-side websocket with node.js. Now, I need to figure out how to do it in my Dart backend. Actually, thanks to Seth Ladd's websocket article, this turns out to be relatively straight-forward.

I create a websocket handler and attach it to the web server that I already have in the backend. With that, I define the websocket handler's onOpen callback for handling websocket connections. Inside that, I define the onMessage callback to process messages sent from the client's synchronization layer:
main() {
  HttpServer app = new HttpServer();

  WebSocketHandler wsHandler = new WebSocketHandler();

  app.addRequestHandler((req) => req.path == "/ws",
                         wsHandler.onRequest);

  Dirty db = new Dirty('dart_comics.db');
  Uuid uuid = new Uuid();
  wsHandler.onOpen = (conn) {
    conn.onMessage = (message) {
      // Do stuff with the message
    };
  };
}
The message handler itself reads messages and sends the appropriate responses back:
    conn.onMessage = (message) {
      print('Received Message: $message');

      var response;
      if (new RegExp(r"^read").hasMatch(message)) {
        response = JSON.stringify(db.values);
      }
      // ...
      print("replying with: $response");
      conn.send(response);
    };
Just like that, I have a working websocket data synchronization layer:


That was quite easy. Not much appears to have changed with Dart websockets since last I checked them out. And I am not complaining a bit. It is an easy-to-use API and it works.


Day #597

2 comments:

  1. You can try https://github.com/lvivski/start

    For now it doesn't allow pattern-matching for web socket messages, but it will soon. So your code can be simplified to:

    class App extends Server {
    App(): super() {
    view = new View();

    var db = new Dirty('dart_comics.db');
    var uuid = new Uuid();

    ws('/ws', (socket) {
    socket.on('read', () { socket.send(JSON.stringify(db.values)); });
    });
    }
    }

    ReplyDelete
  2. This comment has been removed by the author.

    ReplyDelete