sharp-chat/SharpChat/ChatConnection.cs

95 lines
2.6 KiB
C#

using Fleck;
using System;
using System.Collections.Generic;
using System.Net;
namespace SharpChat {
public class ChatConnection : IDisposable {
public const int ID_LENGTH = 20;
#if DEBUG
public static TimeSpan SessionTimeOut { get; } = TimeSpan.FromMinutes(1);
#else
public static TimeSpan SessionTimeOut { get; } = TimeSpan.FromMinutes(5);
#endif
public IWebSocketConnection Socket { get; }
public string Id { get; private set; }
public bool IsDisposed { get; private set; }
public DateTimeOffset LastPing { get; set; } = DateTimeOffset.Now;
public ChatUser User { get; set; }
private int CloseCode { get; set; } = 1000;
private IPAddress _RemoteAddress = null;
public IPAddress RemoteAddress {
get {
if(_RemoteAddress == null) {
if((Socket.ConnectionInfo.ClientIpAddress == "127.0.0.1" || Socket.ConnectionInfo.ClientIpAddress == "::1")
&& Socket.ConnectionInfo.Headers.ContainsKey("X-Real-IP"))
_RemoteAddress = IPAddress.Parse(Socket.ConnectionInfo.Headers["X-Real-IP"]);
else
_RemoteAddress = IPAddress.Parse(Socket.ConnectionInfo.ClientIpAddress);
}
return _RemoteAddress;
}
}
public bool IsAlive => !IsDisposed && !HasTimedOut;
public bool IsAuthed => IsAlive && User is not null;
public ChatConnection(IWebSocketConnection sock) {
Socket = sock;
Id = RNG.SecureRandomString(ID_LENGTH);
}
public void Send(IServerPacket packet) {
if(!Socket.IsAvailable)
return;
IEnumerable<string> data = packet.Pack();
if(data != null)
foreach(string line in data)
if(!string.IsNullOrWhiteSpace(line))
Socket.Send(line);
}
public void BumpPing() {
LastPing = DateTimeOffset.Now;
}
public bool HasTimedOut
=> DateTimeOffset.Now - LastPing > SessionTimeOut;
public void PrepareForRestart() {
CloseCode = 1012;
}
~ChatConnection() {
DoDispose();
}
public void Dispose() {
DoDispose();
GC.SuppressFinalize(this);
}
private void DoDispose() {
if(IsDisposed)
return;
IsDisposed = true;
Socket.Close(CloseCode);
}
public override int GetHashCode() {
return Id.GetHashCode();
}
}
}