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?
Related
I have web app on Azure with 2 slots.
Whenever the slot swap happens, all SignalR clients are disconnected and not even notified about the connection loss.
SignalR events such a Close, Error, Reconnected are never fired on the client.
How to prevent this or at least know when disconnect happens? (of course I need to avoid polling)
How to prevent this or at least know when disconnect happens?
We could enable SignalR tracing to view diagnositc infomration about events in your SignalR application. How to enable and configure tracing for SignalR servers and clients, we could refer to this document.
Detecting the reason for a disconnection
SignalR 2.1 adds an overload to the server OnDisconnect event that indicates if the client deliberately disconnected rather than timing out. The StopCalled parameter is true if the client explicitly closed the connection. In JavaScript, if a server error led the client to disconnect, the error information will be passed to the client as $.connection.hub.lastError.
C# server code: stopCalled parameter
public override System.Threading.Tasks.Task OnDisconnected(bool stopCalled)
{
if (stopCalled)
{
Console.WriteLine(String.Format("Client {0} explicitly closed the connection.", Context.ConnectionId));
}
else
{
Console.WriteLine(String.Format("Client {0} timed out .", Context.ConnectionId));
}
return base.OnDisconnected(stopCalled);
}
JavaScript client code: accessing lastError in the disconnect event.
$.connection.hub.disconnected(function () {
if ($.connection.hub.lastError)
{ alert("Disconnected. Reason: " + $.connection.hub.lastError.message); }
});
More details we could refer to Detecting the reason for a disconnection.
How to prevent this?
We could continuously reconnect it.
In some applications you might want to automatically re-establish a connection after it has been lost and the attempt to reconnect has timed out. To do that, you can call the Start method from your Closed event handler (disconnected event handler on JavaScript clients). You might want to wait a period of time before calling Start in order to avoid doing this too frequently when the server or the physical connection are unavailable. The following code sample is for a JavaScript client using the generated proxy.
$.connection.hub.disconnected(function() {
setTimeout(function() {
$.connection.hub.start();
}, 5000); // Restart connection after 5 seconds.
});
More details we could refer to How to continuously reconnect
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.
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.
I am building a single page app which uses sammy.js, knockout.js and SignalR. The main page (index.html) loads additional html pages into a div based upon the client side route.
I have 2 SignalR hubs, one is connected to by the initial page for server side push data and this works fine. However one of the pages which are loaded when the user navigates to it should also connect to a different hub.
In the main page I am doing the following:
window.hubReady = $.connection.hub.start()
var hub1 = $.connection.hub1;
hub1.updateReceived = function () {
alert('data from server');
}
window.hubReady.done(function() {
hub1.server.start();
});
In the second page I have:
var hub2 = $.connection.hub2;
hub2.updateReceived = function () {
alert('data from server');
}
window.hubReady.done(function() {
hub2.server.start();
});
However I never receive any updates in the second page.
Any idea where I am going wrong?
In order to receive updates from a hub you must have at least 1 client side function declared for that hub when the connection is started. Judging from the libraries you are using I'm assuming you have a single page application and therefore don't instantiate your hub2 data until the connection has already started.
So an easy fix would be to just declare a hub2 client side function alongside your hub1 client side function before start is called. If you want to add more client side functions after the connection has started you'll have to use the .on method.
AKA:
hub2.on("updateReceived", function () {
alert("data from server");
});
I have created a lib called SignalR.EventAggregatorProxy.
it proxies between server side domain events and client side code. Its designed with MVVM and SPA in mind and takes care of all the hub plumbing. Check the wiki for how to set it up.
https://github.com/AndersMalmgren/SignalR.EventAggregatorProxy/wiki
once its configured all you need to subscribe to a event is
ViewModel = function() {
signalR.eventAggregator.subscribe(MyApp.Events.TestEvent, this.onTestEvent, this);
};
MyApp.Events.TestEvent corresponds to a server side .NET event. You can also constraint which event should go to which usera
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.