Как лучше всего создать службу AngularJS, которая использует Autobahn.js 0.8.1 для реализации WAMP v1 (протокол обмена сообщениями приложений WebSocket)? В идеале я хотел бы, чтобы веб-сокет был доступен даже при изменении маршрута без повторной инициализации соединения.
Это внутреннее приложение, которое не может взаимодействовать с Интернетом, поэтому PubNub не подходит. Также было бы полезно избегать переписывания автобана, если это вообще возможно.
Похоже, что доступной библиотеки AngularJS WAMP нет, но это была бы желанная альтернатива.
Проблема связана с первоначальным подключением к Websocket, которое занимает примерно 150 мс. Если я пишу службу, которая подключается к веб-сокету, я должен использовать функцию тайм-аута, когда я вызываю сокет pubsub в своих контроллерах, чтобы я не выполнял вызов до подключения сокета.
Текущая реализация:
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);
}]);
Поскольку controller
нужно дождаться service
, это похоже на хорошее использование для $ q.defer. Когда я попытался реализовать следующее, он не откладывал, несмотря на изменение метода ab._Deferred
:
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);
});
}
Мне все еще нужно включать when.js
, как в этом вопросе? Получение зависимостей для правильной загрузки в requirejs (autobahn и whenjs)
Есть очень похожий вопрос без решения: https://stackoverflow.com/questions/17798504/angularjs-and-websocket-application-messaging-protocol.