Monday, March 12, 2012

First (Failed) Attempt at Web Sockets in Dart

‹prev | My Chain | next›

Tonight, I hope to evaluate how much detail I ought to devote to websockets in Dart for Hipsters. Currently, I plan to mention them in passing in a high-level HTML5 introduction, but perhaps they are worth more.

I normally use faye for my websocket needs, but that won't be of much use to me in Dart as I would have to implement the client-side library. That seems... involved. I briefly explore writing a server in Dart itself (the HTTP server from this dartlang.org article works nicely), but unfortunately websockets are not available on the server-side. Per a tracker issue, websockets are not available in dart:io and dart:html is not available in server-side dart.

So I stick with what I know and install a node.js + express.js server. Along with that, I install WebSocket-Node as it seems to be a solid pure WebSocket implementation. The package.json for my sample app is:
{
    "name": "dart-sockets"
  , "version": "0.0.1"
  , "private": true
  , "dependencies": {
      "express": "2.5.2"
    , "jade": ">= 0.0.1"
    , "websocket": ">0"
  }
}
With that, can npm install to get all of the dependencies resolved. The app.js express.js server is just a static file server along with some development (i.e. not origin restricted) WebSocket stuff:
var express = require('express'),
    WebSocketServer = require('websocket').server;

var app = module.exports = express.createServer();

// Configuration

app.configure(function(){
  app.use(express.static(__dirname + '/public'));
});

app.configure('development', function(){
  app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});

app.listen(3000);

wsServer = new WebSocketServer({
  httpServer: app,
  // You should not use autoAcceptConnections for production
  // applications, as it defeats all standard cross-origin protection
  // facilities built into the protocol and the browser.  You should
  // *always* verify the connection's origin and decide whether or not
  // to accept it.
  autoAcceptConnections: true
});


wsServer.on('request', function(request) {
  var connection = request.accept('echo-protocol', request.origin);
  console.log((new Date()) + ' Connection accepted.');
  connection.on('message', function(message) {
    if (message.type === 'utf8') {
      console.log('Received Message: ' + message.utf8Data);
      connection.sendUTF(message.utf8Data);
    }
    else if (message.type === 'binary') {
      console.log('Received Binary Message of ' + message.binaryData.length + ' bytes');
      connection.sendBytes(message.binaryData);
    }
  });
  connection.on('close', function(reasonCode, description) {
    console.log((new Date()) + ' Peer ' + connection.remoteAddress + ' disconnected.');
  });
});
Again, that is a lot of code, but most of it is boilerplate express.js for static sites and a stripped down WebSocket server copied from the WebSocket-node documentation.

Now for the dart client. I try
#import('dart:html');

main() {
  WebSocket ws = new WebSocket("ws://localhost:3000");
}
But am greeted with:
Internal error: 'http://localhost:3000/main.dart': Error: line 6 pos 22: interface 'WebSocket' has no constructor named 'WebSocket'
  var mySocket = new WebSocket("ws://localhost:3000");
                     ^
Bummer. It seems that I am stuck with dart:dom:
#import('dart:html');

main() {
  WebSocket ws = new WebSocket("ws://localhost:3000");
}
That at least compiles, so I try sending a mesage:
#import('dart:dom');

main() {
  WebSocket ws = new WebSocket("ws://localhost:3000");

  ws.addEventListener('open', (event) {
    ws.send("Hello");
    print("Sent");
  });
}
But that fails. I see not errors in the client, but no messages logged on the server side. I am forced to call it a night here. I will pick back up tomorrow -- hopefully I can see this through. Regardless, since WebSocket is not yet implemented in dart:html, it seems as though WebSockets can wait until the 1.1 edition of the book.


Day #323

2 comments:

  1. Hello Chris,

    I filed a WebSocket bug against Dart a while ago:

    http://code.google.com/p/dart/issues/detail?id=553

    ReplyDelete
    Replies
    1. Looks like that bug can be closed. I tried a recent build and am able to construct websockets from dart:html: http://japhr.blogspot.com/2012/03/dart-websockets-take-2.html (toward the bottom of that post).

      Delete