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
Hello Chris,
ReplyDeleteI filed a WebSocket bug against Dart a while ago:
http://code.google.com/p/dart/issues/detail?id=553
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