var util = require('util'),
    stream = require('stream'),
    WebSocket = require('ws');

var WebSocketStream = (function () {
    function _(address, protocols, options) {
        stream.Duplex.call(this);

        if (typeof address === 'string') {
            this._socket = new WebSocket(address, protocols, options).on('open', onopen.bind(this));
        } else {
            this._socket = address;
            onopen.call(this);
        }
    };
    util.inherits(_, stream.Duplex);

    function onopen() {
        var self = this;
        this._socket.on('message', function (data, flags) {
            self.push(data);
        }).on('close', function () {
            self.connected = false;
            self.push(null);
            self.emit('close');
        }).on('error', function (err) {
            self.emit('error', err);
        });

        this.on('finish', function () {
            self.close();
        }).on('error', function (err) { });

        this.connected = true;
        this.emit('connection', this);
    };

    (function (proto) {
        proto._write = function (chunk, encoding, callback) {
            var self = this;
            if (!this.connected) {
                this.once('connection', function () {
                    self._write(chunk, encoding, callback);
                });
            } else {
                var data = typeof chunk === 'string' ? new Buffer(chunk, encoding) : chunk;
                this._socket.send(data, { binary: true }, callback);
            }
        };

        proto._read = function (n) { };

        proto.close = function () {
            this._socket.close();
            return this;
        };

    })(_.prototype);

    return _;
})();


module.exports.WebSocketStream = WebSocketStream;

module.exports.connect = connent = function (address, protocols, options) {
    return new WebSocketStream(address, protocols, options);
};

module.exports.listen = listen = function (options, onconnection) {
    var server = new WebSocket.Server(options);
    if (typeof onconnection === 'function') {
        server.on('connection', function (ws) {
            onconnection.call(null, new WebSocketStream(ws));
        });
    }
    return server;
};


@@ -199,24 +199,73 @@
 all(this);%0A%0A
+        this.status = %7B sent: 0, received: 0 %7D;%0A%0A
         if (
@@ -369,16 +369,48 @@
 ns).on('
+error', onerror.bind(this)).on('
 open', o
@@ -479,16 +479,48 @@
  address
+.on('error', onerror.bind(this))
 ;%0A      
@@ -737,16 +737,65 @@
 (data);%0A
+            self.status.received += data.length;%0A
         
@@ -921,85 +921,31 @@
 ose'
-);%0A        %7D).on('error', function (err) %7B%0A            self.emit('error', err
+, !!self.status.closing
 );%0A 
@@ -1141,24 +1141,93 @@
 s);%0A    %7D;%0A%0A
+    function onerror(err) %7B%0A        this.emit('error', err);%0A    %7D;%0A%0A
     (functio
@@ -1669,24 +1669,217 @@
 true %7D, 
-callback
+function (err) %7B%0A                    if (!err)%0A                        self.status.sent += data.length;%0A                    typeof callback === 'function' && callback.call(null, err);%0A                %7D
 );%0A     
@@ -1968,32 +1968,72 @@
 = function () %7B%0A
+            this.status.closing = true;%0A
             this

optimise ws-stream.js