Reputation: 42669
We have created a web application using ASP.Net on server and AngularJS on client. One of the requirement here is to track usage of various parts within the web app.
These statistics would require us to log users activity while he is using the application. I am thinking of using SignalR for the sends such activity data to server. We would make frequent requests to server to log activity data (fire and forget model).
My question here is, is it a good use case for using SignalR. Since it neither involves two way communication, neither updation of data in real-time for connected clients.
Also is there something available already which we can leverage to build such solution.
Upvotes: 0
Views: 1256
Reputation: 16056
I think probably yor best bet should be to create an httpInterceptor in angularJS and track whatever you want (or the information you have in hand), you can create a service in the client that connects and send the info to your log service in your server in an async way.
$provide.factory('loggerHttpInterceptor', function($q, logService) {
return {
'request': function(config) {
var deferred = $q.defer();
deferred.resolve(function(){
logService.send('someuser','some action',config.url,'other info');
});
return {config: $q.when(config), logger: deferred.promise};
//Other code for errors / response...etc
});
$httpProvider.interceptors.push('loggerHttpInterceptor');
Edit:
In the case you want to use signalR, you should go with hubs, they are easier to implement, for example I just have a separate folder in my solution named signalR with the hub and a hubActivator file (I prefer that solution against signalR dependencyResolver) to resolve my dependencies.
in this case you can create someting like:
public class TrackerService : Hub
{
private readonly ICacheClient _cacheClient;
private readonly ILogger_logger;
public TrackerService(ILogger logger,ICacheClient cacheClient){
_logger logger;
_cacheClient = cacheClient;
}
public override Task OnConnected(){
var session = _cacheClient.SessionAs<IAuthSession>();
//Get the current user, insert into a conected users list (that´s not 100% mandatory)
}
public override Task OnDisconnected(){
//Delete the user from the list
}
public void EventTracker(PageInfo pageInfo){
}
}
Choose a logger OOB provided by service stack or create your own tracker that´s up to you, by general you will need to override two methods in a hub: OnConnected and OnDisconnected it worth to mention that one user can have more than one connection (multiple tabs in the browser or multiple devices) by general you can use a list of users stored in a static variable or in cache (I prefer SS cache, for the time being I´m using InMemoryCache), then you will need to create the method to track the user info and put the information you need the that object.
in the client side you will need to add a jquery file (jquery-signalR-version.js) for signalR i your view, this file creates the dynamic client methods for the hub, and finally you will need to create a wrapper in angularJs for the signalR client.
factory('signalRHubProxy', ['$rootScope', 'signalRServer',
function($rootScope, signalRServer) {
function signalRHubProxyFactory(serverUrl, hubName) {
var connection = $.hubConnection(signalRServer);
var proxy = connection.createHubProxy(hubName);
return {
on: function(eventName, callback) {
proxy.on(eventName, function(result) {
$rootScope.$apply(function() {
if (callback) {
callback(result);
}
});
});
},
off: function(eventName, callback) {
proxy.off(eventName, function(result) {
$rootScope.$apply(function() {
if (callback) {
callback(result);
}
});
});
},
invoke: function(methodName, params, callback) {
proxy.invoke(methodName, params)
.done(function(result) {
$rootScope.$apply(function() {
if (callback) {
callback(result);
}
});
});
},
start: function() {
connection.start().done(function() {
console.log("Connected, transport = " + connection.transport.name);
});
},
connection: connection
};
}
return signalRHubProxyFactory;
}])
then you can use the proxy in your controllers:
function trackActivityCtrl($scope, $resource, signalRHubProxy) {
var hubProxy, pageInfo;
pageInfo.something = $scope.InfoToTrack
hubProxy.on("EventTracker", function (pageInfo) {
//logic to track the activity
});
hubProxy.start();
}
I hope that helps
Upvotes: 3