what is the best design to use connections in signalr - signalr

I have some doubts regarding my software design with signalr,
usually I start with this code:
var connection = $.hubConnection();
var notifier = connection.createHubProxy('notifier');
connection.start()
.done(function () {
//alert('connection was succesful');
// your event handlers
});
UPDATED QUESTION
If you have a common click event handler that will only use signalR to broadcast a message, and this event handler is on a separate javascript file (out of the context of the current connection):
should I open the connection in the external script? or
should I send a reference of the proxy (already connected) to the external script?

When your page doesn't need a connection you should not open one.

Related

Why is this SignalR messages being received multiple times?

I am using SignalR in a Blazor server-side app. I added the Microsoft.AspNetCore.SignalR.Client Nuget package (v5.0.11) to the project, and used the following code to create the hub connection...
HubConnection hubConnection = new HubConnectionBuilder()
.WithUrl("url")
.Build();
await hubConnection.StartAsync();
I then send out a message with the following code (Debug.WriteLine added to confirm what's going on)...
Debug.WriteLine($"{DateTime.Now.ToLongTimeString()} SignalR msg sent");
await hubConnection.SendAsync("Send", "Hello");
The component that is to handle such messages creates the hub connection and hooks up to the On handler as follows...
HubConnection hubConnection = new HubConnectionBuilder()
.WithUrl("url")
.Build();
hubConnection.On<string>("Receive", msg =>
Debug.WriteLine($"{DateTime.Now.ToLongTimeString()} SignalR msg received - {msg}"));
await hubConnection.StartAsync();
When the message is sent out, it is definitely only being sent once (which I can confirm from the output panel, where I only see the "sent" output once), but it is received twice.
Searching around, it seems that a common reason for this is if jQuery was loaded twice. However, I have checked this, and it's not the case. It's only being loaded the once. Furthermore, one of the other developers on the team tried it, and he got the message received 15 times! Even if we had accidentally included jQuery twice, we certainly didn't include it 15 times. Also, he's using exactly the same code as me (checked out from source control), so we should get the same results if this were the issue.
Anyone any idea why this could be happening? Thanks
This can occur when you initialise a HubConnection within a component and don’t configure IDispose or IAsyncDispose on your component to dispose the HubConnection.
In a Blazor Server-Side application there is already a SignalR host pushing updates to the client.
If you want to push updates from a page you can use a Singleton Service to handle the communication.
If you set up your own SignalR hub and use the SignalR client in your components, your application is something like the diagram below:
As you can see, the client is actually running on the server. The SignalR hub you've added adds processing and memory overhead and does not add any value.
I created a simple sample app that uses a service that clients listen to for updates:
https://github.com/conficient/BlazorServerWithSignalR

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);
});

Signalr server messages to client cancelled (specific clients only)

I use signalR to display currently connected users. Some clients are failing to see the connected clients because the server to client connection is being cancelled by the client as shown below:
Below is my js code:
var progressNotifier = $.connection.activeConnectionsHub;
$.connection.hub.start().done(function () {
progressNotifier.server.showActiveConnections();
// code here
});
// client-side sendMessage function that will be called from the server-side
progressNotifier.client.addConnections = function (param) {
// code here never gets called
}
This only happens on some client browsers.
I tried disabling antivirus, firewall, malware etc. But it is still not working.
Does anyone have an idea what is causing this issue?

SignalR doesn't use 'on' subscription after connection to server is started

I have SignalR working with an Angular client, but I can't get proxy.on() to work if the connection is established before I subscribe to events.
My server method invokes the client method pushToClient on both hubs.
var connection1 = $.hubConnection(); //Works fine since I started connection AFTER subscribing
var proxy1 = connection1.createHubProxy('clientPushHub');
proxy1.on('sendToClient', function (message) {
console.log('This will work: ' + message);
});
connection.start();
var connection2 = $.hubConnection(); // Doesn't work when I start the connection BEFORE subscribing
var proxy2 = connection2.createHubProxy('clientPushHub');
connection2.start();
proxy2.on('sendToClient', function (message) {
console.log('This will not work: ' + message);
});
If I change things so that proxy2 subscribes to pushToClient before starting connection2, it works fine. Also tried doing the 'on' subscription in the start().done() callback but that did not work.
I've downloaded and verified this example works as I expected when subscribing after connecting, and this ASP.NET article/section specifically mentions you can do things in this order if you don't use a generated proxy, which I haven't.
What worked for the asker in this SO question does not work for me.
Any ideas where I might have gone wrong?
Based on this post, it sounds like you have to have at least one event listener prior to calling start. From there you can add more event handlers using the 'on' functionality.
EDIT:
Try this.
proxy2.on('foo',function(){});
connection2.start();
proxy2.on('sendToClient', function (message) {
console.log('This will not work: ' + message);
});
Also this is from the article you linked you for post:
Note: Normally you register event handlers before calling the start method to establish the connection. If you want to register some event handlers after establishing the connection, you can do that, but you must register at least one of your event handler(s) before calling the startmethod. One reason for this is that there can be many Hubs in an application, but you wouldn't want to trigger the OnConnected event on every Hub if you are only going to use to one of them. When the connection is established, the presence of a client method on a Hub's proxy is what tells SignalR to trigger the OnConnected event. If you don't register any event handlers before calling the start method, you will be able to invoke methods on the Hub, but the Hub'sOnConnected method won't be called and no client methods will be invoked from the server.

SignalR Connection interrupted

I have a signalR connection in a first page.
<script>
var online = $.connection.onlineHub;
online.client.aMessage = function () {
};
$.connection.hub.start().done(function () {
online.server.send();
});
</script>
The connection interrupt when i go to another page. Is there way this not happen.
There is no way to keep a SignalR connection open if your navigating away from the page responsible for initiating the connection.
One way you could potentially work around this issue is by creating a Single-Page Application or SPA.

Resources