Last active
January 19, 2017 09:55
-
-
Save iximiuz/9491829 to your computer and use it in GitHub Desktop.
AngularJS namespaced socket.io service concept
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
/** | |
* Пример использования socket.io namespaces в сервисе AngularJS. | |
* | |
* Цель: получить несколько отдельных каналов связи в рамках одного соединения. | |
* | |
* Проблема: так как сервисы в AngularJS являются синглтонами, не возможно | |
* получить несколько экземпляров сервиса Socket с разными значениями | |
* namespace. При этом хочется иметь отдельные сервисы, представляющие | |
* каналы связи в socket.io. | |
* Решение: делаем сервис Socket конструктором, а отдельные каналы связи - именованными | |
* сервисами-экземплярами сервиса Socket (или его наследниками). | |
* | |
* @inspired by http://www.html5rocks.com/en/tutorials/frameworks/angular-websockets/ | |
*/ | |
var services = angular.module('myApp.services', []); | |
// Concept: | |
services.factory('Socket', ['$rootScope', function($rootScope) { | |
var connections = {}; | |
function getConnection(channel) { | |
if (!connections[channel]) { | |
connections[channel] = io.connect('http://localhost:3000/' + channel); | |
} | |
return connections[channel]; | |
} | |
function Socket(namespace) { | |
this.namespace = namespace; | |
} | |
Socket.prototype.on = function(eventName, callback) { | |
var con = getConnection(this.namespace), self = this; | |
con.on(eventName, function() { | |
var args = arguments; | |
$rootScope.$apply(function() { | |
callback.apply(con, args); | |
}); | |
}); | |
}; | |
Socket.prototype.emit = function(eventName, data, callback) { | |
var con = getConnection(this.namespace); | |
con.emit(eventName, data, function() { | |
var args = arguments; | |
$rootScope.$apply(function() { | |
if (callback) { | |
callback.apply(con, args); | |
} | |
}); | |
}) | |
}; | |
return Socket; | |
}]); | |
// Examples: | |
services.factory('channelFoo', ['Socket', function(Socket) { | |
return new Socket('foo'); | |
}]); | |
services.factory('channelBar', ['Socket', function(Socket) { | |
function ChannelBar() { | |
this.namespace = 'bar'; | |
} | |
ChannelBar.prototype = angular.extend(Socket.prototype, {}); | |
ChannelBar.prototype.start = function() { | |
this.emit('start'); | |
}; | |
ChannelBar.prototype.exit = function() { | |
this.emit('exit'); | |
}; | |
return new ChannelBar(); | |
}]); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment