SignalR JavaScript client API call connection - asp.net

As a new to ASP.NET environment and SignalR. I am trying to connect a JavaScript client (WebPage) to an API that includes SignalR HUB (developed using WEB.API 2) using only API Calls.
In other words, I just want to do API call to find my client connected to the signalR hub :
/*Instead of doing this*/
var connection = $.hubConnection();
connection.url = "https://www.myAPI.com/signalr/hubs";
var ClientHub = connection.createHubProxy('clientHub');
connection.start()
.done(...).fail(...);
/*I want to do the following*/
$.post( "https://www.myAPI.com/api/ConnectHUB", someClientData)
.done(...).fail(...);
Is that even possible with simple signalR tools ? or I have to implement something sophisticated myself (With websockets, long pooling and everything I read about) ?

Related

How re-use HttpClient F#

hello everyone i'm new in f#
i created a starter project with giraffe and then i want to make post calls to another api
and ran into the problem of reusing HttpClient and using sockets more efficiently.
let url = "https://someUrl"
let httpClient = new HttpClient ()
let! content = postAsync httpClient url Data
let result= JsonConvert.SerializeObject(result)
How correct is it to make web requests and reuse HttpClient?
I don't about Girafe specifically. In a regular ASP.NET core app you add the HttpClientFactory during the startup with.
service.AddHttpClient() (Seems like this should be called AddHttpClientFactory)
Then inject an instance of IHttpClientFactory into a controller as a constructor parameter.
Inside the controller create an HttpClient with
var client = _httpClientFactory.CreateClient()
Then configure the client settings and make requests using the client as needed.
The factory will manage the pooling of instances behind the scenes.
Maybe some variation on that can be adapted to Girafe.
See also
Make HTTP requests using IHttpClientFactory in ASP.NET Core

How to send Telemetry data from custom end point to azure application insight

I am working with WPF application with client server architecture we not provide internet for client machines so i implemented application telemetry in client WPF application with custom end point and it will send to our local server (on-premise) now i want to send this telemetry data into azure cloud(server have internet connection)
Depending on what language/platform your on-premise server application is written with, you can pick up the corresponding Application Insights SDK and write custom code using TelemetryClient to send telemetry to application insights.
UPDATE on follow up:
At the client end, you can serialize the whole telemetry object like below and then POST to your custom endpoint.
var traceTelemetry = new TraceTelemetry("test message", SeverityLevel.Critical);
traceTelemetry.Context.Cloud.RoleInstance = "test";
var traceTelemetrySerialized = JsonConvert.SerializeObject(traceTelemetry);
Then you can deserialize at the service end and then send to AI:
var traceTelemetryDeserialized = JsonConvert.DeserializeObject<TraceTelemetry>(traceTelemetrySerialized);
telemetryClient.TrackTrace(traceTelemetryDeserialized);

SignalR and switching servers and connection lost

SignalR is running on a certain Server with an open connnection. If we need to bring up another server, then take the original down does SignalR automatically reconnect with the NEW server and start functioning like it was on the first?
We had a similar problem and what we discovered was that SignalR does not automatically reconnect with the new server. Our solution to was to not use the generated proxy. We used an intermediary endpoint whose job it is to provide the current url to use. To connect to SignalR our flow calls the endpoint gets the result using that result we connect to that server for SignalR then when the SignalR connection closes or is lost we repeat the process again as if for the first time.
async function reconnect(connection){
const signalRUrl = await request('<<our intermediary url>>');
connection.hub.url = signalRUrl;
connection.start();
}
var connection = $.hubConnection();
var hubProxy = connection.createHubProxy('yourHub');
hubProxy.on('message',function(){});
await reconnect(connection);
connection.onClose(function () {
reconnect(connection);
});

WCF Service with SignalR

