Incorporating AngularJs, I created a factory
to manage a WebSocket connection effectively.
Here is the code:
.factory('WebSocketConnection', function () {
var service = {};
service.callbacks = [];
service.connect = function() {
if(service.ws)
return;
var ws = new WebSocket("ws://localhost:9000/ws");
ws.onmessage = function (message) {
angular.forEach(service.callbacks, function(callback){
callback(message);
});
};
service.ws = ws;
};
service.send = function(message) {
service.ws.send(message);
};
service.subscribe = function(callback) {
service.callbacks.push(callback);
};
return service;
});
Essentially, this setup enables Angular components like controller
or factory
/service
to register specific callbacks to handle messages; hence, the callbacks array.
Below is an insightful snippet from a listening controller
:
WebSocketConnection.subscribe(function (message) {
$scope.$apply(function () {
var data = angular.fromJson(message.data);
$scope.notifications.push(data);
});
});
Therefore, this function is added to the callbacks array.
However, what if the controller is no longer needed at some point? (e.g., when navigating to another page based on a different controller)
It becomes necessary to remove the callback item (function) from the array each time the controller's usage is terminated to prevent unnecessary and potentially conflicting processing of the callback for subsequent messages.
This is not very convenient...
I contemplated broadcasting an event from the $rootScope
within the factory to enable a specific controller to handle its listeners/subscriptions automatically.
Yet, I prefer not to involve the entire scope tree, encompassing scopes that are not relevant.
What would be the ideal approach?
Note: I aim to establish a 1-N relationship where 1 represents the WebSocket handler (factory) and N denotes any active parallel Angular components, each needing to listen to messages.