I got off to a rough start last night with Dart websockets. So tonight, I take a step back and ask, "is the problem Dart or the server?". The problem could very well lie with WebSocket-Node (or my configuration of it).
Since my websocket experience comes nearly entirely in the form of faye (which is awesome), my direct websocket experience is limited. Limited, but I am pretty sure that what I have done so far in Dart ought to work:
#import('dart:dom'); main() { WebSocket ws = new WebSocket("ws://localhost:3000/"); // After open, send a message to the server ws.addEventListener('open', (event) { bool ret = ws.send("Hello"); print("Sent: $ret"); }); // Handle messages from the server, printing to the console ws.addEventListener('message', (event) { print("Got an event: $event"); print("The data in the event is: " + event.data); }); // Print message to the console on WS error ws.addEventListener('error', (event) { print("whoa: $event"); }); }So I try something similar in the Javascript console of Chrome:
var ws = new WebSocket("ws://localhost:3000"); ws.onopen = function(e){ console.log("Connected..."); } ws.onclose = function(e){ console.log("Disconnected."); } ws.onerror = function(e){ console.log("ERROR: " + e.data); } ws.onmessage = function(e){ console.log("Message: " + e.data); } ws.send("howdy!")Even in Javascript, I am getting no response:
The web socket just sits there and I see no response hit my
onmessage
handler. So clearly something is wrong in my WebSocket-node configuration. Looking back to last's work, my first thought is that maybe autoAcceptConnections: true
is not doing what I think it does. I switched it under the assumption that I want all connections accepted on this local server, but the documentation seems fairly opposed to this. So I switch it back to false
: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: false });After restarting, and trying the same Javascript in the console, I finally see the desired output:
That
autoAcceptConnections
seems broken, but again, it could just be my own misunderstanding of what it means. And, since it is incidental to my exploration of Dart websockets, I set aside that question. Instead, I switch back to Dartium to try out my Dart websocket code.Unfortunately, I am greeted by:
Aw, snap! indeed.
The node.js / WebSocket-node server is logging messages, and it does see the message from Dartium:
Tue Mar 13 2012 23:10:58 GMT-0400 (EDT) Connection accepted. Received Message: Hello Tue Mar 13 2012 23:10:58 GMT-0400 (EDT) Peer 127.0.0.1 disconnected.Ugh. It turns out that actually trying read the data from the websocket is responsible for the crash. If I comment out the line attempting to print out the data:
// Handle messages from the server, printing to the console
ws.addEventListener('message', (event) {
print("Got an event: $event");
// print("The data in the event is: " + event.data);
});
It works.I make a few attempts to cast this properly into a
String
(which it is), to no avail. Since I am getting "Aw, snap!" instead of a stacktrace, I have very little chance to figure out where things are going awry.The only other thing that I can think to do is download the most recent build of Dartium and try again. And...
Got an event: Instance of 'MessageEventImplementation' undefined:1The data in the event is: HelloIt works! Yay!
It is truly amazing how quickly all of this is changing, evolving and getting better. You'd have to be an idiot to even think about writing a book about it at this point. Er...
Regardless of sanity, I am not going to include websockets in the book unless they are worky in the new
dart:html
(dart:dom
is not long for the world). Per the current documentation for dart:html WebSocket, websocket listeners are set via setters: // After open, send a message to the server
ws.onopen = (event) {
bool ret = ws.send("Hello");
print("Sent: $ret");
});
Only when I try that, I get:Exception: NoSuchMethodException : method not found: 'set:onopen' Receiver: Instance of '_WebSocketImpl@33cc944a' Arguments: [Closure] Stack Trace: 0. Function: 'Object.noSuchMethod' url: 'bootstrap' line:677 col:3 1. Function: '::main' url: 'http://localhost:3000/main.dart' line:6 col:13Hrm... You know what? That
onopen
setter is not terribly darty. Perhaps the usual on.open
works? // After open, send a message to the server
ws.
on.
open.
add((event) {
bool ret = ws.send("Hello");
print("Sent: $ret");
});
// Handle messages from the server, printing to the console
ws.
on.
message.
add((event) {
print("Got an event: $event");
print("The data in the event is: " + event.data);
});
// Print message to the console on WS error
ws.
on.
error.
add((event) {
print("whoa: $event");
});
And whoa! That works:Kudos to the Dart team for that. I went from a relatively recent Dartium build in which
dart:html
could not even construct a websocket, let alone use it, to a fully functional websocket implementation. It seems that websockets will not be filed under "not working" in Dart for Hipsters. On the down side, that is more to write for the first edition, but those are good problems to have.Day #324
No comments:
Post a Comment