Page MenuHomePhabricator

D11252.id27019.diff
No OneTemporary

D11252.id27019.diff

diff --git a/resources/celerity/map.php b/resources/celerity/map.php
--- a/resources/celerity/map.php
+++ b/resources/celerity/map.php
@@ -200,6 +200,7 @@
'rsrc/externals/javelin/lib/Router.js' => '29274e2b',
'rsrc/externals/javelin/lib/URI.js' => '6eff08aa',
'rsrc/externals/javelin/lib/Vector.js' => 'cc1bd0b0',
+ 'rsrc/externals/javelin/lib/Websocket.js' => 'f82cb9df',
'rsrc/externals/javelin/lib/Workflow.js' => 'd149e002',
'rsrc/externals/javelin/lib/__tests__/Cookie.js' => '5ed109e8',
'rsrc/externals/javelin/lib/__tests__/DOM.js' => 'c984504b',
@@ -685,6 +686,7 @@
'javelin-view-interpreter' => '0c33c1a0',
'javelin-view-renderer' => '6c2b09a2',
'javelin-view-visitor' => 'efe49472',
+ 'javelin-websocket' => 'f82cb9df',
'javelin-workflow' => 'd149e002',
'lightbox-attachment-css' => '7acac05d',
'maniphest-batch-editor' => '8f380ebc',
@@ -1922,6 +1924,9 @@
'javelin-stratcom',
'phabricator-shaped-request',
),
+ 'f82cb9df' => array(
+ 'javelin-install',
+ ),
'f8ba29d7' => array(
'javelin-behavior',
'javelin-stratcom',
diff --git a/webroot/rsrc/externals/javelin/lib/Websocket.js b/webroot/rsrc/externals/javelin/lib/Websocket.js
new file mode 100644
--- /dev/null
+++ b/webroot/rsrc/externals/javelin/lib/Websocket.js
@@ -0,0 +1,169 @@
+/**
+ * @requires javelin-install
+ * @provides javelin-websocket
+ * @javelin
+ */
+
+/**
+ * Wraps a WebSocket.
+ */
+JX.install('WebSocket', {
+
+ construct: function(uri) {
+ this.setURI(uri);
+ },
+
+ properties: {
+ URI: null,
+
+ /**
+ * Called when a connection is established or re-established after an
+ * interruption.
+ */
+ openHandler: null,
+
+ /**
+ * Called when a message is received.
+ */
+ messageHandler: null,
+
+ /**
+ * Called when the connection is closed.
+ *
+ * You can return `true` to prevent the socket from reconnecting.
+ */
+ closeHandler: null
+ },
+
+ members: {
+ /**
+ * The underlying WebSocket.
+ */
+ _socket: null,
+
+ /**
+ * Is the socket connected?
+ */
+ _isOpen: false,
+
+ /**
+ * Has the caller asked us to close?
+ *
+ * By default, we reconnect when the connection is interrupted.
+ * This stops us from reconnecting if @{method:close} was called.
+ */
+ _shouldClose: false,
+
+ /**
+ * Number of milliseconds to wait after a connection failure before
+ * attempting to reconnect.
+ */
+ _delayUntilReconnect: null,
+
+
+ /**
+ * Open the connection.
+ */
+ open: function() {
+ if (!window.WebSocket) {
+ return;
+ }
+
+ this._shouldClose = false;
+
+ this._socket = new WebSocket(this.getURI());
+ this._socket.onopen = JX.bind(this, this._onopen);
+ this._socket.onmessage = JX.bind(this, this._onmessage);
+ this._socket.onclose = JX.bind(this, this._onclose);
+ },
+
+
+ /**
+ * Send a message.
+ *
+ * If the connection is not currently open, this method has no effect and
+ * the messages vanishes into the ether.
+ */
+ send: function(message) {
+ if (this._isOpen) {
+ this._socket.send(message);
+ }
+ },
+
+
+ /**
+ * Close the connection.
+ */
+ close: function() {
+ if (!$this._isOpen) {
+ return;
+ }
+ this._shouldClose = true;
+ this._socket.close();
+ },
+
+
+ /**
+ * Callback for connection open.
+ */
+ _onopen: function(e) {
+ this._isOpen = true;
+
+ // Reset the reconnect delay, since we connected successfully.
+ this._delayUntilReconnect = 2000;
+
+ var handler = this.getOpenHandler();
+ if (handler) {
+ handler();
+ }
+ },
+
+
+ /**
+ * Callback for message received.
+ */
+ _onmessage: function(e) {
+ var data = e.data;
+
+ var handler = this.getMessageHandler();
+ if (handler) {
+ handler(data);
+ }
+ },
+
+
+ /**
+ * Callback for connection close.
+ */
+ _onclose: function(e) {
+ this._isOpen = false;
+
+ var done = false;
+
+ var handler = this.getCloseHandler();
+ if (handler) {
+ done = handler();
+ }
+
+ // If we didn't explicitly see a close() call and the close handler
+ // did not return `true` to stop the reconnect, wait a little while
+ // and try to reconnect.
+ if (!done && !this._shouldClose) {
+ setTimeout(JX.bind(this, this._reconnect), this._delayUntilReconnect);
+ }
+ },
+
+
+ /**
+ * Reconnect an interrupted socket.
+ */
+ _reconnect: function() {
+ // Increase the reconnect delay by a factor of 2. If we fail to open the
+ // connection, the close handler will send us back here. We'll reconnect
+ // more and more slowly until we eventually get a valid connection.
+ this._delayUntilReconnect = this._delayUntilReconnect * 2;
+ this.open();
+ }
+
+ }
+});

File Metadata

Mime Type
text/plain
Expires
Wed, Mar 5, 3:20 PM (16 h, 13 m ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7225867
Default Alt Text
D11252.id27019.diff (4 KB)

Event Timeline