Repository navigation
Expand file tree
/
Copy pathSessionEndState.cs
More file actions
60 lines (52 loc) · 2.33 KB
/
Copy pathSessionEndState.cs
File metadata and controls
60 lines (52 loc) · 2.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
using System;
using System.Threading.Tasks;
namespace TCPTunnel
{
internal enum SessionEndKind { Active, Voluntary, ConnectionLost, ReadTimedOut, InvalidFrame, ServerReason }
internal sealed class SessionEndState
{
private readonly object gate = new object();
private SessionEndKind kind;
private string message;
internal SessionEndKind Kind { get { lock (gate) return kind; } }
internal string Message { get { lock (gate) return message; } }
internal bool RequiresAcknowledgement => Kind != SessionEndKind.Active && Kind != SessionEndKind.Voluntary;
internal void Leave()
{
lock (gate)
if (kind == SessionEndKind.Active) kind = SessionEndKind.Voluntary;
}
internal void RecordFailure(SessionEndKind failure)
{
if (failure != SessionEndKind.ConnectionLost && failure != SessionEndKind.ReadTimedOut && failure != SessionEndKind.InvalidFrame)
throw new ArgumentOutOfRangeException(nameof(failure));
lock (gate)
if (kind == SessionEndKind.Active) kind = failure;
}
internal void RecordServerReason(SystemMessageKind systemKind, string text)
{
if (systemKind != SystemMessageKind.Kicked && systemKind != SystemMessageKind.MessageTooLong &&
systemKind != SystemMessageKind.TooManyMessages && systemKind != SystemMessageKind.EncryptionError)
return;
lock (gate)
{
if (kind == SessionEndKind.Voluntary || kind == SessionEndKind.ServerReason) return;
message = text;
kind = SessionEndKind.ServerReason;
}
}
internal async Task DrainReceiverAsync(Task receiver)
{
if (Kind != SessionEndKind.ConnectionLost) return;
try { await receiver.WaitAsync(TimeSpan.FromMilliseconds(500)).ConfigureAwait(false); }
catch (Exception) {}
}
internal string GetDisplayMessage() => Kind switch
{
SessionEndKind.ServerReason => Message,
SessionEndKind.ReadTimedOut => Lang.Get(TextId.FrameReadTimedOut),
SessionEndKind.InvalidFrame => Lang.Get(TextId.DisconnectInvalidFrame),
_ => Lang.Get(TextId.HubConnectionLost)
};
}
}