Property StayConnected
StayConnected
Gets or sets a value indicating whether the connection keeps trying to connect until the app stops or disposes it. Default is false.
Declaration
public bool StayConnected { get; set; }
Property Value
| Type | Description |
|---|---|
| bool |
Remarks
When it is true:
- A start that fails doesn't throw, unless it failed with an API error that isn't transient (see IsTransient(Exception)) and that the connection doesn't wait for a new session after (see below), a HubException, or an ArgumentException, InvalidOperationException or NotSupportedException. StartAsync(CancellationToken) then raises Reconnecting with the exception and returns, and the connection tries again.
- When the underlying connection closes, the connection starts again, also after the automatic reconnect of the underlying connection gave up.
It stays closed when the app stops or disposes it, and when the service closes it with an error that isn't transient and that it doesn't wait for
a new session after, such as a ForbiddenApiException thrown in the hub's
OnConnectedAsync, or with a HubException that isn't an API error. - A connection that SignalRApiClientBase created, which fails to start or closes because its session ended, with an UnauthorizedApiException with the SignInRequired error code, or because the service reported that its session ended (see the remarks of ApiHubConnection), whatever the error, waits for a new session on the device before it starts again. The API client reports a new session when a response sets the session cookie while it has none or a sign-in's response sets it, and when the app calls NotifySessionStarted(), which is the only report on browser platforms, where the browser holds the session cookie. A session that started after the connection last connected counts too. The new session can be another user's: a hub that checks the user ID precondition of the connection's client then refuses the connection with a UserChangedApiException, while a connection without a precondition connects with the new session. A connection that fails to start or closes with a UserChangedApiException waits for a new session in the same way, and then tries again: it connects once the session is its user's again, and with another user's session it is refused once more and waits again, so each session start leads to at most one attempt. In the browser, a request can also lead to one (see below). A connection created with ApiHubConnection(HubConnection) handles such errors like the other errors that aren't transient instead.
- In the browser, whose tabs share the session cookie, another tab can have signed in. A connection that closes because its session ended with the SignInRequired error code, while the hub had accepted it, doesn't end the session in its tab yet: it tries again with the browser's cookie once a session starts in its tab or 5 seconds after the close, whichever is first. With a session of the same user it connects, with another user's session it is refused as above, and a connection without a user ID precondition connects with the session, whoever's it is. A hub that accepts connections without a session accepts the connection without one if the browser has none, also one with a user ID precondition, which is only checked against a session, and the service doesn't track such a connection, so later session changes don't close it. Only a refusal with SignInRequired ends the session in the tab. After such a refusal, a start that the service refuses with it, or an automatic reconnect that the hub refuses with it, the connection waits for a session start in its tab, and meanwhile tries again with the browser's cookie every 5 minutes, without ending the session in the tab again. During either wait, and during the wait after a refusal with a UserChangedApiException, a successful response to a request of a client that shares the connection's session, which began during the wait and has the connection's user ID precondition, or any user ID precondition for a connection without one, makes the connection try again at once, at most once every 30 seconds: after a response that comes less than 30 seconds after its last such try, it tries again once they have passed. The response doesn't show that the browser has a session, since the service only checks the session of a request whose endpoint retrieves it, and a try that is refused is handled like the other tries.
The attempts are spaced like the ones of SignalR's default reconnect policy, which it continues: after a close, the first attempt is immediate,
and the ones that follow are 2, 10 and 30 seconds after the attempt before, and then every 30 seconds. A failed start counts as the first attempt,
and after the automatic reconnect of the underlying connection gave up, the attempts are every 30 seconds. A connection that closes less than 30
seconds after it started, such as when the hub's OnConnectedAsync fails, counts as a failed attempt, so the attempts after its close
continue with the next delay instead of starting over. An attempt that follows a start or close with an API error that has a retry time
(RetryAfter) waits at least that long. An attempt that waits for a new session is made as soon as the session starts,
and the attempts after it are spaced as after a close of a connection that was stable. An attempt that the end of a wait without a session start
leads to, as the browser's timed tries of its cookie, also waits out its delay, counted from the start or close before it, while one that a request
cues doesn't. Meanwhile State is Reconnecting, and once the hub accepts the connection,
Reconnected occurs. Setting it to false while the connection tries again stops it after its next attempt, which
then raises Closed.