I have a web application which has few charts on dashboard. The data for charts is fetched on document.ready function at client side invoking a WCF service method.
What i want is now to use SignalR in my application. I am really new to SignalR. How can i call WCF methods from SignalR Hub or what you can say is that instead of pulling data from server i want the WCF service to push data to client every one minute.
Is there a way of communication between signalR and WCF service.
Also another approach can be to force client to ask for data from WCF Service every minute.
Any help will be really appreciated.
I have done following as of yet.
Client Side Function on my Dashboard page
<script src="Scripts/jquery.signalR-2.0.3.min.js"></script>
<!--Reference the autogenerated SignalR hub script. -->
<script src="/signalr/hubs"></script>
<a id="refresh">Refresh</a>
$(function() {
var dashboardHubProxy = $.connection.dashboardHub;
$.connection.hub.start().done(function() {
// dashboardHubProxy.server.refreshClient(parameters);
$("#refresh").click(function() {
dashboardHubProxy.server.refreshClient(parameters);
});
});
dashboardHubProxy.client.refreshChart = function (chartData) {
debugger;
DrawChart(chartData, 'Hourly Call Count For Last ' + Duration + ' Days', '#chartHourly', 'StackedAreaChart');
};
});
and my Dashboard Hub class is as follows
public class DashboardHub : Hub
{
private readonly ReportService ReportService = new ReportService();
public void RefreshClient(string parameters)
{
var chartData = ReportService.GenerateHourlyCallsTrendGraphicalReport(parameters);
Clients.All.refreshChart(chartData);
}
}
My SignalR startup class is as follows
[assembly: OwinStartup(typeof(CallsPortalWeb.Startup), "Configuration")]
namespace CallsPortalWeb
{
public static class Startup
{
public static void Configuration(IAppBuilder app)
{
ConfigureSignalR(app);
}
public static void ConfigureSignalR(IAppBuilder app)
{
app.MapSignalR();
}
}
}
When i click on refresh button and a debugger on RefreshClient method on hub the debugger doesn't get to the method which means i am unable to call server side method of SignalR.
Is there anything needs to be done in web.config?
I agree with AD.Net's comment. To elaborate slightly more though, the SignalR hubs can be hosted directly in your web project kinda the same way controllers are used. There is also a package out there so you can host the SignalR library on its own so it can act as a service all on its own. Either way you will need to hit the SignalR hub first as that is how it communicates then you would call your WCF service methods from within the hubs.
Brief explanation
Your HUB will have methods used by both your USER Client and your WCF Client. You may use something like UserConnected() for the user to call in and setup your logging of the connection. Then the WCF service may call your HUB with an UpdateUserStats(Guid connnectionId, UserStats stats) which would in turn call the USER client directly and provide the stats passed in like so Clients.Client(connectionId).updateStats(stats) which in turn would have a method on the USERS client named updateStats() that would handle the received information.
Initial page landing
What AD.Net provided is basic code that will be called when the user lands on the page. At this point you would want to log the ConnectionId related to that user so you can directly contact them back.
First contact with your hub touching WCF
From your Hub, you could call your WCF service as you normally would inside any normal C# code to fetch your data or perform action and return it to your user.
Method of updating the user periodically
SignalR removes the need for your client code to have to continually poll the server for updates. It is meant to allow you to push data out to the client with out them asking for it directly. This is where the persistence of the connections come into play.
You will probably want to create a wrapper to easily send messages to the hub from your application, since you are using WCF I would assume you have your business logic behind this layer so you will want the WCF service reaching out to your Hub whenever action X happens. You can do that by utilizing the Client side C# code as in this case your client is actually the user and the WCF service. With a chat application the other user is basically doing what you want your WCF service to do, which is send a message to the other client.
Usage example
You are running an online store. The dashboard displays how many orders there have been for the day. So you would wire up a call to the hub to send a message out to update the products ordered when a user places a new order. You can do this by sending it to the admin group you have configured and any admins on the dashboard would get the message. Though if these stats are very user specific, you will more then likely instead reach into the database, find the ConnectionId that the user has connected with and send the update message directly to that connectionid.
WCF Client Code Example
Just incase you want some code, this is directly from MS site on connecting with a .net client. You would use this in your WCF service, or wherever in your code you plan on connecting and then sending an update to your user.
var hubConnection = new HubConnection("http://www.contoso.com/");
IHubProxy stockTickerHubProxy = hubConnection.CreateHubProxy("StockTickerHub");
stockTickerHubProxy.On<Stock>("UpdateStockPrice", stock => Console.WriteLine("Stock update for {0} new price {1}", stock.Symbol, stock.Price));
await hubConnection.Start();
Here is a link directly to the .Net Client section: http://www.asp.net/signalr/overview/signalr-20/hubs-api/hubs-api-guide-net-client
I am sure you have seen this link but it really holds all the good information you need to get started. http://www.asp.net/signalr
Here is a more direct link that goes into usages with code for you. http://www.asp.net/signalr/overview/signalr-20/hubs-api/hubs-api-guide-server
ADDED: Here is a blog specific to Dashboards with SignalR and their polling.
http://solomon-t.blogspot.com/2012/12/signalr-and-interval-polling-for.html
ADDED: Here is a page on managing users signalR connections.
http://www.asp.net/signalr/overview/signalr-20/hubs-api/mapping-users-to-connections
Update for your code update
The .Net Client library (in NuGet) gives your .net code access to the hub. Since you are a client you will need to connect to the hub just like the User who is also a client. Your hub would act as the server for this. So with the .Net Client I am assuming you would setup a windows service that would internally poll, or something event based that would call the .Net Client code portion of it which would reach out to your hub. Your hub would take the information provided, more than likely a ConnectionId or GroupId and broad cast the User (which is perhaps on a website so it would be the JS client) a method that would update the front end for the user client. Basically what I mention under "Brief Explanation".
Now, to directly respond to the code you posted. That is Javascript, I would expect a connect like you have done. Updating the chart on initial connection is fine as well. If this is all the code signalR wise though you are missing a client side method to handle the refresh. Technically, instead of calling Clients.Caller.RefreshChart() you could just return that data and use it, which is what your javascript is doing right now. You are returning void but it is expecting a your date.
Now, I would actually say correct your javascript instead of correcting the hub code. Why? Because having a method in JS on your client that is called "refreshChart()" can be reused for when you are having your server reach out and update the client.
So I would recommend, dropping anything that is related to updating the dashboard in your JS done statement. If you want to do a notification or something to the user that is fine but dont update the grid.
Now create a JS client function called "refreshChart", note the lower case R, you can call it with a big R in c# but the js library will lowercase it so when you make the function have it will receive your dashboard information.
Now, on the server polling, or executing on some action, your WCF would call a method on the hub that would be say "UpdateDashboar(connectionId,dashInfo)" and that method would then inside of it call the "refreshChart" just like you are doing in your RefreshClient method, accept instead of doing Clients.Caller you would use Clients.Client(connectionId).refreshChart(chartInfo).
Directly the reason your code is not working is because you need to turn that Void into the type you expect to be returned. If the rest is coded right you will have it update once. You will need to implement the other logic I mentioned if you want it constantly updating. Which is again why I asked about how you are persisting your connections. I added a link to help you with that if you are not sure what I am talking about.
You should use the SignalR Hub to push data to the client. Your hub can consume a WCF service (the same way your client can) to get the data.
from client:
hub.VisitingDashBoard();
on the hub in the VisitingDashBoard method:
var data = wcfClient.GetDashboardData()//may be pass the user id from the context
Clients.Caller.UpdateDashboard(data)
Of course your client will have a handler for UpdateDashboard call

Using SignalR client through a web proxy

I am using the SignalR .NET client library to create a console app/win service to connect to a signal R Hub using HTTPS on the web. Some of these clients may require a web proxy to access the internet. Where/How do I set the web proxy for the SignalR client?
How on earth is this not a real Question guys? I cant get the signalR to connect to the web server hub when the client is behind a firewall/TMG proxy server.
Use Connection.Proxy property for that - https://msdn.microsoft.com/en-us/library/microsoft.aspnet.signalr.client.connection.proxy(v=vs.111).aspx
Example:
var hubConnection = new HubConnection(url);
var webProxy = new WebProxy(new Uri(“address”));
webProxy.Credentials = new NetworkCredential(“Username”, “Password”);
hubConnection.Proxy = webProxy;
Try this:
var webProxy = new WebProxy(new Uri(proxyUrl));
var connection = new HubConnectionBuilder().WithUrl("signalR hub endpoint", h => h.Proxy = webProxy).Build();
In fact we implemented signalr to have a kind of real time progress about some document generation.
Some of our customers couldn't create documents any more because the connection disconnected.
"Maybe" because of some proxy server who not really blocked but hold the request for a while to scan it, so that signalr client got a timeout

Resources