Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions Assets/Plugins/StreamChat/Core/Configs/IStreamClientConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,20 @@ public interface IStreamClientConfig
/// Does not change server history. See <see cref="StatefulModels.IStreamChannel.MessageCacheWindow"/>.
/// </summary>
MessageCacheWindow DefaultMessageCacheWindow { get; set; }

/// <summary>
/// When the app goes to the background, temporarily drop the chat connection without logging
/// the user out. When the app returns to the foreground, reconnect and recover missed state.
/// Defaults to <c>true</c>. Set to <c>false</c> to keep the connection alive while backgrounded.
///
/// In the Unity Editor this has no effect — pausing play mode or unfocusing the Game view
/// would otherwise disconnect constantly. A warning is logged once.
///
/// Applies when you create the client with <see cref="StreamChatClient.CreateDefaultClient"/>.
/// If you drive the client yourself (you call Update each frame), pause and resume with
/// <see cref="IStreamChatClient.PauseConnectionAsync"/> /
/// <see cref="IStreamChatClient.ResumeConnectionAsync"/> instead.
/// </summary>
bool DisconnectOnApplicationPause { get; set; }
}
}
2 changes: 2 additions & 0 deletions Assets/Plugins/StreamChat/Core/Configs/StreamClientConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,7 @@ public class StreamClientConfig : IStreamClientConfig
public bool OptimisticMessageInsert { get; set; } = true;

public MessageCacheWindow DefaultMessageCacheWindow { get; set; } = null;

public bool DisconnectOnApplicationPause { get; set; } = true;
}
}
22 changes: 22 additions & 0 deletions Assets/Plugins/StreamChat/Core/IStreamChatClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -342,8 +342,30 @@ Task<StreamDeleteChannelsResponse> DeleteMultipleChannelsAsync(IEnumerable<IStre
/// <param name="timeoutMinutes">Optional timeout. Without timeout users will stay muted indefinitely</param>
Task MuteMultipleUsersAsync(IEnumerable<IStreamUser> users, int? timeoutMinutes = default);

/// <summary>
/// Disconnect the local user and stop automatic reconnects. The next connect is a fresh login,
/// not a reconnect recovery. Use <see cref="PauseConnectionAsync"/> to drop the WebSocket
/// without ending the session.
/// </summary>
Task DisconnectUserAsync();

/// <summary>
/// Temporarily drop the chat connection without logging the user out.
/// Call <see cref="DisconnectUserAsync"/> to sign off. Resume with
/// <see cref="ResumeConnectionAsync"/>. If
/// <see cref="Configs.IStreamClientConfig.DisconnectOnApplicationPause"/> is enabled,
/// <see cref="StreamChatClient.CreateDefaultClient"/> already does this when the app
/// backgrounds and returns.
/// </summary>
Task PauseConnectionAsync();

/// <summary>
/// Reconnect after <see cref="PauseConnectionAsync"/> or after the app was backgrounded.
/// No-op if already connected or connecting. This is not login — use
/// <see cref="ConnectUserAsync"/> to sign in.
/// </summary>
Task ResumeConnectionAsync();

bool IsLocalUser(IStreamUser messageUser);

/// <summary>
Expand Down
46 changes: 46 additions & 0 deletions Assets/Plugins/StreamChat/Core/LowLevelClient/DisconnectCause.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
namespace StreamChat.Core.LowLevelClient
{
/// <summary>
/// Why the WebSocket was closed. Used by
/// <see cref="IStreamChatLowLevelClient.DisconnectAsync(DisconnectCause)"/> to decide whether the
/// reconnect scheduler stays armed. Logout stops auto-reconnect; every other cause leaves it running.
///
/// Stateful clients should call <see cref="IStreamChatClient.DisconnectUserAsync"/>,
/// <see cref="IStreamChatClient.PauseConnectionAsync"/>, or
/// <see cref="IStreamChatClient.ResumeConnectionAsync"/> instead of this enum.
/// </summary>
public enum DisconnectCause
{
/// <summary>
/// No disconnect has been recorded yet, or the close was not classified.
/// </summary>
Unknown = 0,

/// <summary>
/// <see cref="IStreamChatClient.DisconnectUserAsync"/>. Session ended; the scheduler is stopped
/// until the next <see cref="IStreamChatClient.ConnectUserAsync"/>.
/// </summary>
UserLogout,

/// <summary>
/// <see cref="IStreamChatClient.PauseConnectionAsync"/>. User session is kept; reconnect with
/// <see cref="IStreamChatClient.ResumeConnectionAsync"/> (the scheduler also stays armed).
/// </summary>
ConnectionReleased,

/// <summary>
/// The app was backgrounded. Session is kept; reconnects when the app returns to the foreground.
/// </summary>
ApplicationPause,

/// <summary>
/// Network became unavailable. Scheduler reconnects when the network is back.
/// </summary>
Network,

/// <summary>
/// Server health-check timed out. Scheduler reconnects.
/// </summary>
HealthTimeout,
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System.Diagnostics;

namespace StreamChat.Core.LowLevelClient
{
/// <summary>
/// Elapsed-time source for the per-frame event drain budget. Production uses
/// <see cref="DiagnosticsElapsedStopwatch"/>; tests inject a fake so pacing is deterministic.
/// </summary>
internal interface IElapsedStopwatch
{
void Restart();

double ElapsedMilliseconds { get; }
}

internal sealed class DiagnosticsElapsedStopwatch : IElapsedStopwatch
{
public void Restart() => _stopwatch.Restart();

public double ElapsedMilliseconds => _stopwatch.Elapsed.TotalMilliseconds;

private readonly Stopwatch _stopwatch = new Stopwatch();
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,25 @@ void SetReconnectStrategySettings(ReconnectStrategy reconnectStrategy, float? ex

void ConnectUser(AuthCredentials userAuthCredentials);

Task DisconnectAsync(bool permanent = false);
/// <summary>
/// Close the WebSocket. Pass <see cref="DisconnectCause.UserLogout"/> to stop automatic reconnects;
/// every other cause leaves the scheduler armed.
/// </summary>
Task DisconnectAsync(DisconnectCause cause = DisconnectCause.ConnectionReleased);

/// <summary>
/// Close the WebSocket. <paramref name="permanent"/> <c>true</c> maps to
/// <see cref="DisconnectCause.UserLogout"/>; <c>false</c> maps to
/// <see cref="DisconnectCause.ConnectionReleased"/>.
/// </summary>
[Obsolete("Use DisconnectAsync(DisconnectCause). true maps to UserLogout, false to ConnectionReleased.")]
Task DisconnectAsync(bool permanent);

/// <summary>
/// Fetch missed events via <c>/sync</c> and apply them. The returned task completes when
/// those events have been processed, which may span several <see cref="Update"/> calls
/// after a large catch-up. Keep calling <see cref="Update"/> while awaiting.
/// </summary>
Task FetchAndProcessEventsSinceLastReceivedEvent(IEnumerable<string> channelCids);

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,12 @@ public void Stop()
_isStopped = true;
}

public void Start()
{
_isStopped = false;
NextReconnectTime = default;
}

//StreamTodo: connection info could be split to separate interface
private readonly IStreamChatLowLevelClient _client;
private readonly ITimeService _timeService;
Expand Down
Loading
Loading