Pregunta

What is the best way to create an AngularJS Service that uses Autobahn.js 0.8.1 to implement WAMP v1 (WebSocket Application Messaging Protocol)? Ideally, I would like the websocket to be accessible even when the route changes without reinitializing the connection.

This is an internal app that can not communicate with the internet, so PubNub is not an option. It would also be helpful to avoid rewriting Autobahn if at all possible.

There does not appear to be an AngularJS WAMP library available, but that would be a welcomed alternative.

The issue revolves around the initial connection to the Websocket taking roughly 150ms. If I write a service that connects to the websocket, I have to use a timeout function when I make a call to the pubsub socket in my controllers so that I don't make the call before the socket is connected.

Current Implementation:

services.factory('socket', ['$rootScope',
  function($rootScope) {
    var pubsub = new ab.Session(
      'ws://1.1.1.1:8080',
      function(session) {
        console.log('New Session Established');
        return session;
      },
      function(code, reason) {
        console.log('Websocket connection closed. Code: '+code+'; reason: '+reason);
      }
    );
    return {
      pubsub: pubsub
    };
  }]);

controllers.controller('PageCtrl', ['$scope', 'socket', '$timeout',
  function($scope, socket, $timeout) {
    $timeout(function() {
      $scope.data = socket.pubsub.call('somecall', []).then(
        function(res) {
        }
      );
    }, 300);
  }]);

Since the controller needs to wait on the service, this seems like a good use for $q.defer. When I tried to implement the following it did not defer despite changing the ab._Deferred method:

services.factory('socket',['$rootScope', '$q',
  function($rootScope, $q) {
    // Change AutoBahn to use Angular Deferred:
    ab._Deferred = $q.defer;

    var service = {};
    service.address = 'ws://box:8080';
    service.name = 'socket';
    service.defer = $q.defer();

    service.connection = new ab.connect(
      // Address:
      service.address,
      // WAMP successful:
      function(session) {
        service.defer.promise.then(function() {
          service.session = session;
          console.log('connected!');
          return service;
        });
        // @todo: make another request now that we're connected
      },
      // WAMP unsuccessful:
      function(code, reason, detail) {
        // @todo: reject $q/defer here?
        //service.defer.reject(error);
      }
    );

    service.getDefer = function() {
      return service.defer;
    };

    service.subscribe = function(name, callback) {
      service.defer.promise.then(function() {
        service.session.subscribe(name, callback);
      });
      service.defer.resolve();
    };

    service.remoteCall = function(remote, msg) {
      service.session.call(remote, msg);
    };
    return service;

  }]);


controllers.controller('AppCtrl', ['$q', '$scope', 'socket') {
  var myDef = $q.defer();
  myDef.promise.then(function() {
    var ws = socket;
    var defer = ws.getDefer();
    defer.resolve();
    console.log('1');
    return ws;
  }).
  then(function(ws) {
    console.log('2');
    ws.remoteCall('somecall', function(res) {
      console.log('Call Successful: ' + res);
    });
    return ws;
  });
  $scope.ws = myDef.resolve();
  ws.remoteCall('anothercall', function(data) {
    console.log(data);
  });
}

Do I still need to include when.js, as in this question? Getting dependencies to load correctly in requirejs (autobahn and whenjs)

There is a very similar question with no solution: https://stackoverflow.com/questions/17798504/angularjs-and-websocket-application-messaging-protocol

¿Fue útil?

Solución

There is AngularWAMP I have tried this out and it works perfectly. Note this is for AngularJS (Not Angular2). With regards to the issue of not connecting to the internet: What you do is set up a router (use Crossbar) on your local LAN and your entire enterprise has access (not the internet). All your clients/servers will connect to your local router.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top