2022-08-30 15:00:58 +00:00
|
|
|
|
using Fleck;
|
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Net;
|
|
|
|
|
|
|
|
|
|
namespace SharpChat {
|
|
|
|
|
public class ChatUserSession : IDisposable, IPacketTarget {
|
|
|
|
|
public const int ID_LENGTH = 32;
|
|
|
|
|
|
|
|
|
|
#if DEBUG
|
|
|
|
|
public static TimeSpan SessionTimeOut { get; } = TimeSpan.FromMinutes(1);
|
|
|
|
|
#else
|
|
|
|
|
public static TimeSpan SessionTimeOut { get; } = TimeSpan.FromMinutes(5);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
public IWebSocketConnection Connection { get; }
|
|
|
|
|
|
|
|
|
|
public string Id { get; private set; }
|
|
|
|
|
public bool IsDisposed { get; private set; }
|
|
|
|
|
public DateTimeOffset LastPing { get; set; } = DateTimeOffset.MinValue;
|
|
|
|
|
public ChatUser User { get; set; }
|
|
|
|
|
|
2022-08-30 18:29:11 +00:00
|
|
|
|
private static int CloseCode { get; set; } = 1000;
|
|
|
|
|
|
2022-08-30 15:00:58 +00:00
|
|
|
|
public string TargetName => @"@log";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private IPAddress _RemoteAddress = null;
|
|
|
|
|
|
|
|
|
|
public IPAddress RemoteAddress {
|
|
|
|
|
get {
|
2022-08-30 18:29:11 +00:00
|
|
|
|
if(_RemoteAddress == null) {
|
|
|
|
|
if((Connection.ConnectionInfo.ClientIpAddress == @"127.0.0.1" || Connection.ConnectionInfo.ClientIpAddress == @"::1")
|
2022-08-30 15:00:58 +00:00
|
|
|
|
&& Connection.ConnectionInfo.Headers.ContainsKey(@"X-Real-IP"))
|
|
|
|
|
_RemoteAddress = IPAddress.Parse(Connection.ConnectionInfo.Headers[@"X-Real-IP"]);
|
|
|
|
|
else
|
|
|
|
|
_RemoteAddress = IPAddress.Parse(Connection.ConnectionInfo.ClientIpAddress);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return _RemoteAddress;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public ChatUserSession(IWebSocketConnection ws) {
|
|
|
|
|
Connection = ws;
|
|
|
|
|
Id = GenerateId();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static string GenerateId() {
|
|
|
|
|
byte[] buffer = new byte[ID_LENGTH];
|
|
|
|
|
RNG.NextBytes(buffer);
|
|
|
|
|
return buffer.GetIdString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Send(IServerPacket packet) {
|
2022-08-30 18:29:11 +00:00
|
|
|
|
if(!Connection.IsAvailable)
|
2022-08-30 15:00:58 +00:00
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
IEnumerable<string> data = packet.Pack();
|
|
|
|
|
|
2022-08-30 18:29:11 +00:00
|
|
|
|
if(data != null)
|
|
|
|
|
foreach(string line in data)
|
|
|
|
|
if(!string.IsNullOrWhiteSpace(line))
|
2022-08-30 15:00:58 +00:00
|
|
|
|
Connection.Send(line);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void BumpPing()
|
|
|
|
|
=> LastPing = DateTimeOffset.Now;
|
|
|
|
|
|
|
|
|
|
public bool HasTimedOut
|
|
|
|
|
=> DateTimeOffset.Now - LastPing > SessionTimeOut;
|
|
|
|
|
|
2022-08-30 18:29:11 +00:00
|
|
|
|
public void PrepareForRestart()
|
|
|
|
|
=> CloseCode = 1012;
|
|
|
|
|
|
2022-08-30 15:00:58 +00:00
|
|
|
|
public void Dispose()
|
|
|
|
|
=> Dispose(true);
|
|
|
|
|
|
|
|
|
|
~ChatUserSession()
|
|
|
|
|
=> Dispose(false);
|
|
|
|
|
|
|
|
|
|
private void Dispose(bool disposing) {
|
2022-08-30 18:29:11 +00:00
|
|
|
|
if(IsDisposed)
|
2022-08-30 15:00:58 +00:00
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
IsDisposed = true;
|
2022-08-30 18:29:11 +00:00
|
|
|
|
Connection.Close(CloseCode);
|
2022-08-30 15:00:58 +00:00
|
|
|
|
|
2022-08-30 18:29:11 +00:00
|
|
|
|
if(disposing)
|
2022-08-30 15:00:58 +00:00
|
|
|
|
GC.SuppressFinalize(this);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|