SignalR disconnects and does not reconnect -
whenever application gets reset, signalr disconnects not reconnect.
i have long running server task sends updates clients when each task completed.
// inside action executed on every completion of task var h = new forcehub(); h.messagesent(email);
above code stops sending updates when application gets reset (i can emulate problem touching web.config).
i'd way reconnect client. user has reload page updates again.
here hub definition
public class forcehub : hub { public void messagesent(string text) { getcontext().clients.all.sent(text); } public void updatestatus(string msg) { getcontext().clients.all.status(msg); } ihubcontext getcontext() { return globalhost.connectionmanager.gethubcontext<forcehub>(); } public override task onconnected() { try { ioc.resolve<ilogger>().info("signalr connected -----------"); }catch (exception){} return base.onconnected(); } public override task ondisconnected() { try { ioc.resolve<ilogger>().info("signalr disconnected -----------"); } catch (exception) { } return base.ondisconnected(); } public override task onreconnected() { try { ioc.resolve<ilogger>().info("signalr re-connected -----------"); } catch (exception) { } return base.onreconnected(); } }
i can see connected , re-connected events triggered after startup, after touching web.config, don't see of these events triggered.
i tried catching on client, event not tirggered:
$.connection.hub.disconnected(function () { console.error('signalr disconnected, retrying connection'); logerror('signal lost.'); settimeout(function () { connection.start(); }, 1000); });
update
i hooked state changed event, triggered, re-connection attempt below not work.
$.connection.hub.statechanged(function (state) { console.debug('signalr state changed', state); if (state.newstate == 1) { console.debug('restarting'); settimeout(function () { $.connection.hub.start(); }, 1000); } });
this event gets triggered twice: newstate 2 ,and 1.
i might have clue... touching web.config produces apppool recycle, meaning new worker process created new requests while existing process continue while until remaining requests end or timeout reached. request not end in timeout period terminated.
signalr client reconnects new process while long running task running in old process, when on long running task
globalhost.connectionmanager.gethubcontext<forcehub>();
you reference "old" hub while client connected "new" hub. that's why test preformed wasp worked: making new request publish on signalr hub processed in newly created worker process.
you try configure singalr backplane (https://www.asp.net/signalr/overview/performance/scaleout-in-signalr), it’s easy configure using sql server (https://www.asp.net/signalr/overview/performance/scaleout-with-sql-server). backplane should capable of connect 2 worker processes , notification on client.
if problem, notifications generated new requests work without backplane. notice real purpose of backplane scale out signalr, is, connect farm of webservers between them.
also keep in mind running long-running task inside iis task hard achieve as, among other things, iis regular apppool recycles , has timeout limits requests execute. recommend read following post: http://www.hanselman.com/blog/howtorunbackgroundtasksinaspnet.aspx “if think can write background task yourself, it's you'll wrong. i'm not impugning skills, i'm saying it's subtle. plus, why should have to?”
hope helps
Comments
Post a Comment