diff --git a/.github/workflows/dart_ci.yaml b/.github/workflows/dart_ci.yaml new file mode 100644 index 0000000..346f137 --- /dev/null +++ b/.github/workflows/dart_ci.yaml @@ -0,0 +1,28 @@ +name: Dart CI + +on: + push: + branches: + - 'master' + - 'test_consume_*' + pull_request: + branches: + - '**' + +jobs: + test: + runs-on: ubuntu-latest + strategy: + matrix: + sdk: [ stable ] + steps: + - uses: actions/checkout@v2 + - uses: dart-lang/setup-dart@v1 + with: + sdk: ${{ matrix.sdk }} + - name: Install dependencies + run: npm install + - name: Analyze project source + run: dartanalyzer . + - name: Run tests + run: ./tool/travis.sh test \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 56514f9..0000000 --- a/.travis.yml +++ /dev/null @@ -1,20 +0,0 @@ -language: dart - -dart: - - 1.24.3 - - 2.0.0 - -# Workaround for issue with sandboxed Chrome in containerized Travis builds. -sudo: required -addons: - chrome: stable - -# Re-use downloaded pub packages everywhere. -cache: - directories: - - $HOME/.pub-cache - -before_script: npm install -script: - - dartanalyzer . - - ./tool/travis.sh test diff --git a/example/echo.dart b/example/echo.dart index 731c743..881e163 100644 --- a/example/echo.dart +++ b/example/echo.dart @@ -4,8 +4,8 @@ import "dart:html"; import 'package:logging/logging.dart'; import "package:sockjs_client/sockjs_client.dart" as SockJS; -DivElement div = querySelector('#first div'); -InputElement inp = querySelector('#first input'); +DivElement div = querySelector('#first div'); +InputElement inp = querySelector('#first input'); FormElement form = querySelector('#first form'); _log(LogRecord l) { @@ -24,19 +24,19 @@ main() { LOG.info("Starting"); var sockjs_url = 'http://127.0.0.1:8081/echo'; - var sockjs = new SockJS.Client(sockjs_url, protocolsWhitelist:['websocket', 'xhr-streaming'], debug: true); + var sockjs = new SockJS.Client(sockjs_url, + protocolsWhitelist: ['websocket', 'xhr-streaming'], debug: true); querySelector('#first input').focus(); - sockjs.onOpen.listen( (_) => LOG.info('[*] open ${sockjs.protocol}') ); - sockjs.onMessage.listen( (e) => LOG.info('[.] message ${e.data}') ); - sockjs.onClose.listen( (_) => LOG.info('[*] close') ); + sockjs.onOpen.listen((_) => LOG.info('[*] open ${sockjs.protocol}')); + sockjs.onMessage.listen((e) => LOG.info('[.] message ${e.data}')); + sockjs.onClose.listen((_) => LOG.info('[*] close')); - inp.onKeyUp.listen( (KeyboardEvent e) { + inp.onKeyUp.listen((KeyboardEvent e) { if (e.keyCode == 13) { LOG.info('[ ] sending ${inp.value}'); sockjs.send(inp.value); inp.value = ''; } }); - -} \ No newline at end of file +} diff --git a/lib/sockjs_client.dart b/lib/sockjs_client.dart index e3d7511..afc8d98 100644 --- a/lib/sockjs_client.dart +++ b/lib/sockjs_client.dart @@ -19,24 +19,35 @@ part "src/transport/receiver-xhr.dart"; part "src/transport/websocket.dart"; part "src/transport/xhr.dart"; -const version = ""; +const version = ""; const CONNECTING = 0; const OPEN = 1; const CLOSING = 2; const CLOSED = 3; -typedef TransformFactory(Client client, String transUrl, {String baseUrl, bool noCredentials}); +typedef TransformFactory(Client client, String transUrl, + {String baseUrl, bool noCredentials}); class Protocol { TransformFactory create; bool enabled; num roundTrips; bool needBody; - Protocol({this.create, this.enabled: true, this.roundTrips: 1, this.needBody: false}); + Protocol( + {this.create, + this.enabled: true, + this.roundTrips: 1, + this.needBody: false}); } Map PROTOCOLS = { - "websocket": new Protocol(create:WebSocketTransport.create, enabled: WebSocketTransport.enabled, roundTrips: WebSocketTransport.roundTrips), - "xhr-streaming": new Protocol(create:XhrStreamingTransport.create, enabled: XhrStreamingTransport.enabled, roundTrips: XhrStreamingTransport.roundTrips) + "websocket": new Protocol( + create: WebSocketTransport.create, + enabled: WebSocketTransport.enabled, + roundTrips: WebSocketTransport.roundTrips), + "xhr-streaming": new Protocol( + create: XhrStreamingTransport.create, + enabled: XhrStreamingTransport.enabled, + roundTrips: XhrStreamingTransport.roundTrips) }; diff --git a/lib/src/ajax.dart b/lib/src/ajax.dart index 4ea9363..09c8e71 100644 --- a/lib/src/ajax.dart +++ b/lib/src/ajax.dart @@ -6,10 +6,10 @@ class StatusEvent extends event.Event { StatusEvent(String type, [this.status = 0, this.text = ""]) : super(type); } -typedef AbstractXHRObject AjaxObjectFactory(String method, String baseUrl, {bool noCredentials, dynamic payload}); +typedef AbstractXHRObject AjaxObjectFactory(String method, String baseUrl, + {bool noCredentials, dynamic payload}); class AbstractXHRObject extends Object with event.Emitter { - html.HttpRequest xhr; StreamSubscription changeSubscription; @@ -17,20 +17,22 @@ class AbstractXHRObject extends Object with event.Emitter { Stream get onFinish => getEventStream('finish'); Stream get onTimeout => getEventStream('timeout'); - void _start(String method, String url, dynamic payload, {bool noCredentials: false, Map headers}) { - + void _start(String method, String url, dynamic payload, + {bool noCredentials: false, Map headers}) { try { - xhr = new html.HttpRequest(); - } catch(x) {}; - - if ( xhr == null ) { - try { - // TODO(nelsonsilva) - xhr = new window['ActiveXObject']('Microsoft.XMLHTTP'); - } catch(x) {}; + xhr = new html.HttpRequest(); + } catch (x) {} + ; + + if (xhr == null) { + try { + // TODO(nelsonsilva) - xhr = new window['ActiveXObject']('Microsoft.XMLHTTP'); + } catch (x) {} + ; } // TODO(nelsonsilva) //if ( window['ActiveXObject'] != null || window['XDomainRequest'] != null) { - // IE8 caches even POSTs + // IE8 caches even POSTs // url += ((url.indexOf('?') === -1) ? '?' : '&') + 't='+(+new Date); //} @@ -39,21 +41,22 @@ class AbstractXHRObject extends Object with event.Emitter { //that.unload_ref = utils.unload_add(function(){that._cleanup(true);}); try { - xhr.open(method, url); - } catch(e) { - // IE raises an exception on wrong port. - dispatch(new StatusEvent("finish")); - _cleanup(); - return; - }; + xhr.open(method, url); + } catch (e) { + // IE raises an exception on wrong port. + dispatch(new StatusEvent("finish")); + _cleanup(); + return; + } + ; if (!noCredentials) { - // Mozilla docs says https://developer.mozilla.org/en/XMLHttpRequest : - // "This never affects same-site requests." - xhr.withCredentials = true; + // Mozilla docs says https://developer.mozilla.org/en/XMLHttpRequest : + // "This never affects same-site requests." + xhr.withCredentials = true; } if (headers != null) { - headers.forEach((k, v) => xhr.setRequestHeader(k, v)); + headers.forEach((k, v) => xhr.setRequestHeader(k, v)); } changeSubscription = xhr.onReadyStateChange.listen(_readyStateHandler); @@ -71,7 +74,8 @@ class AbstractXHRObject extends Object with event.Emitter { try { status = xhr.status; text = xhr.responseText; - } catch (x) {}; + } catch (x) {} + ; // IE does return readystate == 3 for 404 answers. if (text != null && !text.isEmpty) { dispatch(new StatusEvent("chunk", status, text)); @@ -85,7 +89,6 @@ class AbstractXHRObject extends Object with event.Emitter { } void _cleanup([bool abort = false]) { - if (xhr == null) return; // utils.unload_del(that.unload_ref); @@ -93,12 +96,13 @@ class AbstractXHRObject extends Object with event.Emitter { changeSubscription.cancel(); if (abort) { - try { - xhr.abort(); - } catch(x) {}; + try { + xhr.abort(); + } catch (x) {} + ; } //that.unload_ref = that.xhr = null; -} + } void close() { // TODO(nelsonsilva) - nuke(); @@ -107,25 +111,31 @@ class AbstractXHRObject extends Object with event.Emitter { } class XHRCorsObject extends AbstractXHRObject { - XHRCorsObject(String method, String url, {Map headers, bool noCredentials, dynamic payload}) { - Timer.run(() =>_start(method, url, payload, noCredentials: noCredentials != null ? noCredentials : false)); - } + XHRCorsObject(String method, String url, + {Map headers, bool noCredentials, dynamic payload}) { + Timer.run(() => _start(method, url, payload, + noCredentials: noCredentials != null ? noCredentials : false)); + } } - - class XHRLocalObject extends AbstractXHRObject { - XHRLocalObject(String method, String url, {Map headers, bool noCredentials, dynamic payload}) { - Timer.run(() =>_start(method, url, payload, noCredentials: noCredentials != null ? noCredentials : true)); - } + XHRLocalObject(String method, String url, + {Map headers, bool noCredentials, dynamic payload}) { + Timer.run(() => _start(method, url, payload, + noCredentials: noCredentials != null ? noCredentials : true)); + } } -AbstractXHRObject XHRLocalObjectFactory(String method, String baseUrl, {bool noCredentials, dynamic payload}) { - return new XHRLocalObject(method, baseUrl, noCredentials: noCredentials, payload: payload); +AbstractXHRObject XHRLocalObjectFactory(String method, String baseUrl, + {bool noCredentials, dynamic payload}) { + return new XHRLocalObject(method, baseUrl, + noCredentials: noCredentials, payload: payload); } -AbstractXHRObject XHRCorsObjectFactory(String method, String baseUrl, {bool noCredentials, dynamic payload}) { - return new XHRCorsObject(method, baseUrl, noCredentials: noCredentials, payload: payload); +AbstractXHRObject XHRCorsObjectFactory(String method, String baseUrl, + {bool noCredentials, dynamic payload}) { + return new XHRCorsObject(method, baseUrl, + noCredentials: noCredentials, payload: payload); } // 1. Is natively via XHR @@ -133,9 +143,9 @@ AbstractXHRObject XHRCorsObjectFactory(String method, String baseUrl, {bool noCr // 3. Nope, but postMessage is there so it should work via the Iframe. // 4. Nope, sorry. int isXHRCorsCapable() { - return 1; + return 1; - /* + /* if (window["XMLHttpRequest"] != null && window["'withCredentials' in new XMLHttpRequest()) { return 1; } diff --git a/lib/src/client.dart b/lib/src/client.dart index 4019234..5463921 100644 --- a/lib/src/client.dart +++ b/lib/src/client.dart @@ -6,7 +6,8 @@ class CloseEvent extends event.Event { bool wasClean; dynamic lastEvent; - CloseEvent({this.code, this.reason, this.wasClean, this.lastEvent}) : super("close"); + CloseEvent({this.code, this.reason, this.wasClean, this.lastEvent}) + : super("close"); } class MessageEvent extends event.Event { @@ -15,7 +16,6 @@ class MessageEvent extends event.Event { } class Client extends Object with event.Emitter { - bool debug; bool devel; @@ -40,16 +40,16 @@ class Client extends Object with event.Emitter { dynamic _transport = null; Timer _transportTref; - Client(String url, {this.devel: false, - this.debug: false, - this.protocolsWhitelist, - this.info, - this.noCredentials: false, - this.rtt: 0, - this.server, - this.roundTrips, - this.timeout}) { - + Client(String url, + {this.devel: false, + this.debug: false, + this.protocolsWhitelist, + this.info, + this.noCredentials: false, + this.rtt: 0, + this.server, + this.roundTrips, + this.timeout}) { _baseUrl = utils.amendUrl(url); if (server == null) { @@ -58,20 +58,21 @@ class Client extends Object with event.Emitter { _ir = new InfoReceiver.forURL(_baseUrl); _ir.onFinish.listen((InfoReceiverEvent evt) { - _ir = null; - if (evt.info != null) { - _applyInfo(evt.info); - _didClose(); - } else { - _didClose(1002, 'Can\'t connect to server', true); - } + _ir = null; + if (evt.info != null) { + _applyInfo(evt.info); + _didClose(); + } else { + _didClose(1002, 'Can\'t connect to server', true); + } }); } Stream get onOpen => getEventStream('open'); Stream get onMessage => getEventStream('message'); Stream get onClose => getEventStream('close'); - Stream get onHeartbeat => getEventStream('heartbeat'); + Stream get onHeartbeat => + getEventStream('heartbeat'); void close([int code, String reason]) { if (_transport != null) { @@ -91,10 +92,10 @@ class Client extends Object with event.Emitter { bool send(String data) { if (readyState == CONNECTING) { - throw 'INVALID_STATE_ERR'; + throw 'INVALID_STATE_ERR'; } if (readyState == OPEN) { - _transport.doSend(utils.quote(data)); + _transport.doSend(utils.quote(data)); } return true; } @@ -103,32 +104,30 @@ class Client extends Object with event.Emitter { if (readyState != CONNECTING && readyState != OPEN && readyState != CLOSING) { - throw 'INVALID_STATE_ERR'; + throw 'INVALID_STATE_ERR'; } if (_ir != null) { // _ir.nuke(); - _ir = null; + _ir = null; } if (_transport != null) { - _transport.doCleanup(); - _transport = null; + _transport.doCleanup(); + _transport = null; } var close_event = new CloseEvent( - code: code, - reason: reason, - wasClean: utils.userSetCode(code)); - - if (!utils.userSetCode(code) && - readyState == CONNECTING && !force) { - if (_tryNextProtocol(close_event)) { - return; - } - close_event = new CloseEvent( code: 2000, - reason: "All transports failed", - wasClean: false, - lastEvent: close_event ); + code: code, reason: reason, wasClean: utils.userSetCode(code)); + + if (!utils.userSetCode(code) && readyState == CONNECTING && !force) { + if (_tryNextProtocol(close_event)) { + return; + } + close_event = new CloseEvent( + code: 2000, + reason: "All transports failed", + wasClean: false, + lastEvent: close_event); } readyState = CLOSED; @@ -137,16 +136,16 @@ class Client extends Object with event.Emitter { void _dispatchOpen() { if (readyState == CONNECTING) { - if (_transportTref != null) { - _transportTref.cancel(); - _transportTref = null; - } - readyState = OPEN; - dispatch("open"); + if (_transportTref != null) { + _transportTref.cancel(); + _transportTref = null; + } + readyState = OPEN; + dispatch("open"); } else { - // The server might have been restarted, and lost track of our - // connection. - _didClose(1006, "Server lost session"); + // The server might have been restarted, and lost track of our + // connection. + _didClose(1006, "Server lost session"); } } @@ -154,60 +153,59 @@ class Client extends Object with event.Emitter { if (readyState != OPEN) { return; } - dispatch(new MessageEvent(data)); + dispatch(new MessageEvent(data)); } void _dispatchHeartbeat() { if (readyState != OPEN) { - return; + return; } dispatch("heartbeat"); } void _didMessage(String data) { var type = data[0]; - switch(type) { - case 'o': + switch (type) { + case 'o': _dispatchOpen(); break; - case 'a': - var s = data.substring(1); - if (s == null) s = '[]'; - var payload = convert.json.decode(s); - for(var i=0; i < payload.length; i++){ + case 'a': + var s = data.substring(1); + if (s == null) s = '[]'; + var payload = convert.json.decode(s); + for (var i = 0; i < payload.length; i++) { _dispatchMessage(payload[i]); - } - break; - case 'm': - var s = data.substring(1); - if (s == null) s = 'null'; - var payload = convert.json.decode(s); - _dispatchMessage(payload); - break; - case 'c': - var s = data.substring(1); - if (s == null) s = '[]'; - var payload = convert.json.decode(s); - _didClose(payload[0], payload[1]); - break; - case 'h': - _dispatchHeartbeat(); - break; + } + break; + case 'm': + var s = data.substring(1); + if (s == null) s = 'null'; + var payload = convert.json.decode(s); + _dispatchMessage(payload); + break; + case 'c': + var s = data.substring(1); + if (s == null) s = '[]'; + var payload = convert.json.decode(s); + _didClose(payload[0], payload[1]); + break; + case 'h': + _dispatchHeartbeat(); + break; } } bool _tryNextProtocol([CloseEvent closeEvent]) { if (protocol != null) { - _debug('Closed transport: $protocol $closeEvent'); - protocol = null; + _debug('Closed transport: $protocol $closeEvent'); + protocol = null; } if (_transportTref != null) { - _transportTref.cancel(); - _transportTref = null; + _transportTref.cancel(); + _transportTref = null; } - while(true) { - + while (true) { if (_protocols.isEmpty) { return false; } @@ -218,42 +216,44 @@ class Client extends Object with event.Emitter { // the `head`? if (PROTOCOLS.containsKey(protocol) && PROTOCOLS[protocol].needBody && - ( (html.document.body == null) || (html.document.readyState != null && html.document.readyState != 'complete')) - ) { - _protocols.insert(0, protocol); - this.protocol = 'waiting-for-load'; - html.document.onLoad.listen( (_) => _tryNextProtocol()); - return true; + ((html.document.body == null) || + (html.document.readyState != null && + html.document.readyState != 'complete'))) { + _protocols.insert(0, protocol); + this.protocol = 'waiting-for-load'; + html.document.onLoad.listen((_) => _tryNextProtocol()); + return true; } - if (!PROTOCOLS.containsKey(protocol) || - !PROTOCOLS[protocol].enabled) { - _debug('Skipping transport: $protocol'); + if (!PROTOCOLS.containsKey(protocol) || !PROTOCOLS[protocol].enabled) { + _debug('Skipping transport: $protocol'); } else { - // if roundTrips is passed in, we will use it - // instead of the defaulted value for the protocol. - var roundTrips = (this.roundTrips != null && this.roundTrips > 0) - ? this.roundTrips - : PROTOCOLS[protocol].roundTrips; - var to = this.timeout; - if (to == null || to < 1) { - to = rto * roundTrips; - if (to == 0) to = 5000; + // if roundTrips is passed in, we will use it + // instead of the defaulted value for the protocol. + var roundTrips = (this.roundTrips != null && this.roundTrips > 0) + ? this.roundTrips + : PROTOCOLS[protocol].roundTrips; + var to = this.timeout; + if (to == null || to < 1) { + to = rto * roundTrips; + if (to == 0) to = 5000; + } + _transportTref = new Timer(new Duration(milliseconds: to), () { + if (readyState == CONNECTING) { + // I can't understand how it is possible to run + // this timer, when the state is CLOSED, but + // apparently in IE everythin is possible. + _didClose(2007, "Transport timeouted"); } - _transportTref = new Timer(new Duration(milliseconds:to), () { - if (readyState == CONNECTING) { - // I can't understand how it is possible to run - // this timer, when the state is CLOSED, but - // apparently in IE everythin is possible. - _didClose(2007, "Transport timeouted"); - } - }); - - var connid = utils.random_string(8); - var trans_url = "$_baseUrl/$server/$connid"; - _debug('Opening transport: $protocol url:$trans_url RTO:$rto roundTrips:$roundTrips timeout:$to'); - _transport = PROTOCOLS[protocol].create(this, trans_url, baseUrl: _baseUrl, noCredentials: noCredentials); - return true; + }); + + var connid = utils.random_string(8); + var trans_url = "$_baseUrl/$server/$connid"; + _debug( + 'Opening transport: $protocol url:$trans_url RTO:$rto roundTrips:$roundTrips timeout:$to'); + _transport = PROTOCOLS[protocol].create(this, trans_url, + baseUrl: _baseUrl, noCredentials: noCredentials); + return true; } } } @@ -267,8 +267,7 @@ class Client extends Object with event.Emitter { _debug(String msg) { if (debug) { - print(msg); + print(msg); } } - } diff --git a/lib/src/events.dart b/lib/src/events.dart index ae5d45f..e56f90c 100644 --- a/lib/src/events.dart +++ b/lib/src/events.dart @@ -8,13 +8,15 @@ class Event { } class Emitter { - final _evtController = new StreamController.broadcast(); - Stream operator[] (type) => _evtController.stream.where((e) => e.type == type); - + Stream operator [](type) => + _evtController.stream.where((e) => e.type == type); + Stream getEventStream(String type) { - return _evtController.stream.where((e) => e.type == type).map((e) => e as T); + return _evtController.stream + .where((e) => e.type == type) + .map((e) => e as T); } dispatch(evtOrType) { diff --git a/lib/src/info.dart b/lib/src/info.dart index 9ecca35..7bade6f 100644 --- a/lib/src/info.dart +++ b/lib/src/info.dart @@ -23,35 +23,34 @@ class InfoReceiverEvent extends event.Event { } abstract class InfoReceiver extends Object with event.Emitter { - InfoReceiver._(); - Stream get onFinish => getEventStream('finish'); + Stream get onFinish => + getEventStream('finish'); factory InfoReceiver.forURL(String baseUrl) { if (utils.isSameOriginUrl(baseUrl)) { - // If, for some reason, we have SockJS locally - there's no - // need to start up the complex machinery. Just use ajax. - return new AjaxInfoReceiver(baseUrl, XHRLocalObjectFactory); + // If, for some reason, we have SockJS locally - there's no + // need to start up the complex machinery. Just use ajax. + return new AjaxInfoReceiver(baseUrl, XHRLocalObjectFactory); } switch (isXHRCorsCapable()) { case 1: - // XHRLocalObject -> no_credentials=true - return new AjaxInfoReceiver(baseUrl, XHRLocalObjectFactory); + // XHRLocalObject -> no_credentials=true + return new AjaxInfoReceiver(baseUrl, XHRLocalObjectFactory); case 2: - //return new AjaxInfoReceiver(baseUrl, utils.XDRObject); + //return new AjaxInfoReceiver(baseUrl, utils.XDRObject); case 3: - // Opera - return new InfoReceiverIframe(baseUrl); + // Opera + return new InfoReceiverIframe(baseUrl); default: - // IE 7 - return new InfoReceiverFake(); + // IE 7 + return new InfoReceiverFake(); } } } class AjaxInfoReceiver extends InfoReceiver { - AjaxInfoReceiver(String baseUrl, AjaxObjectFactory xhrFactory) : super._() { Timer.run(() => doXhr(baseUrl, xhrFactory)); } @@ -60,40 +59,39 @@ class AjaxInfoReceiver extends InfoReceiver { var t0 = new DateTime.now().millisecondsSinceEpoch; var xo = xhrFactory('GET', "$baseUrl/info"); - var tref = new Timer(new Duration(milliseconds:8000), () => dispatch("timeout")); + var tref = + new Timer(new Duration(milliseconds: 8000), () => dispatch("timeout")); xo.onFinish.listen((StatusEvent evt) { - tref.cancel(); - tref = null; - if (evt.status == 200) { - var rtt = new DateTime.now().millisecondsSinceEpoch - t0; - var info = new Info.fromJSON(convert.json.decode(evt.text)); - dispatch(new InfoReceiverEvent("finish", info, rtt)); - } else { - dispatch(new InfoReceiverEvent("finish")); - } - }); - xo.onTimeout.listen( (_) { - xo.close(); + tref.cancel(); + tref = null; + if (evt.status == 200) { + var rtt = new DateTime.now().millisecondsSinceEpoch - t0; + var info = new Info.fromJSON(convert.json.decode(evt.text)); + dispatch(new InfoReceiverEvent("finish", info, rtt)); + } else { dispatch(new InfoReceiverEvent("finish")); + } + }); + xo.onTimeout.listen((_) { + xo.close(); + dispatch(new InfoReceiverEvent("finish")); }); } } - class InfoReceiverIframe extends InfoReceiver { - InfoReceiverIframe(base_url) : super._() { - if(html.document.body == null) { + if (html.document.body == null) { html.document.onLoad.listen((_) => go()); } else { - go(); + go(); } } - go() { - // TODO(nelsonsilva) - /* + go() { + // TODO(nelsonsilva) + /* var ifr = new IframeTransport(); ifr.protocol = 'w-iframe-info-receiver'; var fun = function(r) { @@ -114,26 +112,23 @@ class InfoReceiverIframe extends InfoReceiver { }; ifr.i_constructor(mock_ri, base_url, base_url); */ - } + } } - class InfoReceiverFake extends InfoReceiver { - InfoReceiverFake() : super._() { // It may not be possible to do cross domain AJAX to get the info // data, for example for IE7. But we want to run JSONP, so let's // fake the response, with rtt=2s (rto=6s). - new Timer(new Duration(milliseconds:2000), () => dispatch("finish")); + new Timer(new Duration(milliseconds: 2000), () => dispatch("finish")); } } - // FacadeJS['w-iframe-info-receiver'] class WInfoReceiverIframe { WInfoReceiverIframe(ri, _trans_url, baseUrl) { var ir = new AjaxInfoReceiver(baseUrl, XHRLocalObjectFactory); - ir.onFinish.listen( (event.Event evt) { + ir.onFinish.listen((event.Event evt) { if (evt is InfoReceiverEvent) { ri._didMessage('m${convert.json.encode([evt.info, evt.rtt])}'); } diff --git a/lib/src/transport/polling.dart b/lib/src/transport/polling.dart index 5274e1e..26bbb7e 100644 --- a/lib/src/transport/polling.dart +++ b/lib/src/transport/polling.dart @@ -1,7 +1,6 @@ part of sockjs_client; class Polling { - Client ri; var receiverFactory; String recvUrl; @@ -10,7 +9,8 @@ class Polling { bool pollIsClosing = false; bool noCredentials; - Polling(this.ri, this.receiverFactory, this.recvUrl, this.xhrFactory, {bool this.noCredentials}) { + Polling(this.ri, this.receiverFactory, this.recvUrl, this.xhrFactory, + {bool this.noCredentials}) { _scheduleRecv(); } @@ -24,25 +24,25 @@ class Polling { var messageSubscription, closeSubscription; var closeHandler = (e) { - messageSubscription.cancel(); - closeSubscription.cancel(); - poll = null; - if (!pollIsClosing) { - if (e.reason == 'permanent') { - ri._didClose(1006, 'Polling error (${e.reason})'); - } else { - _scheduleRecv(); - } + messageSubscription.cancel(); + closeSubscription.cancel(); + poll = null; + if (!pollIsClosing) { + if (e.reason == 'permanent') { + ri._didClose(1006, 'Polling error (${e.reason})'); + } else { + _scheduleRecv(); } - }; - messageSubscription = poll.onMessage.listen(msgHandler); - closeSubscription = poll.onClose.listen(closeHandler); + } + }; + messageSubscription = poll.onMessage.listen(msgHandler); + closeSubscription = poll.onClose.listen(closeHandler); } abort() { - pollIsClosing = true; - if (poll != null) { - poll.abort(); - } + pollIsClosing = true; + if (poll != null) { + poll.abort(); + } } } diff --git a/lib/src/transport/receiver-xhr.dart b/lib/src/transport/receiver-xhr.dart index b4c4535..ff3a6a0 100644 --- a/lib/src/transport/receiver-xhr.dart +++ b/lib/src/transport/receiver-xhr.dart @@ -1,44 +1,44 @@ part of sockjs_client; - class XhrReceiver extends Receiver { +class XhrReceiver extends Receiver { + AbstractXHRObject xo = null; + int buf_pos = 0; - AbstractXHRObject xo = null; - int buf_pos = 0; - - XhrReceiver(url, AjaxObjectFactory xhrFactory, {bool noCredentials}) { + XhrReceiver(url, AjaxObjectFactory xhrFactory, {bool noCredentials}) { xo = xhrFactory('POST', url, noCredentials: noCredentials); - xo.onChunk.listen((e){ - if (e.status != 200) return; - readAndBroadcastMessage(e); + xo.onChunk.listen((e) { + if (e.status != 200) return; + readAndBroadcastMessage(e); }); xo.onFinish.listen((e) { - readAndBroadcastMessage(e); - xo = null; - var reason = (e.status == 200) ? 'network' : 'permanent'; - dispatch(new CloseEvent(reason: reason)); + readAndBroadcastMessage(e); + xo = null; + var reason = (e.status == 200) ? 'network' : 'permanent'; + dispatch(new CloseEvent(reason: reason)); }); } readAndBroadcastMessage(e) { while (true) { - var buf = e.text.substring(buf_pos); - var p = buf.indexOf('\n'); - if (p == -1) break; - buf_pos += p+1; - var msg = buf.substring(0, p); - dispatch(new MessageEvent(msg)); + var buf = e.text.substring(buf_pos); + var p = buf.indexOf('\n'); + if (p == -1) break; + buf_pos += p + 1; + var msg = buf.substring(0, p); + dispatch(new MessageEvent(msg)); } } abort() { if (xo != null) { - xo.close(); - dispatch(new CloseEvent(reason: 'user')); - xo = null; + xo.close(); + dispatch(new CloseEvent(reason: 'user')); + xo = null; } } } -Receiver XhrReceiverFactory(String recvUrl, AjaxObjectFactory xhrFactory, {bool noCredentials}) { +Receiver XhrReceiverFactory(String recvUrl, AjaxObjectFactory xhrFactory, + {bool noCredentials}) { return new XhrReceiver(recvUrl, xhrFactory, noCredentials: noCredentials); } diff --git a/lib/src/transport/receiver.dart b/lib/src/transport/receiver.dart index 8eb0cf5..5a5e135 100644 --- a/lib/src/transport/receiver.dart +++ b/lib/src/transport/receiver.dart @@ -5,4 +5,4 @@ class Receiver extends Object with event.Emitter { Stream get onClose => this["close"]; } -typedef Receiver ReceiverFactory(String recvUrl, AjaxObjectFactory xhrFactory); \ No newline at end of file +typedef Receiver ReceiverFactory(String recvUrl, AjaxObjectFactory xhrFactory); diff --git a/lib/src/transport/sender.dart b/lib/src/transport/sender.dart index 412ec7a..ee204d5 100644 --- a/lib/src/transport/sender.dart +++ b/lib/src/transport/sender.dart @@ -17,11 +17,11 @@ class BufferedSender { doSend(message) { sendBuffer.add(message); if (sendStop == null) { - sendSchedule(); + sendSchedule(); } } - /** For polling transports in a situation when in the message callback, + /** For polling transports in a situation when in the message callback, // new message is being send. If the sending connection was started // before receiving one, it is possible to saturate the network and // timeout due to the lack of receiving socket. To avoid that we delay @@ -29,34 +29,32 @@ class BufferedSender { // connection be started beforehand. This is only a halfmeasure and // does not fix the big problem, but it does make the tests go more // stable on slow networks. */ - sendScheduleWait() { - var tref; - sendStop = () { - sendStop = null; - tref.cancel(); - }; - tref = new Timer(new Duration(milliseconds:25), () { - sendStop = null; - sendSchedule(); - }); - } + sendScheduleWait() { + var tref; + sendStop = () { + sendStop = null; + tref.cancel(); + }; + tref = new Timer(new Duration(milliseconds: 25), () { + sendStop = null; + sendSchedule(); + }); + } sendSchedule() { if (!sendBuffer.isEmpty) { - var payload = '[${sendBuffer.join(',')}]'; - sendStop = sender(transUrl, - payload, - ([status, reason]) { - sendStop = null; - sendScheduleWait(); - }); - sendBuffer = []; + var payload = '[${sendBuffer.join(',')}]'; + sendStop = sender(transUrl, payload, ([status, reason]) { + sendStop = null; + sendScheduleWait(); + }); + sendBuffer = []; } } sendDestructor() { if (_sendStop != null) { - _sendStop(); + _sendStop(); } _sendStop = null; } @@ -65,7 +63,6 @@ class BufferedSender { /** TODO To be fixed since Dart 1.0 does not give access anymore to IFrame ReadyState and only authorize // postMessage communication */ class JsonPGenericSender { - html.FormElement _sendForm = null; html.TextAreaElement _sendArea = null; @@ -95,41 +92,42 @@ class JsonPGenericSender { html.IFrameElement iframe; try { - // ie6 dynamic iframes with target="" support (thanks Chris Lambacher) - iframe = new html.Element.html('