'app.widgets',
/* Feature areas */
- 'app.example'
+ 'app.example',
+ 'app.shared-stomp'
]);
}());
--- /dev/null
+(function () {
+ 'use strict';
+
+ angular
+ .module('app.shared-stomp')
+ .controller('SharedStompController', SharedStompController);
+
+ /**
+ * @ngdoc controller
+ * @name app.shared-stomp.controller:SharedStompController
+ *
+ * @requires $location
+ * @requires app.shared-stomp.sharedWorker
+ *
+ * <p>
+ * <br>
+ * {@link https://docs.angularjs.org/api/ng/service/$location $location}
+ * </p>
+ *
+ * @description
+ * SharedStompController controller.
+ */
+ /* @ngInject */
+ function SharedStompController($location, sharedWorker) {
+ var vm = this;
+
+
+ vm.url = $location.protocol() + '://' + $location.host() + '/spring-stomp-server-full/fullportfolio';
+ vm.clientDestination = '/topic/greeting';
+ vm.serverDestination = '/app/greeting';
+ vm.connectHeaders = JSON.stringify({
+ login: 'mylogin',
+ passcode: 'mypasscode',
+ // User defined headers
+ 'client-id': 'gumartin-id'
+ }, null, 4);
+ // User defined headers
+ vm.sendHeaders = JSON.stringify({
+ priority: 9
+ }, null, 4);
+ // User defined headers
+ vm.subscribeHeaders = JSON.stringify({
+ id: 123456
+ }, null, 4);
+
+
+
+ vm.connect = function () {
+ sharedWorker.connect(JSON.parse(connectHeaders), connectSuccessCallback, connectErrorCallback);
+ };
+
+ vm.subscribe = function () {
+ sharedWorker.subscribe(clientDestination, subscribeCallback, JSON.parse(subscribeHeaders));
+ };
+
+ vm.unSubscribe = function () {
+ sharedWorker.unSubscribe();
+ };
+
+ vm.send = function () {
+ sharedWorker.send(vm.serverDestination, JSON.parse(vm.sendHeaders), vm.payload);
+ };
+
+ vm.disconnect = function() {
+ sharedWorker.disconnect(disconnectCallback);
+ };
+
+ function connectSuccessCallback() {
+ // called back after the client is connected and authenticated to the STOMP server
+ alert('got connection');
+ }
+
+ function connectErrorCallback(error) {
+ // display the error's message header:
+ alert(error.headers.message);
+ }
+
+ function subscribeCallback(message) {
+ // called when the client receives a STOMP message from the server
+ if (message.body) {
+ alert('got message with body ' + message.body);
+ } else {
+ alert('got empty message');
+ }
+ }
+
+ function disconnectCallback() {
+ alert('See you next time!');
+ }
+ }
+
+})();
--- /dev/null
+<!DOCTYPE html>
+<div class="container" ng-controller="ExampleController as vm">
+ <div>
+ <span>1. Connect</span><br>
+ <button ng-click="vm.connect()">Connect to Endpoint</button>
+ <br>
+
+ <label>
+ Endpoint:<br>
+ <input value="http://localhost:8080" ng-model="vm.url" placeholder="url">
+ </label>
+ <br>
+ <label>
+ Headers:<br>
+ <textarea style="width: 200%; border: none" auto-height
+ ng-model="vm.connectHeaders" placeholder="headers">
+ {"login":"superadmin","passcode":"12345678"}
+ </textarea>
+ </label>
+ </div>
+
+ <hr>
+
+ <div>
+ <span>2. Disconnect</span><br>
+ <button ng-click="vm.disconnect()">Disconnect from Endpoint</button>
+ </div>
+
+ <hr>
+
+ <div>
+ <span>3. Subscribe</span><br>
+ <button ng-click="vm.subscribe()">Subscribe to destination</button>
+ <br>
+
+ <label>
+ Queue:<br>
+ <input value="/rpc/" ng-model="vm.clientDestination" placeholder="Client-Destination">
+ </label>
+ <br>
+ <label>
+ Headers:<br>
+ <textarea style="width: 200%; border: none" auto-height
+ ng-model="vm.subscribeHeaders" placeholder="headers">
+ {"rid": 1234}
+ </textarea>
+ </label>
+ </div>
+
+ <hr>
+
+ <div>
+ <span>4. Unsubscribe</span><br>
+ <button ng-click="vm.unSubscribe()">Unsubscribe from destination</button>
+ </div>
+
+ <hr>
+
+ <div>
+ <span>5. Send</span><br>
+ <button ng-click="vm.send()">Send message to server</button>
+ <br>
+
+ <label>
+ Server-Destination:<br>
+ <input value="/dest" ng-model="vm.serverDestination" placeholder="channel">
+ </label>
+ <br>
+ <label>
+ Body / Payload:<br>
+ <textarea style="width: 200%; border: none" auto-height
+ ng-model="vm.payload" placeholder="payload">
+ {"key":"value"}
+ </textarea>
+ </label>
+ <br>
+ <label>
+ Headers:<br>
+ <textarea style="width: 200%; border: none" auto-height
+ ng-model="vm.sendHeaders" size="50" placeholder="headers">
+ {"rid": 1234}
+ </textarea>
+ </label>
+ </div>
+
+ <textarea id="log"></textarea>
+
+</div>
--- /dev/null
+(function() {
+ 'use strict';
+
+ /**
+ * @ngdoc overview
+ * @name app.shared-stomp
+ *
+ * @requires app.core
+ *
+ * @description
+ * # app.shared-stomp
+ *
+ * ## Module STOMP Shared Worker example.
+ * STOMP Shared Worker example
+ */
+ angular.module('app.shared-stomp', [
+ 'app.core'
+ ]);
+
+})();
--- /dev/null
+(function() {
+ 'use strict';
+
+ angular
+ .module('app.shared-stomp')
+ .config(route);
+
+ /**
+ * @ngdoc service
+ * @name app.shared-stomp.route
+ *
+ * @requires $stateProvider
+ * @requires $urlRouterProvider
+ *
+ * <p>
+ * <br>
+ * {@link http://angular-ui.github.io/ui-router/site/#/api/ui.router.state.$stateProvider $stateProvider} <br>
+ * {@link http://angular-ui.github.io/ui-router/site/#/api/ui.router.router.$urlRouterProvider $urlRouterProvider}
+ * </p>
+ *
+ *
+ * @description
+ * Router configuration for Shared Worker STOMP application.
+ */
+ /* @ngInject */
+ function route($stateProvider, $urlRouterProvider) {
+ var state = 'shared-stomp';
+ var config = {
+ abstract: false,
+ url: '/shared-stomp',
+ templateUrl: 'app/shared-stomp/shared-stomp.html'
+ };
+
+ $urlRouterProvider.otherwise(state);
+ $stateProvider.state(state, config);
+ }
+}());
--- /dev/null
+describe('app.shared-stomp', function() {
+ 'use strict';
+
+ describe('state', function() {
+ var view = {
+ example: 'app/shared-stomp/shared-stomp.html'
+ };
+ var $state;
+
+ beforeEach(function() {
+ module('app.shared-stomp');
+
+ inject(function(_$state_) {
+ $state = _$state_;
+ });
+ });
+
+ it('should map /shared-stomp route to users View template', function() {
+ expect($state.get('shared-stomp').templateUrl).toEqual(view.example);
+ });
+
+ });
+
+});
--- /dev/null
+(function () {
+ 'use strict';
+
+ angular
+ .module('app.shared-stomp')
+ .factory('sharedWorker', sharedWorker);
+
+ /**
+ * @ngdoc service
+ * @name app.shared-stomp.sharedWorker
+ *
+ * @requires $window
+ *
+ * <p>
+ * <br>
+ * {@link https://docs.angularjs.org/api/ng/service/$window $window} <br>
+ * </p>
+ *
+ * @description
+ * sharedWorker service.
+ */
+ /* @ngInject */
+ function sharedWorker($window) {
+ var _messagePort;
+ var _connectSuccessCallback;
+ var _connectErrorCallback;
+ var _subscribeCallback;
+ var _disconnectCallback;
+
+ init();
+
+ return {
+ connect: connect,
+ subscribe: subscribe,
+ unSubscribe: unSubscribe,
+ send: send,
+ disconnect: disconnect
+ };
+
+ function init() {
+ if (!!$window.SharedWorker) {
+ var sharedWorker = new $window.SharedWorker('scripts/workers/shared.js');
+ _messagePort = sharedWorker.port;
+ _messagePort.onmessage = onMessage;
+ } else {
+ throw new Error('Shared Web Workers not supported. Try with a modern browser');
+ }
+ }
+
+ /**
+ * @ngdoc method
+ * @name connect
+ * @methodOf app.shared-stomp.connect
+ *
+ * @description
+ * Connects to back end.
+ *
+ * @param {string} url URL to connect.
+ * @param {string} connectHeaders Connection headers.
+ * @param {function} connectSuccessCallback Connection success call back.
+ * @param {function} connectErrorCallback Connection error call back.
+ *
+ */
+ function connect (url, connectHeaders, connectSuccessCallback, connectErrorCallback) {
+ var message = {
+ command: 'connect',
+ url: url,
+ connectHeaders: connectHeaders
+ };
+
+ _connectSuccessCallback = connectSuccessCallback;
+ _connectErrorCallback = connectErrorCallback;
+ _messagePort.postMessage(message);
+ }
+
+ function subscribe(clientDestination, subscribeCallback, subscribeHeaders) {
+ var message = {
+ command: 'subscribe',
+ clientDestination: clientDestination,
+ subscribeHeaders: subscribeHeaders
+ };
+
+ _subscribeCallback = subscribeCallback;
+ _messagePort.postMessage(message);
+ }
+
+ function unSubscribe() {
+ var message = {
+ command: 'unSubscribe'
+ };
+
+ _messagePort.postMessage(message);
+ }
+
+ function send(serverDestination, sendHeaders, payload) {
+ var message = {
+ command: 'send',
+ serverDestination: serverDestination,
+ sendHeaders: sendHeaders,
+ payload: payload
+ };
+
+ _messagePort.postMessage(message);
+ }
+
+ function disconnect(disconnectCallback) {
+ var message = {
+ command: 'disconnect'
+ };
+
+ _disconnectCallback = disconnectCallback;
+ _messagePort.postMessage(message);
+ }
+
+
+ function onMessage(event) {
+ if (event.data.error) {
+ // Error
+ } else {
+ callBack(event.data);
+ }
+ }
+ // var send {
+ // command:
+ // connectionHeaders:
+ // }
+ // var result {
+ // command:
+ // connectError:
+ // message:
+ // };
+ function callBack(data) {
+
+ switch(data.command) {
+ case 'connectSuccessCallback':
+ _connectSuccessCallback();
+ break;
+ case 'connectErrorCallback':
+ _connectErrorCallback(data.connectError);
+ break;
+ case 'subscribeCallback':
+ _subscribeCallback(data.message);
+ break;
+ case 'disconnectCallback':
+ _disconnectCallback();
+ break;
+ default:
+ break;
+ }
+
+ }
+ }
+
+}());
<!-- inject:js -->
<script src="/src/stomp/app/widgets/widgets.module.js"></script>
<script src="/src/stomp/app/widgets/auto-height.directive.js"></script>
+ <script src="/src/stomp/app/shared-stomp/shared-stomp.module.js"></script>
+ <script src="/src/stomp/app/shared-stomp/shared-worker.service.js"></script>
+ <script src="/src/stomp/app/shared-stomp/shared-stomp.route.js"></script>
+ <script src="/src/stomp/app/shared-stomp/shared-stomp.controller.js"></script>
<script src="/src/stomp/app/example/example.module.js"></script>
<script src="/src/stomp/app/example/example.route.js"></script>
<script src="/src/stomp/app/example/example.controller.js"></script>
--- /dev/null
+'use strict';
+
+importScripts('/bower_components/sockjs/sockjs.js');
+importScripts('/bower_components/stomp-websocket/lib/stomp.min.js');
+
+var messagePorts = [];
+var client;
+var subscription;
+
+self.onconnect = function(event) {
+ var messagePort = event.ports[0];
+ messagePort.onmessage = onMessage;
+ // Starts the sending of messages queued on the port
+ // (only needed when using EventTarget.addEventListener; it is implied when using MessagePort.onmessage.)
+ // messagePort.start();
+
+ messagePorts.push(messagePort);
+
+ // When and where should I call close method?
+ // Should I call messagePort.close() or SharedWorkerGlobalScope.close()?
+ // SharedWorker doesn't have close method but SharedWorkerGlobalScope has one :(
+};
+
+self.onerror = function() {
+ self.console.log('SharedWorkerGlobalScope: There is an error with the shared worker!');
+};
+
+function onMessage(event) {
+ callCommand(event.data);
+}
+
+function postMessage(message) {
+ messagePorts.forEach(function (messagePort) {
+ messagePort.postMessage(message);
+ });
+}
+
+function callCommand(data) {
+ switch(data.command) {
+ case 'connect':
+ connect(data.url, data.connectHeaders);
+ break;
+ case 'subscribe':
+ subscribe(data.clientDestination,data.subscribeHeaders);
+ break;
+ case 'unSubscribe':
+ unSubscribe();
+ break;
+ case 'send':
+ send(data.serverDestination, data.sendHeaders, data.payload);
+ break;
+ case 'disconnect':
+ disconnect();
+ break;
+ default:
+ break;
+ }
+}
+
+function connect(url, connectHeaders) {
+ var options = {
+ debug: true,
+ devel: true,
+ //jscs:disable
+ protocols_whitelist: ['websocket', 'xdr-streaming', 'xhr-streaming'],
+ //jscs:enable
+ transports: ['websocket', 'xdr-streaming', 'xhr-streaming']
+ };
+
+ var ws = new SockJS(url, undefined, options);
+ client = Stomp.over(ws);
+ client.heartbeat.outgoing = 20000; // client will send heartbeats every 20000ms
+ client.heartbeat.incoming = 20000; // client does not want to receive heartbeats from the server
+ client.connect(JSON.parse(connectHeaders), connectSuccessCallback, connectErrorCallback);
+}
+
+function subscribe(clientDestination, subscribeHeaders) {
+ subscription = client.subscribe(clientDestination, subscribeCallback, JSON.parse(subscribeHeaders));
+}
+
+function unSubscribe() {
+ subscription.unsubscribe();
+}
+
+function send(serverDestination, sendHeaders, payload) {
+ client.send(serverDestination, JSON.parse(sendHeaders), payload);
+}
+
+function disconnect() {
+ client.disconnect(disconnectCallback);
+}
+
+function connectSuccessCallback() {
+ postMessage({
+ command: 'connectSuccessCallback'
+ });
+}
+
+function connectErrorCallback(error) {
+ postMessage({
+ command: 'connectErrorCallback',
+ connectError: error
+ });
+}
+
+function subscribeCallback(message) {
+ postMessage({
+ command: 'subscribeCallback',
+ message: message
+ });
+}
+
+function disconnectCallback() {
+ postMessage({
+ command: 'disconnectCallback'
+ });
+}