From 0f0c74daaa04baede5f318db68db577cea207b4c Mon Sep 17 00:00:00 2001 From: Flavio Curella Date: Fri, 24 Mar 2017 17:33:55 -0500 Subject: [PATCH] Expose `WebSocketBridge.socket` (#572) * made `WebSocketBridge._socket` public We can provide a convenient way to hook custom behavior (such as debugging) by making the underlying `ReconnectingWebSocket` instance publicly available. Also removed the undocumented `onopen` constructor option. * recompile js --- .../static/channels/js/websocketbridge.js | 24 +++++++++---------- docs/javascript.rst | 7 ++++++ js_client/README.md | 13 +++++++--- js_client/src/index.js | 23 +++++++++--------- js_client/tests/websocketbridge.test.js | 10 ++++++++ 5 files changed, 49 insertions(+), 28 deletions(-) diff --git a/channels/static/channels/js/websocketbridge.js b/channels/static/channels/js/websocketbridge.js index 17382fe..d7b2845 100644 --- a/channels/static/channels/js/websocketbridge.js +++ b/channels/static/channels/js/websocketbridge.js @@ -228,8 +228,6 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } -var noop = function noop() {}; - /** * Bridge between Channels and plain javascript. * @@ -240,17 +238,19 @@ var noop = function noop() {}; * console.log(action, stream); * }); */ - var WebSocketBridge = function () { function WebSocketBridge(options) { _classCallCheck(this, WebSocketBridge); - this._socket = null; + /** + * The underlaying `ReconnectingWebSocket` instance. + * + * @type {ReconnectingWebSocket} + */ + this.socket = null; this.streams = {}; this.default_cb = null; - this.options = _extends({}, { - onopen: noop - }, options); + this.options = _extends({}, options); } /** @@ -283,7 +283,7 @@ var WebSocketBridge = function () { _url = url; } } - this._socket = new _reconnectingWebsocket2.default(_url, protocols, options); + this.socket = new _reconnectingWebsocket2.default(_url, protocols, options); } /** @@ -306,7 +306,7 @@ var WebSocketBridge = function () { var _this = this; this.default_cb = cb; - this._socket.onmessage = function (event) { + this.socket.onmessage = function (event) { var msg = JSON.parse(event.data); var action = void 0; var stream = void 0; @@ -322,8 +322,6 @@ var WebSocketBridge = function () { _this.default_cb ? _this.default_cb(action, stream) : null; } }; - - this._socket.onopen = this.options.onopen; } /** @@ -363,7 +361,7 @@ var WebSocketBridge = function () { }, { key: 'send', value: function send(msg) { - this._socket.send(JSON.stringify(msg)); + this.socket.send(JSON.stringify(msg)); } /** @@ -386,7 +384,7 @@ var WebSocketBridge = function () { stream: _stream, payload: action }; - _this2._socket.send(JSON.stringify(msg)); + _this2.socket.send(JSON.stringify(msg)); } }; } diff --git a/docs/javascript.rst b/docs/javascript.rst index 540047b..b7e2f67 100644 --- a/docs/javascript.rst +++ b/docs/javascript.rst @@ -47,5 +47,12 @@ To send a message to a specific stream:: webSocketBridge.stream('mystream').send({prop1: 'value1', prop2: 'value1'}) +The `WebSocketBridge` instance exposes the underlaying `ReconnectingWebSocket` as the `socket` property. You can use this property to add any custom behavior. For example:: + + webSocketBridge.socket.addEventListener('open', function() { + console.log("Connected to WebSocket"); + }) + + The library is also available as a npm module, under the name `django-channels `_ diff --git a/js_client/README.md b/js_client/README.md index 506cd49..5a97685 100644 --- a/js_client/README.md +++ b/js_client/README.md @@ -8,7 +8,7 @@ To process messages: import { WebSocketBridge } from 'django-channels' const webSocketBridge = new WebSocketBridge(); -webSocketBridge.connect(); +webSocketBridge.connect('/ws/'); webSocketBridge.listen(function(action, stream) { console.log(action, stream); }); @@ -18,14 +18,13 @@ To send messages: ``` webSocketBridge.send({prop1: 'value1', prop2: 'value1'}); - ``` To demultiplex specific streams: ``` const webSocketBridge = new WebSocketBridge(); -webSocketBridge.connect(); +webSocketBridge.connect('/ws/'); webSocketBridge.listen(); webSocketBridge.demultiplex('mystream', function(action, stream) { console.log(action, stream); @@ -40,3 +39,11 @@ To send a message to a specific stream: ``` webSocketBridge.stream('mystream').send({prop1: 'value1', prop2: 'value1'}) ``` + +The `WebSocketBridge` instance exposes the underlaying `ReconnectingWebSocket` as the `socket` property. You can use this property to add any custom behavior. For example: + +``` +webSocketBridge.socket.addEventListener('open', function() { + console.log("Connected to WebSocket"); +}) +``` diff --git a/js_client/src/index.js b/js_client/src/index.js index a0b7eeb..b2ebd81 100644 --- a/js_client/src/index.js +++ b/js_client/src/index.js @@ -1,8 +1,6 @@ import ReconnectingWebSocket from 'reconnecting-websocket'; -const noop = (...args) => {}; - /** * Bridge between Channels and plain javascript. * @@ -15,12 +13,15 @@ const noop = (...args) => {}; */ export class WebSocketBridge { constructor(options) { - this._socket = null; + /** + * The underlaying `ReconnectingWebSocket` instance. + * + * @type {ReconnectingWebSocket} + */ + this.socket = null; this.streams = {}; this.default_cb = null; - this.options = Object.assign({}, { - onopen: noop, - }, options); + this.options = {...options}; } /** @@ -49,7 +50,7 @@ export class WebSocketBridge { _url = url; } } - this._socket = new ReconnectingWebSocket(_url, protocols, options); + this.socket = new ReconnectingWebSocket(_url, protocols, options); } /** @@ -67,7 +68,7 @@ export class WebSocketBridge { */ listen(cb) { this.default_cb = cb; - this._socket.onmessage = (event) => { + this.socket.onmessage = (event) => { const msg = JSON.parse(event.data); let action; let stream; @@ -83,8 +84,6 @@ export class WebSocketBridge { this.default_cb ? this.default_cb(action, stream) : null; } }; - - this._socket.onopen = this.options.onopen; } /** @@ -119,7 +118,7 @@ export class WebSocketBridge { * webSocketBridge.send({prop1: 'value1', prop2: 'value1'}); */ send(msg) { - this._socket.send(JSON.stringify(msg)); + this.socket.send(JSON.stringify(msg)); } /** @@ -137,7 +136,7 @@ export class WebSocketBridge { stream, payload: action } - this._socket.send(JSON.stringify(msg)); + this.socket.send(JSON.stringify(msg)); } } } diff --git a/js_client/tests/websocketbridge.test.js b/js_client/tests/websocketbridge.test.js index b575629..0b347be 100644 --- a/js_client/tests/websocketbridge.test.js +++ b/js_client/tests/websocketbridge.test.js @@ -20,7 +20,17 @@ describe('WebSocketBridge', () => { const webSocketBridge = new WebSocketBridge(); webSocketBridge.connect('/somepath/'); }); + it('Can add event listeners to socket', () => { + const webSocketBridge = new WebSocketBridge(); + const myMock = jest.fn(); + webSocketBridge.connect('ws://localhost', {}); + webSocketBridge.socket.addEventListener('message', myMock); + mockServer.send('{"type": "test", "payload": "message 1"}'); + + expect(myMock.mock.calls.length).toBe(1); + + }); it('Processes messages', () => { const webSocketBridge = new WebSocketBridge(); const myMock = jest.fn();