Reputation: 819
I have this part of code
$(function () {
//
// Initialize section
//
//
var hub = $.connection.hub,
platformHub = $.connection.PlatformHub,
tryingToReconnect = false,
firstConnection = true,
state = 'notconnected';
hub.url = 'http://localhost:80/signalr';
hub.logging = true;
//
// CLIENT METHODS SECTION
//
platformHub.client.hello = function (message) {
kendoConsole.log(message);
//Transient state variable from property bag
kendoConsole.log('Connection Started on : ' + platformHub.state.ConnectionStartedOn);
};
platformHub.client.greetings = function (message) {
kendoConsole.log(message);
};
//
// START HUB
//
//
function StartHub() {
try {
$('#connectionstatus').html('Connecting...');
hub.start({ transport: ['webSockets', 'longPolling', 'serverSentEvents', 'foreverFrame'] })
.done(function () {
tryingToReconnect = false;
state = 'connected';
//set connected status
$('#connectionstatus').html('connected!');
kendoConsole.log('transport = ' + hub.transport.name);
if (firstConnection) {
//send hello
$('#send').click(function () {
platformHub.server.hello();
});
//subscribe to groups
$('#subscribe').click(function () {
var v = $('#group').val();
platformHub.server.subscribe(v);
});
//handle error on server method.
//Each method is a promise and has a fail method
$('#error').click(function () {
try {
platformHub.server
.raiseError()
.done(function () {
kendoConsole.log('Raise error method called on server.');
})
.fail(function (error) {
kendoConsole.error('Failed: ' + error.message);
});
} catch (error) {
kendoConsole.error('Error: ' + error);
}
});
//get Time (With return value)
$('#getTime').click(function () {
try {
platformHub.server
.getServerTime()
.done(function (message) {
var _msg = "Current time = " + message.CurrentTime +
", utc = " + message.CurrentUtcTime +
', zone = ' + message.TimeZone.StandardName;
kendoConsole.log(_msg);
});
} catch (error) {
kendoConsole.error('Error: ' + error);
}
});
}
//set to fase in order not to create duplicate events for buttons
firstConnection = false;
})
.fail(function (error) {
kendoConsole.error('An error has occurred connecting: ' + error);
});
} catch (error) {
kendoConsole.error('An error has occurred connecting: ' + error);
}
}
//
// HANDLE EVENTS SECTION
//
//
hub
// TRying to reconnect event
//
.reconnecting(function () {
tryingToReconnect = true;
$('#connectionstatus').html('trying to reconnect....');
})
//
// state changed
//
.stateChanged(function (change) {
if (change.newState === $.connection.connectionState.disconnected) {
tryingToReconnect = true;
}
else { tryingToReconnect = false;}
})
//
// Rconnected event
//
.reconnected(function () {
tryingToReconnect = false;
state = 'connected';
$('#connectionstatus').html('reconnected');
})
//
// Disconnect event
//
//handle disconnect event. by default it will fire after 30 seconds
// https://www.asp.net/signalr/overview/guide-to-the-api/handling-connection-lifetime-events
//error handling https://www.asp.net/signalr/overview/guide-to-the-api/platformHubs-api-guide-javascript-client#connectionlifetime
.disconnected(function () {
tryingToReconnect = true;
state = 'disconnected';
if (hub.lastError) {
$('#connectionstatus').html('disconnected! Reason=' + hub.lastError.message);
}
else {
$('#connectionstatus').html('disconnected!');
}
//trying to reconnect.
if (tryingToReconnect) {
setTimeout(function () {
StartHub();
}, 5000); // Restart connection after 5 seconds.
}
})
//
// Slow Connection Event
//
.connectionSlow(function () {
kendoConsole.log('We are currently experiencing difficulties with the connection.')
})
//
// Error event
//
.error(function (error) {
kendoConsole.error('An error occurred on the hub connection: ' + error);
});
//start hub
StartHub();
});
That works fine... i have also created server side functionality.
Now i want to change the client side code and recreate the same functionality with AngularJS. Because i want to add this code only once in my app, i think that should use service or factory (i think service is better for this purpose).
Because i am new in AngularJS i am little confused about how can this work, i search on internet to find an example but cant find something usefull. Can anyone give some link or a simple example of how can recreate the same code with Angular?
Upvotes: 4
Views: 3161
Reputation: 23078
Since I stumbled across this question while searching for the same things, I thought of providing a late answer for future reference. I followed these steps:
1) Installed angular-signalr-hub => "angular-signalr-hub": "^1.6.3"
or something similar should appear in bower.json
2) Followed usage guide from the package Git page. My code looks like the following:
// make sure that you reference SignalR module
angular.module("customModule", ["SignalR"]);
// the identifier should match HubName attribute from server side (I will also add server side highlights after client implementation)
var hub = new Hub("Environment", {
//client side methods
listeners: {
'PushNotification': function (msg) {
console.log("Received message from hub: ", msg);
if (!msg)
return;
// do something with the data received from server
}
},
//server side methods
methods: ["Subscribe", "Unsubscribe"],
//handle connection error
errorHandler: function (error) {
console.error(error);
},
// set path to signalR. In my case, I have a service that provides the base path
rootPath: $rootUrlService.rootUrl + "signalr",
//TODO: check if it can be moved to a more generic place
// handle connection change events
stateChanged: function (state) {
switch (state.newState) {
case $.signalR.connectionState.connecting:
console.log("Connecting...");
break;
case $.signalR.connectionState.connected:
console.log("Connected ...");
break;
case $.signalR.connectionState.reconnecting:
console.log("Reconnected ...");
break;
case $.signalR.connectionState.disconnected:
console.log("Disconnected ...");
break;
}
}
});
3) Server side implementation - I have chosen a generic implementation
[HubName("Environment")]
public class EnvironmentHub : Hub
{
// not needed, but keep them as an example
public void Subscribe(string groupName)
{
Groups.Add(Context.ConnectionId, groupName);
}
public void Unsubscribe(string groupName)
{
Groups.Remove(Context.ConnectionId, groupName);
}
}
// define a service to allow dependency injection usage
public interface ISignalRHubService<THub>
where THub : IHub
{
/// <summary>
/// pushes some data for all clients within the specified group
/// </summary>
/// <param name="groupName">group name</param>
/// <param name="data">data to push to clients</param>
void PushNotification(string groupName, object data);
/// <summary>
/// pushes some data for all clients of this hub
/// </summary>
/// <param name="data">data to push to clients</param>
void PushNotification(object data);
}
public class SignalRHubService<THub> : ISignalRHubService<THub>
where THub : IHub
{
#region Properties
private readonly Lazy<IHubContext> _hub = new Lazy<IHubContext>(
() => GlobalHost.ConnectionManager.GetHubContext<THub>()
);
protected IHubContext Hub => _hub.Value;
#endregion
#region Methods
public void PushNotification(string groupName, object data)
{
Hub.Clients.Group(groupName).PushNotification(data);
}
public void PushNotification(object data)
{
Hub.Clients.All.PushNotification(data);
}
#endregion
}
Obtain an instance of ISignalRHubService<EnvironmentHub>
through DI and make a call like the following:
SignalRHubService.PushNotification(someData);
Upvotes: 4